Merge
authorroland
Tue, 05 May 2015 19:27:08 +0200
changeset 30592 fa0ae17a543e
parent 30590 14f7f48c1377 (current diff)
parent 30591 b32fcc177417 (diff)
child 30593 69f942690128
Merge
hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/bytecode.gif
hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/link.gif
hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/method.gif
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupOrganizer
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphCountGroupOrganizer.java
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardGroupOrganizer.java
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/StructuredViewAction.java
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/diff.gif
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/folder.gif
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/graph.gif
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/import.gif
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/remove.gif
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/removeall.gif
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/save.gif
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/structure.gif
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupOrganizer.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupReceiver.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/JavaSE6ScriptEngine.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/NullScriptEngine.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ScriptEngineAbstraction.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/add.gif
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/delete.gif
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/down.gif
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/minus.gif
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/plus.gif
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/up.gif
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Source.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/OldHierarchicalLayoutManager.java
hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupReceiver
hotspot/src/share/tools/IdealGraphVisualizer/README
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/RhinoScriptEngine.java
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/layer.xml
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupOrganizer
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/JavaGroupOrganizer.java
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/combine.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/extendedColor.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/linestyle.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeMemory.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeRootInputs.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeSafepointInputs.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeSelfLoops.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/split.filter
hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/settings.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/META-INF/services/com.sun.hotspot.igv.data.services.InputGraphProvider
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ConnectionAnchor.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedPanAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/FindPanel.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/PreferenceConstants.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/SlotLayout.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/NodeFindAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/export.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/overview.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/search.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoomin.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoomout.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/DiagramConnectionWidget.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/MultiConnectionWidget.java
--- a/hotspot/.hgignore	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/.hgignore	Tue May 05 19:27:08 2015 +0200
@@ -6,5 +6,7 @@
 ^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/
 ^src/share/tools/IdealGraphVisualizer/build/
 ^src/share/tools/IdealGraphVisualizer/dist/
+^src/share/tools/IdealGraphVisualizer/nbplatform/
+.igv.log
 ^.hgtip
 .DS_Store
--- a/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/build-impl.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/build-impl.xml	Tue May 05 19:27:08 2015 +0200
@@ -4,6 +4,13 @@
 ***         EDIT ../build.xml INSTEAD         ***
 -->
 <project name="com.sun.hotspot.igv.svg-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
     <property file="nbproject/private/suite-private.properties"/>
     <property file="nbproject/suite.properties"/>
     <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
@@ -16,13 +23,21 @@
             <property name="@{name}" value="${@{value}}"/>
         </sequential>
     </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
     <property file="${user.properties.file}"/>
     <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
         <condition>
             <not>
-                <available file="${harness.dir}" type="dir"/>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
             </not>
         </condition>
     </fail>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/genfiles.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/genfiles.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,8 +1,5 @@
-build.xml.data.CRC32=ebcf0422
-build.xml.script.CRC32=d7a2678d
-build.xml.stylesheet.CRC32=79c3b980
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
 nbproject/build-impl.xml.data.CRC32=ebcf0422
-nbproject/build-impl.xml.script.CRC32=57997f94
-nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
+nbproject/build-impl.xml.script.CRC32=42ef3ff6
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.47.1
--- a/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/BatikSVG.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/BatikSVG.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,40 +25,58 @@
 
 import java.awt.Graphics2D;
 import java.io.Writer;
+import java.io.File;
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
 import org.w3c.dom.DOMImplementation;
 
 /**
- *
+ * Utility class
  * @author Thomas Wuerthinger
  */
 public class BatikSVG {
 
+    private BatikSVG() {
+    }
+
     private static Constructor SVGGraphics2DConstructor;
-    private static Method Method_stream;
-    private static Method Method_createDefault;
-    private static Method Method_getDOMImplementation;
-    private static Method Method_setEmbeddedFontsOn;
+    private static Method streamMethod;
+    private static Method createDefaultMethod;
+    private static Method getDOMImplementationMethod;
+    private static Method setEmbeddedFontsOnMethod;
+    private static Class<?> classSVGGraphics2D;
 
+    /**
+     * Creates a graphics object that allows to be exported to SVG data using the {@link #printToStream(Graphics2D, Writer, boolean) printToStream} method.
+     * @return the newly created Graphics2D object or null if the library does not exist
+     */
     public static Graphics2D createGraphicsObject() {
         try {
             if (SVGGraphics2DConstructor == null) {
-                ClassLoader cl = BatikSVG.class.getClassLoader();
-                Class Class_GenericDOMImplementation = cl.loadClass("org.apache.batik.dom.GenericDOMImplementation");
-                Class Class_SVGGeneratorContext = cl.loadClass("org.apache.batik.svggen.SVGGeneratorContext");
-                Class Class_SVGGraphics2D = cl.loadClass("org.apache.batik.svggen.SVGGraphics2D");
-                Method_getDOMImplementation = Class_GenericDOMImplementation.getDeclaredMethod("getDOMImplementation", new Class[0]);
-                Method_createDefault = Class_SVGGeneratorContext.getDeclaredMethod("createDefault", new Class[]{org.w3c.dom.Document.class});
-                Method_setEmbeddedFontsOn = Class_SVGGeneratorContext.getDeclaredMethod("setEmbeddedFontsOn", new Class[]{boolean.class});
-                Method_stream = Class_SVGGraphics2D.getDeclaredMethod("stream", Writer.class, boolean.class);
-                SVGGraphics2DConstructor = Class_SVGGraphics2D.getConstructor(Class_SVGGeneratorContext, boolean.class);
+                String batikJar = System.getenv().get("IGV_BATIK_JAR");
+                if (batikJar == null) {
+                    return null;
+                }
+                // Load batik in it's own class loader since some it's support jars interfere with the JDK
+                URL url = new File(batikJar).toURI().toURL();
+                ClassLoader cl = new URLClassLoader(new URL[] { url });
+                Class<?> classGenericDOMImplementation = cl.loadClass("org.apache.batik.dom.GenericDOMImplementation");
+                Class<?> classSVGGeneratorContext = cl.loadClass("org.apache.batik.svggen.SVGGeneratorContext");
+                classSVGGraphics2D = cl.loadClass("org.apache.batik.svggen.SVGGraphics2D");
+                getDOMImplementationMethod = classGenericDOMImplementation.getDeclaredMethod("getDOMImplementation", new Class[0]);
+                createDefaultMethod = classSVGGeneratorContext.getDeclaredMethod("createDefault", new Class[]{org.w3c.dom.Document.class});
+                setEmbeddedFontsOnMethod = classSVGGeneratorContext.getDeclaredMethod("setEmbeddedFontsOn", new Class[]{boolean.class});
+                streamMethod = classSVGGraphics2D.getDeclaredMethod("stream", Writer.class, boolean.class);
+                SVGGraphics2DConstructor = classSVGGraphics2D.getConstructor(classSVGGeneratorContext, boolean.class);
             }
-            DOMImplementation dom = (DOMImplementation) Method_getDOMImplementation.invoke(null);
+            DOMImplementation dom = (DOMImplementation) getDOMImplementationMethod.invoke(null);
             org.w3c.dom.Document document = dom.createDocument("http://www.w3.org/2000/svg", "svg", null);
-            Object ctx = Method_createDefault.invoke(null, document);
-            Method_setEmbeddedFontsOn.invoke(ctx, true);
+            Object ctx = createDefaultMethod.invoke(null, document);
+            setEmbeddedFontsOnMethod.invoke(ctx, true);
             Graphics2D svgGenerator = (Graphics2D) SVGGraphics2DConstructor.newInstance(ctx, true);
             return svgGenerator;
         } catch (ClassNotFoundException e) {
@@ -71,12 +89,22 @@
             return null;
         } catch (InstantiationException e) {
             return null;
+        } catch (MalformedURLException e) {
+            return null;
         }
     }
 
+    /**
+     * Serializes a graphics object to a stream in SVG format.
+     * @param svgGenerator the graphics object. Only graphics objects created by the {@link #createGraphicsObject() createGraphicsObject} method are valid.
+     * @param stream the stream to which the data is written
+     * @param useCSS whether to use CSS styles in the SVG output
+     */
     public static void printToStream(Graphics2D svgGenerator, Writer stream, boolean useCSS) {
+        assert classSVGGraphics2D != null;
+        assert classSVGGraphics2D.isInstance(svgGenerator);
         try {
-            Method_stream.invoke(svgGenerator, stream, useCSS);
+            streamMethod.invoke(svgGenerator, stream, useCSS);
         } catch (IllegalAccessException e) {
             assert false;
         } catch (InvocationTargetException e) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/package-info.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+/**
+ * This package is used to proxy the SVG export functionality of the BatikSVG library. Reflection is used such that the
+ * library is optional and need not be present at build time.
+ */
+package com.sun.hotspot.igv.svg;
+
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/manifest.mf	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/manifest.mf	Tue May 05 19:27:08 2015 +0200
@@ -1,6 +1,6 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.bytecodes
-OpenIDE-Module-Layer: com/sun/hotspot/igv/bytecodes/layer.xml
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/bytecodes/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.bytecodes
+OpenIDE-Module-Layer: com/sun/hotspot/igv/bytecodes/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/bytecodes/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -15,12 +15,36 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>org.jdesktop.layout</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
                         <release-version>1</release-version>
-                        <specification-version>1.4</specification-version>
+                        <specification-version>1.16.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.39.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -28,7 +52,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.11</specification-version>
+                        <specification-version>6.34.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -36,7 +60,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.2.0.1</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -44,7 +68,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -52,7 +84,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.16</specification-version>
+                        <specification-version>6.39.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/Bundle.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/Bundle.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
-CTL_BytecodeViewAction=Open BytecodeView Window
-CTL_BytecodeViewTopComponent=BytecodeView Window
+CTL_BytecodeViewAction=Bytecode
+CTL_BytecodeViewTopComponent=Bytecode
 CTL_SelectBytecodesAction=Select nodes
-HINT_BytecodeViewTopComponent=This is a BytecodeView window
+HINT_BytecodeViewTopComponent=Shows the bytecode associated with the displayed graph.
 OpenIDE-Module-Name=Bytecodes
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,14 +29,14 @@
 import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
 import java.awt.Image;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Set;
 import javax.swing.Action;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
-import org.openide.util.Utilities;
+import org.openide.util.ImageUtilities;
 
 /**
  *
@@ -49,29 +49,35 @@
     public BytecodeNode(InputBytecode bytecode, InputGraph graph, String bciValue) {
 
         super(Children.LEAF);
-        this.setDisplayName(bytecode.getBci() + " " + bytecode.getName());
+        String displayName = bytecode.getBci() + " " + bytecode.getName() + " " + bytecode.getOperands();
 
         bciValue = bytecode.getBci() + " " + bciValue;
         bciValue = bciValue.trim();
 
-        Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<InputNode>(graph.getNodes());
+        Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<>(graph.getNodes());
         StringPropertyMatcher matcher = new StringPropertyMatcher("bci", bciValue);
         List<InputNode> nodeList = selector.selectMultiple(matcher);
         if (nodeList.size() > 0) {
-            nodes = new HashSet<InputNode>();
+            nodes = new LinkedHashSet<>();
             for (InputNode n : nodeList) {
                 nodes.add(n);
             }
-            this.setDisplayName(this.getDisplayName() + " (" + nodes.size() + " nodes)");
+            displayName += " (" + nodes.size() + " nodes)";
         }
+
+        if (bytecode.getComment() != null) {
+            displayName += " // " + bytecode.getComment();
+        }
+
+        this.setDisplayName(displayName);
     }
 
     @Override
     public Image getIcon(int i) {
         if (nodes != null) {
-            return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/link.gif");
+            return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/link.png");
         } else {
-            return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/bytecode.gif");
+            return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/bytecode.png");
         }
     }
 
@@ -91,6 +97,7 @@
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public <T extends Node.Cookie> T getCookie(Class<T> aClass) {
         if (aClass == SelectBytecodesCookie.class && nodes != null) {
             return (T) (new SelectBytecodesCookie(nodes));
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
         super(NbBundle.getMessage(BytecodeViewAction.class, "CTL_BytecodeViewAction"));
     }
 
+    @Override
     public void actionPerformed(ActionEvent evt) {
         TopComponent win = BytecodeViewTopComponent.findInstance();
         win.open();
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.form	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.form	Tue May 05 19:27:08 2015 +0200
@@ -3,6 +3,8 @@
 <Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.util.LookupHistory;
 import java.awt.BorderLayout;
 import java.io.Serializable;
 import javax.swing.SwingUtilities;
@@ -33,11 +34,7 @@
 import org.openide.explorer.ExplorerManager;
 import org.openide.explorer.ExplorerUtils;
 import org.openide.explorer.view.BeanTreeView;
-import org.openide.util.Lookup;
-import org.openide.util.LookupEvent;
-import org.openide.util.LookupListener;
-import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
+import org.openide.util.*;
 import org.openide.windows.TopComponent;
 import org.openide.windows.WindowManager;
 
@@ -91,6 +88,7 @@
     }// </editor-fold>//GEN-END:initComponents
     // Variables declaration - do not modify//GEN-BEGIN:variables
     // End of variables declaration//GEN-END:variables
+
     /**
      * Gets default instance. Do not use directly: reserved for *.settings files only,
      * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
@@ -126,7 +124,7 @@
 
     @Override
     public void componentOpened() {
-        Lookup.Template tpl = new Lookup.Template(Object.class);
+        Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<>(InputGraphProvider.class);
         result = Utilities.actionsGlobalContext().lookup(tpl);
         result.addLookupListener(this);
     }
@@ -147,23 +145,47 @@
         return PREFERRED_ID;
     }
 
+    @Override
     public ExplorerManager getExplorerManager() {
         return manager;
     }
 
+    @Override
+    public void requestActive() {
+        super.requestActive();
+        this.treeView.requestFocus();
+    }
+
+    @Override
+    public boolean requestFocus(boolean temporary) {
+        this.treeView.requestFocus();
+        return super.requestFocus(temporary);
+    }
+
+    @Override
+    protected boolean requestFocusInWindow(boolean temporary) {
+        this.treeView.requestFocus();
+        return super.requestFocusInWindow(temporary);
+    }
+
+    @Override
     public void resultChanged(LookupEvent lookupEvent) {
-        final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
-        if (p != null) {
+        final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
             SwingUtilities.invokeLater(new Runnable() {
+                @Override
                 public void run() {
-            InputGraph graph = p.getGraph();
-            if (graph != null) {
-                Group g = graph.getGroup();
-                rootNode.update(graph, g.getMethod());
-            }
-        }
+                if (p != null) {
+                    InputGraph graph = p.getGraph();
+                    if (graph != null) {
+                        Group g = graph.getGroup();
+                        rootNode.update(graph, g.getMethod());
+                        return;
+                    }
+                }
+                        rootNode.update(null, null);
+                    }
             });
-        }
+
     }
 
     final static class ResolvableHelper implements Serializable {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/MethodNode.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/MethodNode.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
-import org.openide.util.Utilities;
+import org.openide.util.ImageUtilities;
 
 /**
  *
@@ -38,7 +38,7 @@
  */
 public class MethodNode extends AbstractNode {
 
-    private static class MethodNodeChildren extends Children.Keys {
+    private static class MethodNodeChildren extends Children.Keys<InputBytecode> {
 
         private InputMethod method;
         private InputGraph graph;
@@ -50,9 +50,8 @@
             this.graph = graph;
         }
 
-        protected Node[] createNodes(Object object) {
-            assert object instanceof InputBytecode;
-            InputBytecode bc = (InputBytecode) object;
+        @Override
+        protected Node[] createNodes(InputBytecode bc) {
             if (bc.getInlined() == null) {
                 return new Node[]{new BytecodeNode(bc, graph, bciString)};
             } else {
@@ -84,7 +83,7 @@
 
     @Override
     public Image getIcon(int i) {
-        return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/method.gif");
+        return ImageUtilities.loadImage("com/sun/hotspot/igv/bytecodes/images/method.png");
     }
 
     @Override
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,9 +24,9 @@
 package com.sun.hotspot.igv.bytecodes;
 
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.util.LookupHistory;
 import org.openide.nodes.Node;
 import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
 import org.openide.util.NbBundle;
 import org.openide.util.actions.CookieAction;
 
@@ -36,22 +36,26 @@
  */
 public final class SelectBytecodesAction extends CookieAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         SelectBytecodesCookie c = activatedNodes[0].getCookie(SelectBytecodesCookie.class);
-        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
         if (p != null) {
             p.setSelectedNodes(c.getNodes());
         }
     }
 
+    @Override
     protected int mode() {
         return CookieAction.MODE_EXACTLY_ONE;
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(SelectBytecodesAction.class, "CTL_SelectBytecodesAction");
     }
 
+    @Override
     protected Class[] cookieClasses() {
         return new Class[]{
             SelectBytecodesCookie.class
@@ -64,6 +68,7 @@
         putValue("noIconInMenu", Boolean.TRUE);
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -73,3 +78,4 @@
         return false;
     }
 }
+
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesCookie.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesCookie.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/bytecode.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/bytecode.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/link.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/link.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/method.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/method.png has changed
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/manifest.mf	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/manifest.mf	Tue May 05 19:27:08 2015 +0200
@@ -1,6 +1,6 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.controlflow
-OpenIDE-Module-Layer: com/sun/hotspot/igv/controlflow/layer.xml
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/controlflow/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.controlflow
+OpenIDE-Module-Layer: com/sun/hotspot/igv/controlflow/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/controlflow/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -31,12 +31,20 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>org.jdesktop.layout</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
                         <release-version>1</release-version>
-                        <specification-version>1.4</specification-version>
+                        <specification-version>1.16.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -52,7 +60,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockConnectionWidget.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockConnectionWidget.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,9 @@
 import com.sun.hotspot.igv.data.InputBlockEdge;
 import com.sun.hotspot.igv.layout.Link;
 import com.sun.hotspot.igv.layout.Port;
+import java.awt.BasicStroke;
 import java.awt.Point;
+import java.awt.Stroke;
 import java.util.ArrayList;
 import java.util.List;
 import org.netbeans.api.visual.widget.ConnectionWidget;
@@ -37,12 +39,19 @@
  */
 public class BlockConnectionWidget extends ConnectionWidget implements Link {
 
+    private static final Stroke NORMAL_STROKE = new BasicStroke(1.0f);
+    private static final Stroke BOLD_STROKE = new BasicStroke(2.5f);
+    private static final Stroke DASHED_STROKE = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, new float[]{5, 5}, 0);
+    private static final Stroke BOLD_DASHED_STROKE = new BasicStroke(2.5f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, new float[]{5, 5}, 0);
+
     private BlockWidget from;
     private BlockWidget to;
     private Port inputSlot;
     private Port outputSlot;
     private List<Point> points;
     private InputBlockEdge edge;
+    private boolean isDashed = false;
+    private boolean isBold = false;
 
     public BlockConnectionWidget(ControlFlowScene scene, InputBlockEdge edge) {
         super(scene);
@@ -67,6 +76,30 @@
         return outputSlot;
     }
 
+    public void setBold(boolean bold) {
+        this.isBold = bold;
+        updateStroke();
+    }
+
+    public void setDashed(boolean dashed) {
+        this.isDashed = dashed;
+        updateStroke();
+    }
+
+    private void updateStroke() {
+        Stroke stroke = NORMAL_STROKE;
+        if (isBold) {
+            if (isDashed) {
+                stroke = BOLD_DASHED_STROKE;
+            } else {
+                stroke = BOLD_STROKE;
+            }
+        } else if (isDashed) {
+            stroke = DASHED_STROKE;
+        }
+        setStroke(stroke);
+    }
+
     public void setControlPoints(List<Point> p) {
         this.points = p;
     }
@@ -80,4 +113,9 @@
     public String toString() {
         return "Connection[ " + from.toString() + " - " + to.toString() + "]";
     }
+
+    @Override
+    public boolean isVIP() {
+        return isBold;
+    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockWidget.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockWidget.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,7 @@
 import java.awt.Dimension;
 import java.awt.Font;
 import java.awt.Point;
+import java.awt.Rectangle;
 import org.netbeans.api.visual.border.BorderFactory;
 import org.netbeans.api.visual.model.ObjectState;
 import org.netbeans.api.visual.widget.LabelWidget;
@@ -41,13 +42,13 @@
  */
 public class BlockWidget extends LabelWidget implements Vertex {
 
-    public static final Dimension SIZE = new Dimension(20, 20);
+    public static final Dimension MIN_SIZE = new Dimension(20, 20);
     private InputBlock block;
     private Port inputSlot;
     private Port outputSlot;
     private Cluster cluster;
     private boolean root;
-    private static final Font font = new Font(Font.SERIF, Font.PLAIN, 12);
+    private static final Font font = new Font(Font.SANS_SERIF, Font.PLAIN, 12);
     private static final Font boldFont = font.deriveFont(Font.BOLD);
     public static final Color NORMAL_FOREGROUND_COLOR = Color.BLACK;
     public static final Color HOVER_FOREGROUND_COLOR = Color.BLUE;
@@ -59,29 +60,24 @@
         this.setLabel(block.getName());
         this.setForeground(NORMAL_FOREGROUND_COLOR);
         this.setBorder(BorderFactory.createLineBorder(1, NORMAL_FOREGROUND_COLOR));
-        this.setMinimumSize(SIZE);
-        this.setMaximumSize(SIZE);
+        this.setMinimumSize(MIN_SIZE);
 
         this.setFont(font);
+        this.setAlignment(Alignment.CENTER);
 
         final BlockWidget widget = this;
         inputSlot = new Port() {
-
             public Point getRelativePosition() {
-                return new Point((int) (SIZE.getWidth() / 2), (int) (SIZE.getHeight() / 2));
+                return new Point((int) (getSize().getWidth() / 2), (int) (getSize().getHeight() / 2));
             }
-
             public Vertex getVertex() {
                 return widget;
             }
         };
-
         outputSlot = new Port() {
-
             public Point getRelativePosition() {
-                return new Point((int) (SIZE.getWidth() / 2), (int) (SIZE.getHeight() / 2));
+                return new Point((int) (getSize().getWidth() / 2), (int) (getSize().getHeight() / 2));
             }
-
             public Vertex getVertex() {
                 return widget;
             }
@@ -101,7 +97,12 @@
     }
 
     public Dimension getSize() {
-        return SIZE;
+        Rectangle bounds = getBounds();
+        if (bounds != null) {
+            return bounds.getSize();
+        } else {
+            return MIN_SIZE;
+        }
     }
 
     public void setPosition(Point p) {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/Bundle.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/Bundle.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,4 +1,4 @@
-CTL_ControlFlowAction=Open ControlFlow Window
-CTL_ControlFlowTopComponent=ControlFlow Window
-HINT_ControlFlowTopComponent=This is a ControlFlow window
+CTL_ControlFlowAction=Control Flow
+CTL_ControlFlowTopComponent=Control Flow
+HINT_ControlFlowTopComponent=Shows the blocks of the current graph.
 OpenIDE-Module-Name=ControlFlow
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,17 +23,17 @@
  */
 package com.sun.hotspot.igv.controlflow;
 
+import com.sun.hotspot.igv.data.InputBlockEdge;
 import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.data.InputBlockEdge;
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
 import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.util.LookupHistory;
 import java.awt.Color;
 import java.awt.Point;
 import java.awt.Rectangle;
 import java.util.ArrayList;
 import java.util.HashSet;
-import java.util.HashMap;
 import java.util.Set;
 import javax.swing.BorderFactory;
 import org.netbeans.api.visual.action.ActionFactory;
@@ -44,15 +44,14 @@
 import org.netbeans.api.visual.action.WidgetAction;
 import org.netbeans.api.visual.anchor.AnchorFactory;
 import org.netbeans.api.visual.anchor.AnchorShape;
-import org.netbeans.api.visual.layout.LayoutFactory;
 import org.netbeans.api.visual.router.RouterFactory;
 import org.netbeans.api.visual.widget.LayerWidget;
 import org.netbeans.api.visual.widget.Widget;
 import org.netbeans.api.visual.graph.GraphScene;
 import org.netbeans.api.visual.graph.layout.GraphLayout;
+import org.netbeans.api.visual.layout.LayoutFactory;
 import org.netbeans.api.visual.layout.SceneLayout;
 import org.netbeans.api.visual.widget.ConnectionWidget;
-import org.openide.util.Lookup;
 
 /**
  *
@@ -61,13 +60,12 @@
 public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> implements SelectProvider, MoveProvider, RectangularSelectDecorator, RectangularSelectProvider {
 
     private HashSet<BlockWidget> selection;
-    private HashMap<InputBlock, BlockWidget> blockMap;
     private InputGraph oldGraph;
     private LayerWidget edgeLayer;
     private LayerWidget mainLayer;
     private LayerWidget selectLayer;
     private WidgetAction hoverAction = this.createWidgetHoverAction();
-    private WidgetAction selectAction = ActionFactory.createSelectAction(this);
+    private WidgetAction selectAction = new DoubleClickSelectAction(this);
     private WidgetAction moveAction = ActionFactory.createMoveAction(null, this);
 
     public ControlFlowScene() {
@@ -111,27 +109,21 @@
             addNode(b);
         }
 
-        for (InputBlock b : g.getBlocks()) {
-            for (InputBlockEdge e : b.getOutputs()) {
-                addEdge(e);
-                assert g.getBlocks().contains(e.getFrom());
-                assert g.getBlocks().contains(e.getTo());
-                this.setEdgeSource(e, e.getFrom());
-                this.setEdgeTarget(e, e.getTo());
-            }
+        for (InputBlockEdge e : g.getBlockEdges()) {
+            addEdge(e);
+            assert g.getBlocks().contains(e.getFrom());
+            assert g.getBlocks().contains(e.getTo());
+            this.setEdgeSource(e, e.getFrom());
+            this.setEdgeTarget(e, e.getTo());
         }
 
-        GraphLayout layout = new HierarchicalGraphLayout();//GridGraphLayout();
+        GraphLayout<InputBlock, InputBlockEdge> layout = new HierarchicalGraphLayout<InputBlock, InputBlockEdge>();//GridGraphLayout();
         SceneLayout sceneLayout = LayoutFactory.createSceneGraphLayout(this, layout);
         sceneLayout.invokeLayout();
 
         this.validate();
     }
 
-    public BlockWidget getBlockWidget(InputBlock b) {
-        return blockMap.get(b);
-    }
-
     public void clearSelection() {
         for (BlockWidget w : selection) {
             w.setState(w.getState().deriveSelected(false));
@@ -141,7 +133,7 @@
     }
 
     public void selectionChanged() {
-        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//)Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
         if (p != null) {
             Set<InputNode> inputNodes = new HashSet<InputNode>();
             for (BlockWidget w : selection) {
@@ -204,15 +196,19 @@
     }
 
     public void setNewLocation(Widget widget, Point location) {
-        Point originalLocation = getOriginalLocation(widget);
-        int xOffset = location.x - originalLocation.x;
-        int yOffset = location.y - originalLocation.y;
-        for (Widget w : this.selection) {
-            Point p = new Point(w.getPreferredLocation());
-            p.translate(xOffset, yOffset);
-            w.setPreferredLocation(p);
+        if (selection.contains(widget)) {
+            // move entire selection
+            Point originalLocation = getOriginalLocation(widget);
+            int xOffset = location.x - originalLocation.x;
+            int yOffset = location.y - originalLocation.y;
+            for (Widget w : selection) {
+                Point p = new Point(w.getPreferredLocation());
+                p.translate(xOffset, yOffset);
+                w.setPreferredLocation(p);
+            }
+        } else {
+            widget.setPreferredLocation(location);
         }
-
     }
 
     public Widget createSelectionWidget() {
@@ -271,7 +267,15 @@
     }
 
     protected Widget attachEdgeWidget(InputBlockEdge edge) {
-        ConnectionWidget w = new BlockConnectionWidget(this, edge);
+        BlockConnectionWidget w = new BlockConnectionWidget(this, edge);
+        switch (edge.getState()) {
+            case NEW:
+                w.setBold(true);
+                break;
+            case DELETED:
+                w.setDashed(true);
+                break;
+        }
         w.setRouter(RouterFactory.createDirectRouter());
         w.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
         edgeLayer.addChild(w);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.form	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.form	Tue May 05 19:27:08 2015 +0200
@@ -3,6 +3,8 @@
 <Form version="1.3" maxVersion="1.3" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.util.LookupHistory;
 import java.awt.BorderLayout;
 import java.io.Serializable;
 import javax.swing.JScrollPane;
@@ -63,17 +64,7 @@
         this.add(panel, BorderLayout.CENTER);
     }
 
-    @Override
-    public void requestFocus() {
-        super.requestFocus();
-        scene.getView().requestFocus();
-    }
 
-    @Override
-    public boolean requestFocusInWindow() {
-        super.requestFocusInWindow();
-        return scene.getView().requestFocusInWindow();
-    }
 
     /** This method is called from within the constructor to
      * initialize the form.
@@ -96,6 +87,7 @@
     }// </editor-fold>//GEN-END:initComponents
     // Variables declaration - do not modify//GEN-BEGIN:variables
     // End of variables declaration//GEN-END:variables
+
     /**
      * Gets default instance. Do not use directly: reserved for *.settings files only,
      * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
@@ -131,7 +123,7 @@
 
     @Override
     public void componentOpened() {
-        Lookup.Template tpl = new Lookup.Template(Object.class);
+        Lookup.Template<InputGraphProvider> tpl = new Lookup.Template<InputGraphProvider>(InputGraphProvider.class);
         result = Utilities.actionsGlobalContext().lookup(tpl);
         result.addLookupListener(this);
     }
@@ -143,16 +135,16 @@
     }
 
     public void resultChanged(LookupEvent lookupEvent) {
-
-        final InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);//Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
         if (p != null) {
             SwingUtilities.invokeLater(new Runnable() {
+
                 public void run() {
-            InputGraph g = p.getGraph();
-            if (g != null) {
-                scene.setGraph(g);
-            }
-        }
+                    InputGraph g = p.getGraph();
+                    if (g != null) {
+                        scene.setGraph(g);
+                    }
+                }
             });
         }
     }
@@ -169,8 +161,8 @@
 
     @Override
     public void requestActive() {
-        scene.getView().requestFocusInWindow();
         super.requestActive();
+        scene.getView().requestFocus();
     }
 
     final static class ResolvableHelper implements Serializable {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/DoubleClickSelectAction.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.controlflow;
+
+import java.awt.Point;
+import java.awt.event.MouseEvent;
+import org.netbeans.api.visual.action.SelectProvider;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ * Selection action that acts on double-click only. Does not support aiming.
+ *
+ * @author Peter Hofer
+ */
+public class DoubleClickSelectAction extends WidgetAction.LockedAdapter {
+
+    private final SelectProvider provider;
+
+    public DoubleClickSelectAction(SelectProvider provider) {
+        this.provider = provider;
+    }
+
+    protected boolean isLocked() {
+        return false;
+    }
+
+    @Override
+    public State mousePressed(Widget widget, WidgetMouseEvent event) {
+        if (event.getClickCount() >= 2 && (event.getButton() == MouseEvent.BUTTON1 || event.getButton() == MouseEvent.BUTTON2)) {
+            boolean invert = (event.getModifiersEx() & MouseEvent.CTRL_DOWN_MASK) != 0;
+            Point point = event.getPoint();
+            if (provider.isSelectionAllowed(widget, point, invert)) {
+                provider.select(widget, point, invert);
+                return State.CHAIN_ONLY;
+            }
+        }
+        return State.REJECTED;
+    }
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/HierarchicalGraphLayout.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/HierarchicalGraphLayout.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,7 +34,7 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -76,6 +76,10 @@
         public void setControlPoints(List<Point> list) {
         // Do nothing for now
         }
+
+        public boolean isVIP() {
+            return false;
+        }
     }
 
     private class VertexWrapper implements Vertex {
@@ -127,6 +131,7 @@
         }
 
         public int compareTo(Vertex o) {
+            @SuppressWarnings("unchecked")
             VertexWrapper vw = (VertexWrapper) o;
             return node.toString().compareTo(vw.node.toString());
         }
@@ -138,8 +143,8 @@
 
     protected void performGraphLayout(UniversalGraph<N, E> graph) {
 
-        Set<LinkWrapper> links = new HashSet<LinkWrapper>();
-        Set<VertexWrapper> vertices = new HashSet<VertexWrapper>();
+        Set<LinkWrapper> links = new LinkedHashSet<LinkWrapper>();
+        Set<VertexWrapper> vertices = new LinkedHashSet<VertexWrapper>();
         Map<N, VertexWrapper> vertexMap = new HashMap<N, VertexWrapper>();
 
         for (N node : graph.getNodes()) {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -1,126 +1,142 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
-    <type>org.netbeans.modules.apisupport.project</type>
-    <configuration>
-        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
-            <code-name-base>com.sun.hotspot.igv.coordinator</code-name-base>
-            <suite-component/>
-            <module-dependencies>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.difference</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.settings</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.netbeans.api.progress</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <release-version>1</release-version>
-                        <specification-version>1.10.0.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.actions</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.6.1.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.awt</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.11.0.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.dialogs</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>7.5.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.explorer</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.11</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.filesystems</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>7.3</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.loaders</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.7</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.nodes</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>7.2.0.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.util</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>org.openide.windows</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>6.16</specification-version>
-                    </run-dependency>
-                </dependency>
-            </module-dependencies>
-            <public-packages/>
-        </data>
-    </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.coordinator</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.connection</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.difference</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.settings</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.api.progress</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.23.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.actions</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.21.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.30.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.dialogs</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.18.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.explorer</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.34.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.filesystems</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.46.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.loaders</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.nodes</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.20.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.windows</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.39.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupOrganizer	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-com.sun.hotspot.igv.coordinator.StandardGroupOrganizer
-com.sun.hotspot.igv.coordinator.GraphCountGroupOrganizer
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/Bundle.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/Bundle.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,7 +1,6 @@
-
-AdvancedOption_DisplayName_Coordinator=Settings
-AdvancedOption_Tooltip_Coordinator=Visualization Tool Settings
-CTL_OutlineTopComponent=Outline Window
-CTL_SomeAction=test
-HINT_OutlineTopComponent=This is a Outline window
-OpenIDE-Module-Name=Coordinator
+AdvancedOption_DisplayName_Coordinator=Settings
+AdvancedOption_Tooltip_Coordinator=Visualization Tool Settings
+CTL_OutlineTopComponent=Outline
+CTL_SomeAction=test
+HINT_OutlineTopComponent=Displays loaded groups of graphs.
+OpenIDE-Module-Name=Coordinator
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,18 +24,13 @@
 package com.sun.hotspot.igv.coordinator;
 
 import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
-import com.sun.hotspot.igv.data.ChangedListener;
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.Pair;
+import com.sun.hotspot.igv.data.*;
 import java.awt.Image;
-import java.util.ArrayList;
 import java.util.List;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
-import org.openide.util.Utilities;
+import org.openide.util.ImageUtilities;
 import org.openide.util.lookup.AbstractLookup;
 import org.openide.util.lookup.InstanceContent;
 
@@ -45,107 +40,72 @@
  */
 public class FolderNode extends AbstractNode {
 
-    private GroupOrganizer organizer;
     private InstanceContent content;
-    private List<Pair<String, List<Group>>> structure;
-    private List<String> subFolders;
     private FolderChildren children;
 
-    private static class FolderChildren extends Children.Keys implements ChangedListener<Group> {
+    private static class FolderChildren extends Children.Keys<FolderElement> implements ChangedListener {
+
+        private final Folder folder;
 
-        private FolderNode parent;
-        private List<Group> registeredGroups;
-
-        public void setParent(FolderNode parent) {
-            this.parent = parent;
-            this.registeredGroups = new ArrayList<Group>();
+        public FolderChildren(Folder folder) {
+            this.folder = folder;
+            folder.getChangedEvent().addListener(this);
         }
 
         @Override
-        protected Node[] createNodes(Object arg0) {
-
-            for(Group g : registeredGroups) {
-                g.getChangedEvent().removeListener(this);
-            }
-            registeredGroups.clear();
-
-            Pair<String, List<Group>> p = (Pair<String, List<Group>>) arg0;
-            if (p.getLeft().length() == 0) {
-
-                List<Node> curNodes = new ArrayList<Node>();
-                for (Group g : p.getRight()) {
-                    for (InputGraph graph : g.getGraphs()) {
-                        curNodes.add(new GraphNode(graph));
-                    }
-                    g.getChangedEvent().addListener(this);
-                    registeredGroups.add(g);
-                }
-
-                Node[] result = new Node[curNodes.size()];
-                for (int i = 0; i < curNodes.size(); i++) {
-                    result[i] = curNodes.get(i);
-                }
-                return result;
-
-            } else {
-                return new Node[]{new FolderNode(p.getLeft(), parent.organizer, parent.subFolders, p.getRight())};
+        protected Node[] createNodes(FolderElement e) {
+             if (e instanceof InputGraph) {
+                return new Node[]{new GraphNode((InputGraph) e)};
+            } else if (e instanceof Folder) {
+                 return new Node[]{new FolderNode((Folder) e)};
+             } else {
+                return null;
             }
         }
 
         @Override
         public void addNotify() {
-            this.setKeys(parent.structure);
+            this.setKeys(folder.getElements());
         }
 
-        public void changed(Group source) {
-            List<Pair<String, List<Group>>> newStructure = new ArrayList<Pair<String, List<Group>>>();
-            for(Pair<String, List<Group>> p : parent.structure) {
-                refreshKey(p);
-            }
-        }
-    }
-
-    protected InstanceContent getContent() {
-        return content;
+        @Override
+        public void changed(Object source) {
+            addNotify();
+         }
     }
 
     @Override
     public Image getIcon(int i) {
-        return Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.gif");
+        return ImageUtilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.png");
     }
 
-    protected FolderNode(String name, GroupOrganizer organizer, List<String> subFolders, List<Group> groups) {
-        this(name, organizer, subFolders, groups, new FolderChildren(), new InstanceContent());
+    protected FolderNode(Folder folder) {
+        this(folder, new FolderChildren(folder), new InstanceContent());
     }
 
-    private FolderNode(String name, GroupOrganizer organizer, List<String> oldSubFolders, final List<Group> groups, FolderChildren children, InstanceContent content) {
+    private FolderNode(final Folder folder, FolderChildren children, InstanceContent content) {
         super(children, new AbstractLookup(content));
-        children.setParent(this);
         this.content = content;
         this.children = children;
-        content.add(new RemoveCookie() {
-
-            public void remove() {
-                for (Group g : groups) {
-                    if (g.getDocument() != null) {
-                        g.getDocument().removeGroup(g);
-                    }
+        if (folder instanceof FolderElement) {
+            final FolderElement folderElement = (FolderElement) folder;
+            this.setDisplayName(folderElement.getName());
+            content.add(new RemoveCookie() {
+                @Override
+                public void remove() {
+                    folderElement.getParent().removeElement(folderElement);
                 }
-            }
-        });
-        init(name, organizer, oldSubFolders, groups);
+            });
+        }
     }
 
-    public void init(String name, GroupOrganizer organizer, List<String> oldSubFolders, List<Group> groups) {
+    public void init(String name, List<Group> groups) {
         this.setDisplayName(name);
-        this.organizer = organizer;
-        this.subFolders = new ArrayList<String>(oldSubFolders);
-        if (name.length() > 0) {
-            this.subFolders.add(name);
+        children.addNotify();
+
+        for (Group g : groups) {
+            content.add(g);
         }
-        structure = organizer.organize(subFolders, groups);
-        assert structure != null;
-        children.addNotify();
     }
 
     @Override
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphCountGroupOrganizer.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.hotspot.igv.coordinator;
-
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.Pair;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class GraphCountGroupOrganizer implements GroupOrganizer {
-
-    public String getName() {
-        return "Graph count structure";
-    }
-
-    public List<Pair<String, List<Group>>> organize(List<String> subFolders, List<Group> groups) {
-
-        List<Pair<String, List<Group>>> result = new ArrayList<Pair<String, List<Group>>>();
-
-        if (subFolders.size() == 0) {
-            Map<Integer, List<Group>> map = new HashMap<Integer, List<Group>>();
-            for (Group g : groups) {
-                Integer cur = g.getGraphs().size();
-                if (!map.containsKey(cur)) {
-                    map.put(cur, new ArrayList<Group>());
-                }
-                map.get(cur).add(g);
-            }
-
-            SortedSet<Integer> keys = new TreeSet<Integer>(map.keySet());
-            for (Integer i : keys) {
-                result.add(new Pair<String, List<Group>>("Graph count " + i, map.get(i)));
-            }
-
-        } else if (subFolders.size() == 1) {
-            for (Group g : groups) {
-                List<Group> children = new ArrayList<Group>();
-                children.add(g);
-                Pair<String, List<Group>> p = new Pair<String, List<Group>>();
-                p.setLeft(g.getName());
-                p.setRight(children);
-                result.add(p);
-            }
-        } else if (subFolders.size() == 2) {
-            result.add(new Pair<String, List<Group>>("", groups));
-        }
-
-        return result;
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphNode.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphNode.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,23 +23,27 @@
  */
 package com.sun.hotspot.igv.coordinator;
 
+import com.sun.hotspot.igv.coordinator.actions.CloneGraphAction;
 import com.sun.hotspot.igv.coordinator.actions.DiffGraphAction;
 import com.sun.hotspot.igv.coordinator.actions.DiffGraphCookie;
-import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
+import com.sun.hotspot.igv.coordinator.actions.GraphCloneCookie;
+import com.sun.hotspot.igv.coordinator.actions.GraphOpenCookie;
+import com.sun.hotspot.igv.coordinator.actions.GraphRemoveCookie;
 import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.data.services.GraphViewer;
-import com.sun.hotspot.igv.data.services.InputGraphProvider;
 import com.sun.hotspot.igv.util.PropertiesSheet;
 import java.awt.Image;
 import javax.swing.Action;
 import org.openide.actions.OpenAction;
-import org.openide.cookies.OpenCookie;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
-import org.openide.nodes.Node;
+import org.openide.nodes.NodeAdapter;
+import org.openide.nodes.NodeEvent;
+import org.openide.nodes.NodeMemberEvent;
 import org.openide.nodes.Sheet;
+import org.openide.util.ImageUtilities;
 import org.openide.util.Lookup;
-import org.openide.util.Utilities;
 import org.openide.util.lookup.AbstractLookup;
 import org.openide.util.lookup.InstanceContent;
 
@@ -48,7 +52,6 @@
  * @author Thomas Wuerthinger
  */
 public class GraphNode extends AbstractNode {
-
     private InputGraph graph;
 
     /** Creates a new instance of GraphNode */
@@ -56,7 +59,7 @@
         this(graph, new InstanceContent());
     }
 
-    private GraphNode(final InputGraph graph, InstanceContent content) {
+    private GraphNode(InputGraph graph, InstanceContent content) {
         super(Children.LEAF, new AbstractLookup(content));
         this.graph = graph;
         this.setDisplayName(graph.getName());
@@ -66,19 +69,22 @@
 
         if (viewer != null) {
             // Action for opening the graph
-            content.add(new OpenCookie() {
-
-                public void open() {
-                    viewer.view(graph);
-                }
-            });
+            content.add(new GraphOpenCookie(viewer, graph));
         }
 
         // Action for removing a graph
-        content.add(new RemoveCookie() {
+        content.add(new GraphRemoveCookie(graph));
+
+        // Action for diffing to the current graph
+        content.add(new DiffGraphCookie(graph));
 
-            public void remove() {
-                graph.getGroup().removeGraph(graph);
+        // Action for cloning to the current graph
+        content.add(new GraphCloneCookie(viewer, graph));
+
+        this.addNodeListener(new NodeAdapter() {
+            @Override
+            public void childrenRemoved(NodeMemberEvent ev) {
+                GraphNode.this.graph = null;
             }
         });
     }
@@ -86,13 +92,17 @@
     @Override
     protected Sheet createSheet() {
         Sheet s = super.createSheet();
-        PropertiesSheet.initializeSheet(graph.getProperties(), s);
+        Properties p = new Properties();
+        p.add(graph.getProperties());
+        p.setProperty("nodeCount", Integer.toString(graph.getNodes().size()));
+        p.setProperty("edgeCount", Integer.toString(graph.getEdges().size()));
+        PropertiesSheet.initializeSheet(p, s);
         return s;
     }
 
     @Override
     public Image getIcon(int i) {
-        return Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/graph.gif");
+        return ImageUtilities.loadImage("com/sun/hotspot/igv/coordinator/images/graph.png");
     }
 
     @Override
@@ -101,30 +111,28 @@
     }
 
     @Override
-    public <T extends Node.Cookie> T getCookie(Class<T> aClass) {
-        if (aClass == DiffGraphCookie.class) {
-            InputGraphProvider graphProvider = Utilities.actionsGlobalContext().lookup(InputGraphProvider.class);
-
-            InputGraph graphA = null;
-            if (graphProvider != null) {
-                graphA = graphProvider.getGraph();
-            }
-
-            if (graphA != null && !graphA.isDifferenceGraph()) {
-                return (T) new DiffGraphCookie(graphA, graph);
-            }
-        }
-
-        return super.getCookie(aClass);
-    }
-
-    @Override
     public Action[] getActions(boolean b) {
-        return new Action[]{(Action) DiffGraphAction.findObject(DiffGraphAction.class, true), (Action) OpenAction.findObject(OpenAction.class, true)};
+        return new Action[]{(Action) DiffGraphAction.findObject(DiffGraphAction.class, true), (Action) CloneGraphAction.findObject(CloneGraphAction.class, true), (Action) OpenAction.findObject(OpenAction.class, true)};
     }
 
     @Override
     public Action getPreferredAction() {
         return (Action) OpenAction.findObject(OpenAction.class, true);
     }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (obj instanceof GraphNode) {
+            return (graph == ((GraphNode) obj).graph);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return graph.hashCode();
+    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.form	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.form	Tue May 05 19:27:08 2015 +0200
@@ -3,6 +3,8 @@
 <Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
@@ -14,28 +16,17 @@
 
   <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
   <SubComponents>
-    <Container class="javax.swing.JPanel" name="jPanel2">
+    <Container class="javax.swing.JScrollPane" name="treeView">
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new BeanTreeView();"/>
+      </AuxValues>
       <Constraints>
         <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
           <BorderConstraints direction="Center"/>
         </Constraint>
       </Constraints>
 
-      <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
-      <SubComponents>
-        <Container class="javax.swing.JScrollPane" name="jScrollPane1">
-          <AuxValues>
-            <AuxValue name="JavaCodeGenerator_CreateCodeCustom" type="java.lang.String" value="new BeanTreeView();"/>
-          </AuxValues>
-          <Constraints>
-            <Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout" value="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout$BorderConstraintsDescription">
-              <BorderConstraints direction="Center"/>
-            </Constraint>
-          </Constraints>
-
-          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
-        </Container>
-      </SubComponents>
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
     </Container>
   </SubComponents>
 </Form>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,37 +23,25 @@
  */
 package com.sun.hotspot.igv.coordinator;
 
-import com.sun.hotspot.igv.coordinator.actions.ImportAction;
-import com.sun.hotspot.igv.coordinator.actions.RemoveAction;
-import com.sun.hotspot.igv.coordinator.actions.RemoveAllAction;
-import com.sun.hotspot.igv.coordinator.actions.SaveAllAction;
-import com.sun.hotspot.igv.coordinator.actions.SaveAsAction;
-import com.sun.hotspot.igv.coordinator.actions.StructuredViewAction;
+import com.sun.hotspot.igv.connection.Server;
+import com.sun.hotspot.igv.coordinator.actions.*;
 import com.sun.hotspot.igv.data.GraphDocument;
-import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.services.GroupCallback;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import com.sun.hotspot.igv.data.services.GroupReceiver;
 import java.awt.BorderLayout;
-import java.awt.Component;
 import java.io.IOException;
 import java.io.ObjectInput;
 import java.io.ObjectOutput;
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import javax.swing.BoxLayout;
-import javax.swing.JPanel;
 import javax.swing.UIManager;
 import javax.swing.border.Border;
 import org.openide.ErrorManager;
+import org.openide.actions.GarbageCollectAction;
 import org.openide.awt.Toolbar;
 import org.openide.awt.ToolbarPool;
 import org.openide.explorer.ExplorerManager;
 import org.openide.explorer.ExplorerUtils;
 import org.openide.explorer.view.BeanTreeView;
-import org.openide.util.Lookup;
 import org.openide.util.LookupEvent;
 import org.openide.util.LookupListener;
 import org.openide.util.NbBundle;
@@ -72,7 +60,8 @@
     private ExplorerManager manager;
     private GraphDocument document;
     private FolderNode root;
-    private GroupOrganizer organizer;
+    private Server server;
+    private Server binaryServer;
 
     private OutlineTopComponent() {
         initComponents();
@@ -88,17 +77,9 @@
 
     private void initListView() {
         manager = new ExplorerManager();
-        organizer = new StandardGroupOrganizer();
-        root = new FolderNode("", organizer, new ArrayList<String>(), document.getGroups());
+        root = new FolderNode(document);
         manager.setRootContext(root);
-        ((BeanTreeView) this.jScrollPane1).setRootVisible(false);
-
-        document.getChangedEvent().addListener(new ChangedListener<GraphDocument>() {
-
-            public void changed(GraphDocument document) {
-                updateStructure();
-            }
-        });
+        ((BeanTreeView) this.treeView).setRootVisible(false);
 
         associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
     }
@@ -111,61 +92,41 @@
         this.add(toolbar, BorderLayout.NORTH);
 
         toolbar.add(ImportAction.get(ImportAction.class));
-        toolbar.add(((NodeAction) RemoveAction.get(RemoveAction.class)).createContextAwareInstance(this.getLookup()));
-        toolbar.add(RemoveAllAction.get(RemoveAllAction.class));
 
         toolbar.add(((NodeAction) SaveAsAction.get(SaveAsAction.class)).createContextAwareInstance(this.getLookup()));
         toolbar.add(SaveAllAction.get(SaveAllAction.class));
 
-        toolbar.add(StructuredViewAction.get(StructuredViewAction.class).getToolbarPresenter());
+        toolbar.add(((NodeAction) RemoveAction.get(RemoveAction.class)).createContextAwareInstance(this.getLookup()));
+        toolbar.add(RemoveAllAction.get(RemoveAllAction.class));
+
+        toolbar.add(GarbageCollectAction.get(GarbageCollectAction.class).getToolbarPresenter());
 
         for (Toolbar tb : ToolbarPool.getDefault().getToolbars()) {
             tb.setVisible(false);
         }
-
-        initOrganizers();
-    }
-
-    public void setOrganizer(GroupOrganizer organizer) {
-        this.organizer = organizer;
-        updateStructure();
-    }
-
-    private void initOrganizers() {
-
     }
 
     private void initReceivers() {
 
         final GroupCallback callback = new GroupCallback() {
 
+            @Override
             public void started(Group g) {
-                getDocument().addGroup(g);
+                synchronized(OutlineTopComponent.this) {
+                    getDocument().addElement(g);
+                }
             }
         };
 
-        Collection<? extends GroupReceiver> receivers = Lookup.getDefault().lookupAll(GroupReceiver.class);
-        if (receivers.size() > 0) {
-            JPanel panel = new JPanel();
-            panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
-
-            for (GroupReceiver r : receivers) {
-                Component c = r.init(callback);
-                panel.add(c);
-            }
-
-            jPanel2.add(panel, BorderLayout.PAGE_START);
-        }
-    }
-
-    private void updateStructure() {
-        root.init("", organizer, new ArrayList<String>(), document.getGroups());
+        server = new Server(getDocument(), callback, false);
+        binaryServer = new Server(getDocument(), callback, true);
     }
 
     public void clear() {
         document.clear();
     }
 
+    @Override
     public ExplorerManager getExplorerManager() {
         return manager;
     }
@@ -221,6 +182,25 @@
         return PREFERRED_ID;
     }
 
+    @Override
+    public void requestActive() {
+        super.requestActive();
+        treeView.requestFocus();
+    }
+
+    @Override
+    public boolean requestFocus(boolean temporary) {
+        treeView.requestFocus();
+        return super.requestFocus(temporary);
+    }
+
+    @Override
+    protected boolean requestFocusInWindow(boolean temporary) {
+        treeView.requestFocus();
+        return super.requestFocusInWindow(temporary);
+    }
+
+    @Override
     public void resultChanged(LookupEvent lookupEvent) {
     }
 
@@ -228,7 +208,7 @@
     public void readExternal(ObjectInput objectInput) throws IOException, ClassNotFoundException {
         // Not called when user starts application for the first time
         super.readExternal(objectInput);
-        ((BeanTreeView) this.jScrollPane1).setRootVisible(false);
+        ((BeanTreeView) this.treeView).setRootVisible(false);
     }
 
     @Override
@@ -253,19 +233,13 @@
     // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
     private void initComponents() {
 
-        jPanel2 = new javax.swing.JPanel();
-        jScrollPane1 = new BeanTreeView();
+        treeView = new BeanTreeView();
 
         setLayout(new java.awt.BorderLayout());
-
-        jPanel2.setLayout(new java.awt.BorderLayout());
-        jPanel2.add(jScrollPane1, java.awt.BorderLayout.CENTER);
-
-        add(jPanel2, java.awt.BorderLayout.CENTER);
+        add(treeView, java.awt.BorderLayout.CENTER);
     }// </editor-fold>//GEN-END:initComponents
 
     // Variables declaration - do not modify//GEN-BEGIN:variables
-    private javax.swing.JPanel jPanel2;
-    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JScrollPane treeView;
     // End of variables declaration//GEN-END:variables
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml	Tue May 05 19:27:08 2015 +0200
@@ -4,7 +4,7 @@
     <Row>
         <Toolbar name="Edit" position="1" visible="false"/>
         <Toolbar name="File" position="1" visible="false" />
-        <Toolbar name="Memory" position="1" visible="false" />
+        <Toolbar name="Memory" position="1" visible="true" />
     </Row>
     <Row>
         <Toolbar name="WorkspaceSwitcher" />
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardGroupOrganizer.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.hotspot.igv.coordinator;
-
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import com.sun.hotspot.igv.data.Pair;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class StandardGroupOrganizer implements GroupOrganizer {
-
-    public String getName() {
-        return "-- None --";
-    }
-
-    public List<Pair<String, List<Group>>> organize(List<String> subFolders, List<Group> groups) {
-
-        List<Pair<String, List<Group>>> result = new ArrayList<Pair<String, List<Group>>>();
-
-        if (groups.size() == 1 && subFolders.size() > 0) {
-            result.add(new Pair<String, List<Group>>("", groups));
-        } else {
-            for (Group g : groups) {
-                List<Group> children = new ArrayList<Group>();
-                children.add(g);
-                Pair<String, List<Group>> p = new Pair<String, List<Group>>();
-                p.setLeft(g.getName());
-                p.setRight(children);
-                result.add(p);
-            }
-        }
-
-        return result;
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/Bundle.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/Bundle.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,18 +1,10 @@
-CTL_EditFilterAction=Edit...
 CTL_ImportAction=Open...
 CTL_OpenGraphAction=View graph
 CTL_DiffGraphAction=Difference to current graph
-CTL_RemoveAction=Remove methods
-CTL_ApplyFilterAction=Apply
-CTL_FilterAction=Open Filter Window
-CTL_AppliedFilterAction=Open AppliedFilter Window
-CTL_OutlineAction=Open Outline Window
-CTL_MoveFilterUpAction=Move upwards
-CTL_MoveFilterDownAction=Move downwards
-CTL_RemoveFilterAction=Remove
-CTL_RemoveFilterSettingsAction=Remove filter setting
-CTL_SaveAsAction=Save selected methods...
-CTL_SaveAllAction=Save all...
-CTL_SaveFilterSettingsAction=Save filter settings...
-CTL_PropertiesAction=Open Properties Window
+CTL_RemoveAction=Remove selected graphs and groups
+CTL_RemoveAllAction=Remove all graphs and groups
+CTL_OutlineAction=Outline
+CTL_SaveAsAction=Save selected groups...
+CTL_SaveAllAction=Save all groups...
+CTL_PropertiesAction=Open Properties Window 
 CTL_NewFilterAction=New filter...
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/CloneGraphAction.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.coordinator.actions;
+
+import org.openide.nodes.Node;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CookieAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class CloneGraphAction extends CookieAction {
+
+    @Override
+    protected void performAction(Node[] activatedNodes) {
+        GraphCloneCookie c = activatedNodes[0].getCookie(GraphCloneCookie.class);
+        assert c != null;
+        c.openClone();
+    }
+
+    @Override
+    protected int mode() {
+        return CookieAction.MODE_EXACTLY_ONE;
+    }
+
+    @Override
+    protected boolean enable(Node[] activatedNodes) {
+        boolean b = super.enable(activatedNodes);
+        if (b) {
+            assert activatedNodes.length == 1;
+            GraphCloneCookie c = activatedNodes[0].getCookie(GraphCloneCookie.class);
+            assert c != null;
+            return true;
+        }
+
+        return false;
+    }
+
+    @Override
+    public String getName() {
+        return "Open clone";
+    }
+
+    @Override
+    protected Class<?>[] cookieClasses() {
+        return new Class<?>[]{
+            GraphCloneCookie.class
+        };
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/coordinator/images/graph.png";
+    }
+
+    @Override
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
+
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,30 +35,49 @@
  */
 public final class DiffGraphAction extends CookieAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         DiffGraphCookie c = activatedNodes[0].getCookie(DiffGraphCookie.class);
+        assert c != null;
         c.openDiff();
     }
 
+    @Override
     protected int mode() {
         return CookieAction.MODE_EXACTLY_ONE;
     }
 
+    @Override
+    protected boolean enable(Node[] activatedNodes) {
+        boolean b = super.enable(activatedNodes);
+        if (b) {
+            assert activatedNodes.length == 1;
+            DiffGraphCookie c = activatedNodes[0].getCookie(DiffGraphCookie.class);
+            assert c != null;
+            return c.isPossible();
+        }
+
+        return false;
+    }
+
+    @Override
     public String getName() {
         return NbBundle.getMessage(DiffGraphAction.class, "CTL_DiffGraphAction");
     }
 
-    protected Class[] cookieClasses() {
-        return new Class[]{
+    @Override
+    protected Class<?>[] cookieClasses() {
+        return new Class<?>[]{
             DiffGraphCookie.class
         };
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/diff.gif";
+        return "com/sun/hotspot/igv/coordinator/images/diff.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -68,3 +87,4 @@
         return false;
     }
 }
+
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphCookie.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/DiffGraphCookie.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -21,12 +21,13 @@
  * questions.
  *
  */
-
 package com.sun.hotspot.igv.coordinator.actions;
 
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.services.GraphViewer;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
 import com.sun.hotspot.igv.difference.Difference;
+import com.sun.hotspot.igv.util.LookupHistory;
 import org.openide.nodes.Node;
 import org.openide.util.Lookup;
 
@@ -36,21 +37,30 @@
  */
 public class DiffGraphCookie implements Node.Cookie {
 
-    private InputGraph a;
-    private InputGraph b;
+    private InputGraph graph;
+
+    public DiffGraphCookie(InputGraph graph) {
+        this.graph = graph;
+    }
 
-    public DiffGraphCookie(InputGraph a, InputGraph b) {
-        this.a = a;
-        this.b = b;
+    private InputGraph getCurrentGraph() {
+        InputGraphProvider graphProvider = LookupHistory.getLast(InputGraphProvider.class);
+        if (graphProvider != null) {
+            return graphProvider.getGraph();
+        }
+        return null;
+    }
+
+    public boolean isPossible() {
+        return getCurrentGraph() != null;
     }
 
     public void openDiff() {
-
+        InputGraph other = getCurrentGraph();
         final GraphViewer viewer = Lookup.getDefault().lookup(GraphViewer.class);
-
-        if(viewer != null) {
-            InputGraph diffGraph = Difference.createDiffGraph(a, b);
-            viewer.view(diffGraph);
+        if (viewer != null) {
+            InputGraph diffGraph = Difference.createDiffGraph(other, graph);
+            viewer.view(diffGraph, true);
         }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/GraphCloneCookie.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.coordinator.actions;
+
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.services.GraphViewer;
+import org.openide.nodes.Node;
+
+public class GraphCloneCookie implements Node.Cookie {
+
+    private final GraphViewer viewer;
+    private final InputGraph graph;
+
+    public GraphCloneCookie(GraphViewer viewer, InputGraph graph) {
+        this.viewer = viewer;
+        this.graph = graph;
+    }
+
+    public void openClone() {
+        viewer.view(graph, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/GraphOpenCookie.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.coordinator.actions;
+
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.services.GraphViewer;
+import org.openide.cookies.OpenCookie;
+
+public class GraphOpenCookie implements OpenCookie {
+
+    private final GraphViewer viewer;
+    private final InputGraph graph;
+
+    public GraphOpenCookie(GraphViewer viewer, InputGraph graph) {
+        this.viewer = viewer;
+        this.graph = graph;
+    }
+
+    @Override
+    public void open() {
+        viewer.view(graph, false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/GraphRemoveCookie.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.coordinator.actions;
+
+import com.sun.hotspot.igv.data.InputGraph;
+
+public class GraphRemoveCookie implements RemoveCookie {
+    private final InputGraph graph;
+
+    public GraphRemoveCookie(InputGraph graph) {
+        this.graph = graph;
+    }
+
+    @Override
+    public void remove() {
+        graph.getGroup().removeElement(graph);
+    }
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/ImportAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/ImportAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,51 +26,54 @@
 
 import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
 import com.sun.hotspot.igv.data.GraphDocument;
+import com.sun.hotspot.igv.data.serialization.BinaryParser;
+import com.sun.hotspot.igv.data.serialization.GraphParser;
+import com.sun.hotspot.igv.data.serialization.ParseMonitor;
 import com.sun.hotspot.igv.data.serialization.Parser;
 import com.sun.hotspot.igv.settings.Settings;
-import com.sun.hotspot.igv.data.serialization.XMLParser;
 import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import java.io.File;
-import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
+import java.nio.channels.FileChannel;
+import java.nio.file.StandardOpenOption;
 import javax.swing.Action;
 import javax.swing.JFileChooser;
 import javax.swing.KeyStroke;
+import javax.swing.SwingUtilities;
 import javax.swing.filechooser.FileFilter;
 import org.netbeans.api.progress.ProgressHandle;
 import org.netbeans.api.progress.ProgressHandleFactory;
-import org.openide.DialogDisplayer;
-import org.openide.NotifyDescriptor;
+import org.openide.util.Exceptions;
 import org.openide.util.HelpCtx;
 import org.openide.util.NbBundle;
 import org.openide.util.RequestProcessor;
 import org.openide.util.actions.CallableSystemAction;
-import org.openide.xml.XMLUtil;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
 public final class ImportAction extends CallableSystemAction {
+    private static final int WORKUNITS = 10000;
 
     public static FileFilter getFileFilter() {
         return new FileFilter() {
 
+            @Override
             public boolean accept(File f) {
-                return f.getName().toLowerCase().endsWith(".xml") || f.isDirectory();
+                return f.getName().toLowerCase().endsWith(".xml") || f.getName().toLowerCase().endsWith(".bgv") || f.isDirectory();
             }
 
+            @Override
             public String getDescription() {
-                return "XML files (*.xml)";
+                return "Graph files (*.xml, *.bgv)";
             }
         };
     }
 
+    @Override
     public void performAction() {
 
         JFileChooser fc = new JFileChooser();
@@ -86,84 +89,79 @@
             }
 
             Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
-
             try {
-                final XMLReader reader = XMLUtil.createXMLReader();
-                final FileInputStream inputStream = new FileInputStream(file);
-                final InputSource is = new InputSource(inputStream);
-
+                final FileChannel channel = FileChannel.open(file.toPath(), StandardOpenOption.READ);
                 final ProgressHandle handle = ProgressHandleFactory.createHandle("Opening file " + file.getName());
-                final int basis = 1000;
-                handle.start(basis);
-                final int start = inputStream.available();
-
-                final XMLParser.ParseMonitor parseMonitor = new XMLParser.ParseMonitor() {
-
-                    public void setProgress(double d) {
+                handle.start(WORKUNITS);
+                final long start = channel.size();
+                ParseMonitor monitor = new ParseMonitor() {
+                    @Override
+                    public void updateProgress() {
                         try {
-                            int curAvailable = inputStream.available();
-                            int prog = (int) (basis * (double) (start - curAvailable) / (double) start);
+                            int prog = (int) (WORKUNITS * (double) channel.position() / (double) start);
                             handle.progress(prog);
                         } catch (IOException ex) {
                         }
                     }
-
+                    @Override
                     public void setState(String state) {
-                        setProgress(0.0);
+                        updateProgress();
                         handle.progress(state);
                     }
                 };
-                final Parser parser = new Parser();
+                final GraphParser parser;
                 final OutlineTopComponent component = OutlineTopComponent.findInstance();
-
-                component.requestActive();
-
+                if (file.getName().endsWith(".xml")) {
+                    parser = new Parser(channel, monitor, null);
+                } else if (file.getName().endsWith(".bgv")) {
+                    parser = new BinaryParser(channel, monitor, component.getDocument(), null);
+                } else {
+                    parser = null;
+                }
                 RequestProcessor.getDefault().post(new Runnable() {
-
+                    @Override
                     public void run() {
-                        GraphDocument document = null;
                         try {
-                            document = parser.parse(reader, is, parseMonitor);
-                            parseMonitor.setState("Finishing");
-                            component.getDocument().addGraphDocument(document);
-                        } catch (SAXException ex) {
-                            String s = "Exception during parsing the XML file, could not load document!";
-                            if (ex instanceof XMLParser.MissingAttributeException) {
-                                XMLParser.MissingAttributeException e = (XMLParser.MissingAttributeException) ex;
-                                s += "\nMissing attribute \"" + e.getAttributeName() + "\"";
+                            final GraphDocument document = parser.parse();
+                            if (document != null) {
+                                SwingUtilities.invokeLater(new Runnable(){
+                                    @Override
+                                    public void run() {
+                                        component.requestActive();
+                                        component.getDocument().addGraphDocument(document);
+                                    }
+                                });
                             }
-                            ex.printStackTrace();
-                            NotifyDescriptor d = new NotifyDescriptor.Message(s, NotifyDescriptor.ERROR_MESSAGE);
-                            DialogDisplayer.getDefault().notify(d);
+                        } catch (IOException ex) {
+                            Exceptions.printStackTrace(ex);
                         }
                         handle.finish();
                     }
                 });
-
-            } catch (SAXException ex) {
-                ex.printStackTrace();
             } catch (FileNotFoundException ex) {
-                ex.printStackTrace();
+                Exceptions.printStackTrace(ex);
             } catch (IOException ex) {
-                ex.printStackTrace();
+                Exceptions.printStackTrace(ex);
             }
         }
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(ImportAction.class, "CTL_ImportAction");
     }
 
     public ImportAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Open an XML graph document");
+        putValue(Action.SHORT_DESCRIPTION, "Open XML graph document...");
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_MASK));
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/import.gif";
+        return "com/sun/hotspot/igv/coordinator/images/import.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/OutlineAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/OutlineAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
 
 package com.sun.hotspot.igv.coordinator.actions;
 
-import com.sun.hotspot.igv.coordinator.*;
+import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
 import java.awt.event.ActionEvent;
 import javax.swing.AbstractAction;
 import org.openide.util.NbBundle;
@@ -40,6 +40,7 @@
         super(NbBundle.getMessage(OutlineAction.class, "CTL_OutlineAction"));
     }
 
+    @Override
     public void actionPerformed(ActionEvent evt) {
         TopComponent win = OutlineTopComponent.findInstance();
         win.open();
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,7 @@
  */
 public final class RemoveAction extends NodeAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         for (Node n : activatedNodes) {
             RemoveCookie removeCookie = n.getCookie(RemoveCookie.class);
@@ -46,18 +47,20 @@
     }
 
     public RemoveAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Remove");
+        putValue(Action.SHORT_DESCRIPTION, "Remove selected graphs and groups");
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(RemoveAction.class, "CTL_RemoveAction");
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/remove.gif";
+        return "com/sun/hotspot/igv/coordinator/images/remove.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -67,6 +70,7 @@
         return false;
     }
 
+    @Override
     protected boolean enable(Node[] nodes) {
         return nodes.length > 0;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAllAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAllAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,20 +40,22 @@
 public final class RemoveAllAction extends CallableSystemAction {
 
 
+    @Override
     public String getName() {
-        return NbBundle.getMessage(RemoveAllAction.class, "CTL_ImportAction");
+        return NbBundle.getMessage(RemoveAllAction.class, "CTL_RemoveAllAction");
     }
 
     public RemoveAllAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Remove all methods");
+        putValue(Action.SHORT_DESCRIPTION, "Remove all graphs and groups");
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_SHIFT, InputEvent.CTRL_MASK));
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/removeall.gif";
+        return "com/sun/hotspot/igv/coordinator/images/removeall.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveCookie.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveCookie.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,17 +39,19 @@
  */
 public final class SaveAllAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         final OutlineTopComponent component = OutlineTopComponent.findInstance();
         SaveAsAction.save(component.getDocument());
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(SaveAllAction.class, "CTL_SaveAllAction");
     }
 
     public SaveAllAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Save all methods to XML file");
+        putValue(Action.SHORT_DESCRIPTION, "Save all groups to XML file...");
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));
     }
 
@@ -58,6 +60,7 @@
         return "com/sun/hotspot/igv/coordinator/images/saveall.gif";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAsAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,12 +28,8 @@
 import com.sun.hotspot.igv.data.Group;
 import com.sun.hotspot.igv.data.serialization.Printer;
 import com.sun.hotspot.igv.settings.Settings;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.Writer;
+import java.io.*;
+import javax.swing.Action;
 import javax.swing.JFileChooser;
 import org.openide.nodes.Node;
 import org.openide.util.HelpCtx;
@@ -47,12 +43,17 @@
  */
 public final class SaveAsAction extends NodeAction {
 
+    public SaveAsAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Save selected groups to XML file...");
+    }
+
+    @Override
     protected void performAction(Node[] activatedNodes) {
 
         GraphDocument doc = new GraphDocument();
         for (Node n : activatedNodes) {
             Group group = n.getLookup().lookup(Group.class);
-            doc.addGroup(group);
+            doc.addElement(group);
         }
 
         save(doc);
@@ -75,10 +76,10 @@
             }
             Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
             try {
-                Writer writer = new OutputStreamWriter(new FileOutputStream(file));
-                Printer p = new Printer();
-                p.export(writer, doc);
-                writer.close();
+                try (Writer writer = new OutputStreamWriter(new FileOutputStream(file))) {
+                    Printer p = new Printer();
+                    p.export(writer, doc);
+                }
             } catch (FileNotFoundException e) {
                 e.printStackTrace();
             } catch (IOException e) {
@@ -92,15 +93,17 @@
         return CookieAction.MODE_SOME;
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(SaveAsAction.class, "CTL_SaveAsAction");
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/coordinator/images/save.gif";
+        return "com/sun/hotspot/igv/coordinator/images/save.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -110,6 +113,7 @@
         return false;
     }
 
+    @Override
     protected boolean enable(Node[] nodes) {
 
         int cnt = 0;
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/StructuredViewAction.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,180 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.hotspot.igv.coordinator.actions;
-
-import com.sun.hotspot.igv.coordinator.OutlineTopComponent;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import java.awt.Component;
-import java.awt.Image;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.ItemEvent;
-import java.awt.event.ItemListener;
-import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import javax.swing.Action;
-import javax.swing.ButtonGroup;
-import javax.swing.ImageIcon;
-import javax.swing.JButton;
-import javax.swing.JCheckBoxMenuItem;
-import javax.swing.JMenuItem;
-import javax.swing.JPopupMenu;
-import javax.swing.event.PopupMenuEvent;
-import javax.swing.event.PopupMenuListener;
-import org.openide.awt.DropDownButtonFactory;
-import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
-import org.openide.util.Utilities;
-import org.openide.util.actions.CallableSystemAction;
-
-public class StructuredViewAction extends CallableSystemAction {
-
-    private static JButton dropDownButton;
-    private static ButtonGroup buttonGroup;
-    private static JPopupMenu popup;
-    private MyMenuItemListener menuItemListener;
-    private Map<JMenuItem, GroupOrganizer> map;
-
-    public StructuredViewAction() {
-
-        putValue(Action.SHORT_DESCRIPTION, "Cluster nodes into blocks");
-    }
-
-    @Override
-    public Component getToolbarPresenter() {
-
-        Image iconImage = Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/structure.gif");
-        ImageIcon icon = new ImageIcon(iconImage);
-
-        popup = new JPopupMenu();
-
-        menuItemListener = new MyMenuItemListener();
-
-        buttonGroup = new ButtonGroup();
-
-        Collection<? extends GroupOrganizer> organizersCollection = Lookup.getDefault().lookupAll(GroupOrganizer.class);
-
-        List<GroupOrganizer> organizers = new ArrayList<GroupOrganizer>(organizersCollection);
-        Collections.sort(organizers, new Comparator<GroupOrganizer>() {
-            public int compare(GroupOrganizer a, GroupOrganizer b) {
-                return a.getName().compareTo(b.getName());
-            }
-        });
-
-        map = new HashMap<JMenuItem, GroupOrganizer>();
-
-        boolean first = true;
-        for(GroupOrganizer organizer : organizers) {
-            JCheckBoxMenuItem item = new JCheckBoxMenuItem(organizer.getName());
-            map.put(item, organizer);
-            item.addActionListener(menuItemListener);
-            buttonGroup.add(item);
-            popup.add(item);
-            if(first) {
-                item.setSelected(true);
-                first = false;
-            }
-        }
-
-        dropDownButton = DropDownButtonFactory.createDropDownButton(
-                new ImageIcon(
-                new BufferedImage(32, 32, BufferedImage.TYPE_BYTE_GRAY)),
-                popup);
-
-        dropDownButton.setIcon(icon);
-
-        dropDownButton.setToolTipText("Insert Layer Registration");
-
-        dropDownButton.addItemListener(new ItemListener() {
-
-            public void itemStateChanged(ItemEvent e) {
-                int state = e.getStateChange();
-                if (state == ItemEvent.SELECTED) {
-                    performAction();
-                }
-            }
-        });
-
-        dropDownButton.addActionListener(new ActionListener() {
-            public void actionPerformed(ActionEvent e) {
-                performAction();
-            }
-        });
-
-        popup.addPopupMenuListener(new PopupMenuListener() {
-
-            public void popupMenuCanceled(PopupMenuEvent e) {
-                dropDownButton.setSelected(false);
-            }
-
-            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
-                dropDownButton.setSelected(false);
-            }
-
-            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
-                dropDownButton.setSelected(true);
-            }
-        });
-
-        return dropDownButton;
-
-    }
-
-    private class MyMenuItemListener implements ActionListener {
-
-        public void actionPerformed(ActionEvent ev) {
-            JMenuItem item = (JMenuItem) ev.getSource();
-            GroupOrganizer organizer = map.get(item);
-            assert organizer != null : "Organizer must exist!";
-            OutlineTopComponent.findInstance().setOrganizer(organizer);
-        }
-    }
-
-
-    @Override
-    public void performAction() {
-        popup.show(dropDownButton, 0, dropDownButton.getHeight());
-    }
-
-    public String getName() {
-        return "Structured View";
-    }
-
-    public HelpCtx getHelpCtx() {
-        return HelpCtx.DEFAULT_HELP;
-    }
-
-    @Override
-    protected boolean asynchronous() {
-        return false;
-    }
-
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/customLeftWsmode.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/customLeftWsmode.xml	Tue May 05 19:27:08 2015 +0200
@@ -4,12 +4,8 @@
     <kind type="view" />
     <state type="joined" />
     <constraints>
-        <path orientation="horizontal" number="0" weight="0.779245283018868"/>
-        <path orientation="vertical" number="0" weight="0.7511825922421949"/>
-        <path orientation="horizontal" number="0" weight="0.5"/>
-        <path orientation="vertical" number="20" weight="0.7"/>
-        <path orientation="horizontal" number="40" weight="0.55"/>
-        <path orientation="horizontal" number="0" weight="0.2711864406779661"/>
+        <path orientation="horizontal" number="0" weight="0.2"/>
+        <path orientation="vertical" number="0" weight="0.75"/>
     </constraints>
     <bounds x="0" y="0" width="0" height="0" />
     <frame state="0"/>
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/diff.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/diff.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/folder.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/folder.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/graph.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/graph.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/import.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/import.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/remove.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/remove.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/removeall.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/removeall.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/save.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/save.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/saveall.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/structure.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/structure.png has changed
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml	Tue May 05 19:27:08 2015 +0200
@@ -1,110 +1,194 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.2//EN" "http://www.netbeans.org/dtds/filesystem-1_2.dtd">
 <filesystem>
-    <attr name="Actions\Edit\com-sun-hotspot-igv-bytecodes-SelectBytecodesAction.instance\position" intvalue="200"/>
-    <attr name="Actions\Edit\org-netbeans-core-ui-sysopen-SystemOpenAction.instance\position" intvalue="100"/>
-    <attr name="Actions\Edit\org-openide-actions-CopyAction.instance\position" intvalue="1300"/>
-    <attr name="Actions\Edit\org-openide-actions-CutAction.instance\position" intvalue="1400"/>
-    <attr name="Actions\Edit\org-openide-actions-DeleteAction.instance\position" intvalue="1500"/>
-    <attr name="Actions\Edit\org-openide-actions-FindAction.instance\position" intvalue="1600"/>
-    <attr name="Actions\Edit\org-openide-actions-GotoAction.instance\position" intvalue="1700"/>
-    <attr name="Actions\Edit\org-openide-actions-PasteAction.instance\position" intvalue="1800"/>
-    <attr name="Actions\Edit\org-openide-actions-RedoAction.instance\position" intvalue="1900"/>
-    <attr name="Actions\Edit\org-openide-actions-ReplaceAction.instance\position" intvalue="2000"/>
-    <attr name="Actions\Edit\org-openide-actions-UndoAction.instance\position" intvalue="2100"/>
-
     <folder name="Actions">
         <folder name="File">
-            <file name="com-sun-hotspot-igv-coordinator-actions-SaveAsAction.instance">
-                <attr name="position" intvalue="700"/>
-            </file>
-            <file name="com-sun-hotspot-igv-coordinator-actions-SaveAllAction.instance">
-                <attr name="position" intvalue="800"/>
-            </file>
-            <file name="com-sun-hotspot-igv-coordinator-actions-ImportAction.instance">
-                <attr name="position" intvalue="1000"/>
-            </file>
+            <file name="com-sun-hotspot-igv-coordinator-actions-SaveAsAction.instance"/>
+            <file name="com-sun-hotspot-igv-coordinator-actions-SaveAllAction.instance"/>
+            <file name="com-sun-hotspot-igv-coordinator-actions-ImportAction.instance"/>
         </folder>
         <folder name="Edit">
-
-            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance">
-                <attr name="position" intvalue="1200"/>
-            </file>
+            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance"/>
+            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.instance"/>
         </folder>
         <folder name="Window">
             <file name="com-sun-hotspot-igv-coordinator-actions-OutlineAction.instance"/>
         </folder>
     </folder>
+    
     <folder name="Menu">
         <folder name="File">
+            <file name="Separator2.instance_hidden"/>
+            <file name="Separator3.instance_hidden"/>
+            <file name="SeparatorOpen.instance_hidden"/>
             <file name="com-sun-hotspot-igv-coordinator-actions-ImportAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/File/com-sun-hotspot-igv-coordinator-actions-ImportAction.instance"/>
                 <attr name="position" intvalue="100"/>
             </file>
-            <file name="MySeparator2.instance">
+            <file name="SeparatorSave.instance">
                 <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
-                <attr name="position" intvalue="300"/>
+                <attr name="position" intvalue="150"/>
             </file>
             <file name="com-sun-hotspot-igv-coordinator-actions-SaveAsAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/File/com-sun-hotspot-igv-coordinator-actions-SaveAsAction.instance"/>
-                <attr name="position" intvalue="300"/>
+                <attr name="position" intvalue="200"/>
             </file>
             <file name="com-sun-hotspot-igv-coordinator-actions-SaveAllAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/File/com-sun-hotspot-igv-coordinator-actions-SaveAllAction.instance"/>
-                <attr name="position" intvalue="400"/>
-            </file>
-            <file name="MySeparator3.instance">
-                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
-                <attr name="position" intvalue="500"/>
+                <attr name="position" intvalue="300"/>
             </file>
-
-            <file name="org-netbeans-modules-openfile-OpenFileAction.instance_hidden"/>
-            <file name="org-openide-actions-PageSetupAction.instance_hidden"/>
-            <file name="org-openide-actions-PrintAction.instance_hidden"/>
-            <file name="org-openide-actions-SaveAction.instance_hidden"/>
-            <file name="org-openide-actions-SaveAllAction.instance_hidden"/>
-            <file name="org-openide-actions-SaveAsAction.shadow_hidden"/>
-        </folder>
-        <folder name="Edit">
-            <file name="com-sun-hotspot-igv-coordinator-actions-SaveFilterSettingsAction.shadow">
-                <attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-SaveFilterSettingsAction.instance"/>
+            <file name="SeparatorRemove.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="350"/>
             </file>
             <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance"/>
+                <attr name="position" intvalue="400" />
             </file>
-            <file name="org-netbeans-core-actions-JumpNextAction.shadow_hidden"/>
-            <file name="org-netbeans-core-actions-JumpPrevAction.shadow_hidden"/>
-            <file name="org-openide-actions-CutAction.instance_hidden"/>
-            <file name="org-openide-actions-CopyAction.instance_hidden"/>
-            <file name="org-openide-actions-PasteAction.instance_hidden"/>
-            <file name="org-openide-actions-DeleteAction.instance_hidden"/>
-            <file name="org-openide-actions-FindAction.instance_hidden"/>
-            <file name="org-openide-actions-ReplaceAction.instance_hidden"/>
-            <file name="org-openide-actions-JumpNextAction.shadow_hidden"/>
-            <file name="org-openide-actions-JumpPrevAction.shadow_hidden"/>
+            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-RemoveAllAction.instance"/>
+                <attr name="position" intvalue="500" />
+            </file>
+            
+            <!-- Hidden menu entries from other modules -->
+            <file name="org-netbeans-modules-editor-ExportHtmlAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-openfile-OpenFileAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-openfile-RecentFileAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-print-action-PageSetupAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-print-action-PrintAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-CloseProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-CustomizeProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-NewFile.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-NewProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-OpenProject.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-RecentProjects.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-groups-GroupsMenu.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAction.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAllAction.shadow_hidden"/>
+            <file name="org-openide-actions-SaveAsAction.shadow_hidden"/>
         </folder>
-        <file name="GoTo_hidden"/>
-        <folder name="View">
+        
+        <folder name="Edit">
+            <!-- Hidden menu entries from other modules -->
             <file name="Separator1.instance_hidden"/>
             <file name="Separator2.instance_hidden"/>
-            <file name="org-netbeans-core-actions-HTMLViewAction.instance_hidden"/>
-            <file name="org-netbeans-core-actions-LogAction.instance_hidden"/>
+            <file name="SeparatorAfterFindPrevious.instance_hidden"/>
+            <file name="SeparatorAfterProjectsSearch.instance_hidden"/>
+            <file name="WhereUsedAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$FindNextAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$FindPreviousAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$FindSelectionAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$PasteFormattedAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$SelectAllAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$SelectIdentifierAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$StartMacroRecordingAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-MainMenuAction$StopMacroRecordingAction.instance_hidden"/>
+            <file name="org-netbeans-modules-search-FindInFilesAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-search-ReplaceInFilesAction.shadow_hidden"/>
+            <file name="org-openide-actions-CopyAction.shadow_hidden"/>
+            <file name="org-openide-actions-CutAction.shadow_hidden"/>
+            <file name="org-openide-actions-DeleteAction.shadow_hidden"/>
+            <file name="org-openide-actions-FindAction.shadow_hidden"/>
+            <file name="org-openide-actions-PasteAction.shadow_hidden"/>
+            <file name="org-openide-actions-ReplaceAction.shadow_hidden"/>
+            <file name="sep-before-reposearch.instance_hidden"/>
+        </folder>
+        
+        <folder name="View">
+            <!-- Hidden menu entries from other modules -->
+            <file name="Separator1.instance_hidden"/>
+            <file name="Separator2.instance_hidden"/>
+            <file name="org-netbeans-core-actions-HTMLViewAction.shadow_hidden"/>
+            <file name="org-netbeans-core-actions-LogAction.shadow_hidden"/>
+            <file name="org-netbeans-core-multiview-EditorsAction.instance_hidden"/>
             <file name="org-netbeans-core-windows-actions-ToolbarsListAction.instance_hidden"/>
+            <file name="org-netbeans-modules-editor-NbCodeFoldingAction.instance_hidden"/>
+            <file name="org-netbeans-modules-project-ui-SyncEditorWithViewsAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-versioning-ShowTextAnnotationsAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-versioning-diff-ShowDiffSidebarAction.shadow_hidden"/>
+            <file name="toggle-line-numbers.shadow_hidden"/>
+            <file name="toggle-non-printable-characters.shadow_hidden"/>
+            <file name="toggle-toolbar.shadow_hidden"/>
         </folder>
+        
+        <!-- Hidden menus -->
+        <folder name="GoTo_hidden"/>
+        <folder name="Source_hidden"/>
+        <folder name="Refactoring_hidden"/>
+        <folder name="BuildProject_hidden"/>
+        <folder name="RunProject_hidden"/>
+        <folder name="Versioning_hidden"/>
+        
+        <folder name="Tools">
+            <!-- Hidden menu entries from other modules -->
+            <file name="LibrariesCustomizerAction.shadow_hidden"/>
+            <file name="PaletteManager_hidden"/>
+            <file name="Separator1.instance_hidden"/>
+            <file name="Separator2.instance_hidden"/>
+            <file name="ServerManagerAction3.shadow_hidden"/>
+            <file name="VariablesCustomizerAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-autoupdate-ui-actions-PluginManagerAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-favorites-templates-TemplatesAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-options-OptionsWindowAction-separatorBefore.instance_hidden"/>
+            <file name="org-netbeans-modules-xml-catalog-CatalogAction.shadow_hidden"/>
+            <file name="org-openide-actions-ToolsAction.shadow_hidden"/>
+        </folder>
+        
         <folder name="Window">
             <file name="OutlineAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/Window/com-sun-hotspot-igv-coordinator-actions-OutlineAction.instance"/>
             </file>
+            
+            <!-- Hidden menu entries from other modules -->
+            <file name="Debug_hidden"/>
+            <file name="Navigator_hidden"/>
+            <file name="Other_hidden"/>
+            <file name="Output_hidden"/>
+            <file name="ProgressListAction.shadow_hidden"/>
+            <file name="ShowPaletteAction.shadow_hidden"/>
+            <file name="SwitchToRecentDocumentAction.shadow_hidden"/>
+            <file name="Versioning_hidden"/>
+            <file name="org-netbeans-core-ide-ServicesTabAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-favorites-View.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-logical-tab-action.shadow_hidden"/>
+            <file name="org-netbeans-modules-project-ui-physical-tab-action.shadow_hidden"/>
+            <file name="org-netbeans-modules-tasklist-ui-TaskListAction.shadow_hidden"/>
+            <file name="CloneDocumentAction.shadow_hidden"/>
+        </folder>
+
+        <folder name="Help">
+            <!-- Hidden menu entries from other modules -->
+            <file name="Separator1.instance_hidden"/>
+            <file name="netbeans-kb.url_hidden"/>
+            <file name="org-netbeans-modules-autoupdate-ui-actions-CheckForUpdatesAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-bugzilla-ReportNBIssueAction.shadow_hidden"/>
+            <file name="org-netbeans-modules-usersguide-master.xml_hidden"/>
+            <file name="shortcuts.xml_hidden"/>
         </folder>
     </folder>
-    <folder name="Toolbars">
-        <file name="Standard.xml" url="StandardConfiguration.xml"/>
+
+    <folder name="OptionsDialog">
+        <!-- Hidden option tabs from other modules -->
+        <file name="Editor.instance_hidden"/>
+        <file name="FontsAndColors.instance_hidden"/>
+        <file name="General.instance_hidden"/>
+        <file name="Keymaps.instance_hidden"/>
+        <folder name="Advanced">
+            <file name="Files.instance_hidden"/>
+            <file name="IssueTracking.instance_hidden"/>
+            <file name="JavaScript.instance_hidden"/>
+            <file name="Spellchecker.instance_hidden"/>
+            <file name="TermAdvancedOption.instance_hidden"/>
+            <file name="ToDo.instance_hidden"/>
+            <file name="Versioning.instance_hidden"/>
+        </folder>
     </folder>
+    
     <folder name="Windows2">
         <folder name="Components">
             <file name="OutlineTopComponent.settings" url="OutlineTopComponentSettings.xml"/>
         </folder>
-        <folder name="Modes">
+        <folder name="Modes">  
             <file name="customLeft.wsmode" url="customLeftWsmode.xml"/>
             <folder name="customLeft">
                 <file name="OutlineTopComponent.wstcref" url="OutlineTopComponentWstcref.xml"/>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/manifest.mf	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/manifest.mf	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.data
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/data/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.data
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/data/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,8 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
+src.dir=src
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
+test.src.dir=test
+build.test.classes.dir=${build.dir}/test/classes
+build.test.results.dir=${build.dir}/test/results
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -6,6 +6,19 @@
             <code-name-base>com.sun.hotspot.igv.data</code-name-base>
             <suite-component/>
             <module-dependencies/>
+            <test-dependencies>
+                <test-type>
+                    <name>unit</name>
+                    <test-dependency>
+                        <code-name-base>org.netbeans.libs.junit4</code-name-base>
+                        <compile-dependency/>
+                    </test-dependency>
+                    <test-dependency>
+                        <code-name-base>org.openide.util</code-name-base>
+                        <compile-dependency/>
+                    </test-dependency>
+                </test-type>
+            </test-dependencies>
             <public-packages>
                 <package>com.sun.hotspot.igv.data</package>
                 <package>com.sun.hotspot.igv.data.serialization</package>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEvent.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEvent.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,20 +24,22 @@
 package com.sun.hotspot.igv.data;
 
 /**
- *
+ * Class representing a generic changed event.
  * @author Thomas Wuerthinger
+ * @param <T>
  */
 public class ChangedEvent<T> extends Event<ChangedListener<T>> {
 
     private T object;
 
-    public ChangedEvent() {
-    }
-
+    /**
+     * Creates a new event with the specific object as the one for which the event gets fired.
+     */
     public ChangedEvent(T object) {
         this.object = object;
     }
 
+    @Override
     protected void fire(ChangedListener<T> l) {
         l.changed(object);
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEventProvider.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEventProvider.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,14 @@
 package com.sun.hotspot.igv.data;
 
 /**
- *
+ * Provides a changed event object.
  * @author Thomas Wuerthinger
+ * @param <T> Class for which the changed event fires.
  */
 public interface ChangedEventProvider<T> {
 
-    public ChangedEvent<T> getChangedEvent();
+    /**
+     * Returns the changed event object. Should always return the same instance.
+     */
+    ChangedEvent<T> getChangedEvent();
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedListener.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedListener.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,10 +24,15 @@
 package com.sun.hotspot.igv.data;
 
 /**
- *
+ * Listens to changed events.
  * @author Thomas Wuerthinger
+ * @param <T> Class for which the changed event fires.
  */
 public interface ChangedListener<T> {
 
-    public void changed(T source);
+    /**
+     * This method is called everytime a changed event is fired.
+     * @param source Object that has changed.
+     */
+    void changed(T source);
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ControllableChangedListener.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public abstract class ControllableChangedListener<T> implements ChangedListener<T>{
+
+    private boolean enabled;
+
+
+    public ControllableChangedListener() {
+        enabled = true;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+
+    public void setEnabled(boolean b) {
+        enabled = b;
+    }
+
+    @Override
+    public void changed(T source) {
+        if(enabled) {
+            filteredChanged(source);
+        }
+    }
+
+    public abstract void filteredChanged(T source);
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Event.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Event.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,23 +33,48 @@
 public abstract class Event<L> {
 
     private List<L> listener;
+    private boolean fireEvents;
+    private boolean eventWasFired;
 
     public Event() {
-        listener = new ArrayList<L>();
+        listener = new ArrayList<>();
+        fireEvents = true;
     }
 
     public void addListener(L l) {
         listener.add(l);
     }
 
-    public void removeListener(L l) {
+    /**
+     * Remove listener
+     * @param l
+     */
+    public void removeListener(final L l) {
         listener.remove(l);
     }
 
     public void fire() {
-        List<L> tmpList = new ArrayList<L>(listener);
-        for (L l : tmpList) {
-            fire(l);
+        if(fireEvents) {
+            List<L> tmpList = new ArrayList<>(listener);
+            for (L l : tmpList) {
+                fire(l);
+            }
+        } else {
+            eventWasFired = true;
+        }
+    }
+
+    public void beginAtomic() {
+        assert fireEvents : "endAtomic has to be called before another beginAtomic may be called";
+        this.fireEvents = false;
+        this.eventWasFired = false;
+    }
+
+    public void endAtomic() {
+        assert !fireEvents : "beginAtomic has to be called first";
+        this.fireEvents = true;
+        if(eventWasFired) {
+            fire();
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Folder.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+import java.util.List;
+
+public interface Folder {
+    List<? extends FolderElement> getElements();
+    void removeElement(FolderElement element);
+    void addElement(FolderElement group);
+    ChangedEvent<? extends Folder> getChangedEvent();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/FolderElement.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+public interface FolderElement {
+
+    Folder getParent();
+    String getName();
+    void setParent(Folder parent);
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,53 +24,36 @@
 package com.sun.hotspot.igv.data;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class GraphDocument extends Properties.Entity implements ChangedEventProvider<GraphDocument> {
+public class GraphDocument extends Properties.Entity implements ChangedEventProvider<GraphDocument>, Folder {
 
-    private List<Group> groups;
+    private List<FolderElement> elements;
     private ChangedEvent<GraphDocument> changedEvent;
 
     public GraphDocument() {
-        groups = new ArrayList<Group>();
-        changedEvent = new ChangedEvent<GraphDocument>(this);
+        elements = new ArrayList<>();
+        changedEvent = new ChangedEvent<>(this);
     }
 
     public void clear() {
-        groups.clear();
+        elements.clear();
         getChangedEvent().fire();
     }
 
+    @Override
     public ChangedEvent<GraphDocument> getChangedEvent() {
         return changedEvent;
     }
 
-    public List<Group> getGroups() {
-        return Collections.unmodifiableList(groups);
-    }
-
-    public void addGroup(Group group) {
-        group.setDocument(this);
-        groups.add(group);
-        getChangedEvent().fire();
-    }
-
-    public void removeGroup(Group group) {
-        if (groups.contains(group)) {
-            group.setDocument(null);
-            groups.remove(group);
-            getChangedEvent().fire();
-        }
-    }
-
     public void addGraphDocument(GraphDocument document) {
-        for (Group g : document.groups) {
-            this.addGroup(g);
+        for (FolderElement e : document.elements) {
+            e.setParent(this);
+            this.addElement(e);
         }
         document.clear();
         getChangedEvent().fire();
@@ -80,12 +63,30 @@
     public String toString() {
         StringBuilder sb = new StringBuilder();
 
-        sb.append("GraphDocument: " + getProperties().toString() + " \n\n");
-        for (Group g : getGroups()) {
+        sb.append("GraphDocument: ").append(getProperties().toString()).append(" \n\n");
+        for (FolderElement g : getElements()) {
             sb.append(g.toString());
             sb.append("\n\n");
         }
 
         return sb.toString();
     }
+
+    @Override
+    public List<? extends FolderElement> getElements() {
+        return elements;
+    }
+
+    @Override
+    public void removeElement(FolderElement element) {
+        if (elements.remove(element)) {
+            getChangedEvent().fire();
+        }
+    }
+
+    @Override
+    public void addElement(FolderElement element) {
+        elements.add(element);
+        getChangedEvent().fire();
+    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,49 +23,36 @@
  */
 package com.sun.hotspot.igv.data;
 
-import com.sun.hotspot.igv.data.ChangedEvent;
-import com.sun.hotspot.igv.data.ChangedEventProvider;
-import com.sun.hotspot.igv.data.Properties;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class Group extends Properties.Entity implements ChangedEventProvider<Group> {
+public class Group extends Properties.Entity implements ChangedEventProvider<Group>, Folder, FolderElement {
 
-    private List<InputGraph> graphs;
+    private final List<FolderElement> elements;
+    private final List<InputGraph> graphs;
+
+    private InputMethod method;
     private transient ChangedEvent<Group> changedEvent;
-    private GraphDocument document;
-    private InputMethod method;
-    private String assembly;
+    private Folder parent;
 
-    public Group() {
-        graphs = new ArrayList<InputGraph>();
-        init();
-    }
+    public Group(Folder parent) {
+        elements = new ArrayList<>();
+        graphs = new ArrayList<>();
+        changedEvent = new ChangedEvent<>(this);
+        this.parent = parent;
 
-    private void init() {
-        changedEvent = new ChangedEvent<Group>(this);
+        // Ensure that name and type are never null
+        getProperties().setProperty("name", "");
+        getProperties().setProperty("type", "");
     }
 
     public void fireChangedEvent() {
         changedEvent.fire();
     }
 
-    public void setAssembly(String s) {
-        this.assembly = s;
-    }
-
-    public String getAssembly() {
-        return assembly;
-    }
-
     public void setMethod(InputMethod method) {
         this.method = method;
     }
@@ -74,68 +61,120 @@
         return method;
     }
 
-    void setDocument(GraphDocument document) {
-        this.document = document;
-    }
-
-    public GraphDocument getDocument() {
-        return document;
-    }
-
+    @Override
     public ChangedEvent<Group> getChangedEvent() {
         return changedEvent;
     }
 
-    public List<InputGraph> getGraphs() {
-        return Collections.unmodifiableList(graphs);
+    @Override
+    public List<FolderElement> getElements() {
+        return Collections.unmodifiableList(elements);
+    }
+
+    public int getGraphsCount() {
+        return elements.size();
     }
 
-    public void addGraph(InputGraph g) {
-        assert g != null;
-        assert !graphs.contains(g);
-        graphs.add(g);
+    @Override
+    public void addElement(FolderElement element) {
+        elements.add(element);
+        if (element instanceof InputGraph) {
+            graphs.add((InputGraph) element);
+        } else {
+
+        }
+        element.setParent(this);
         changedEvent.fire();
     }
 
-    public void removeGraph(InputGraph g) {
-        int index = graphs.indexOf(g);
-        if (index != -1) {
-            graphs.remove(g);
-            changedEvent.fire();
-        }
-    }
-
     public Set<Integer> getAllNodes() {
-        Set<Integer> result = new HashSet<Integer>();
-        for (InputGraph g : graphs) {
-            Set<Integer> ids = g.getNodesAsSet();
-            result.addAll(g.getNodesAsSet());
-            for (Integer i : ids) {
-                result.add(-i);
+        Set<Integer> result = new HashSet<>();
+        for (FolderElement e : elements) {
+            if (e instanceof InputGraph) {
+                InputGraph g = (InputGraph) e;
+                result.addAll(g.getNodesAsSet());
             }
         }
         return result;
     }
 
-    public InputGraph getLastAdded() {
-        if (graphs.size() == 0) {
-            return null;
-        }
-        return graphs.get(graphs.size() - 1);
-    }
-
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append("Group " + getProperties().toString() + "\n");
-        for (InputGraph g : graphs) {
+        sb.append("Group ").append(getProperties()).append("\n");
+        for (FolderElement g : elements) {
             sb.append(g.toString());
-            sb.append("\n");
+            sb.append('\n');
         }
         return sb.toString();
     }
 
+    @Override
     public String getName() {
         return getProperties().get("name");
     }
+
+    public String getType() {
+        return getProperties().get("type");
+
+    }
+
+    InputGraph getPrev(InputGraph graph) {
+        InputGraph lastGraph = null;
+        for (FolderElement e : elements) {
+            if (e == graph) {
+                return lastGraph;
+            }
+            if (e instanceof InputGraph) {
+                lastGraph = (InputGraph) e;
+            }
+        }
+        return null;
+    }
+
+    InputGraph getNext(InputGraph graph) {
+        boolean found = false;
+        for (FolderElement e : elements) {
+            if (e == graph) {
+                found = true;
+            } else if (found && e instanceof InputGraph) {
+                return (InputGraph) e;
+            }
+        }
+        return null;
+    }
+
+    public InputGraph getLastGraph() {
+        InputGraph lastGraph = null;
+        for (FolderElement e : elements) {
+            if (e instanceof InputGraph) {
+                lastGraph = (InputGraph) e;
+            }
+        }
+        return lastGraph;
+    }
+
+    @Override
+    public Folder getParent() {
+         return parent;
+    }
+
+    @Override
+    public void removeElement(FolderElement element) {
+        if (elements.remove(element)) {
+            if (element instanceof InputGraph) {
+                graphs.remove((InputGraph) element);
+            }
+            changedEvent.fire();
+        }
+    }
+
+    public List<InputGraph> getGraphs() {
+        return graphs;
+    }
+
+    @Override
+    public void setParent(Folder parent) {
+        this.parent = parent;
+    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,12 +23,7 @@
  */
 package com.sun.hotspot.igv.data;
 
-import java.awt.Rectangle;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  *
@@ -37,104 +32,81 @@
 public class InputBlock {
 
     private List<InputNode> nodes;
-    private List<String> successorNames;
     private String name;
     private InputGraph graph;
-    private Rectangle bounds;
     private Set<InputBlock> successors;
-    private Set<InputBlock> predecessors;
-    private Set<InputBlockEdge> inputs;
-    private Set<InputBlockEdge> outputs;
+
+    @Override
+    public int hashCode() {
+        return name.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+
+        if (o == this) {
+            return true;
+        }
+
+        if (o == null || (!(o instanceof InputBlock))) {
+            return false;
+        }
 
-    public InputBlock(InputGraph graph, String name) {
+        final InputBlock b = (InputBlock)o;
+        final boolean result = b.nodes.equals(nodes) && b.name.equals(name) && b.successors.size() == successors.size();
+        if (!result) {
+            return false;
+        }
+
+        final HashSet<String> s = new HashSet<>();
+        for (InputBlock succ : successors) {
+            s.add(succ.name);
+        }
+
+        for (InputBlock succ : b.successors) {
+            if (!s.contains(succ.name)) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    InputBlock(InputGraph graph, String name) {
         this.graph = graph;
         this.name = name;
-        nodes = new ArrayList<InputNode>();
-        successorNames = new ArrayList<String>();
-        successors = new HashSet<InputBlock>();
-        predecessors = new HashSet<InputBlock>();
-        inputs = new HashSet<InputBlockEdge>();
-        outputs = new HashSet<InputBlockEdge>();
-    }
-
-    public void removeSuccessor(InputBlock b) {
-        if (successors.contains(b)) {
-            successors.remove(b);
-            b.predecessors.remove(this);
-            InputBlockEdge e = new InputBlockEdge(this, b);
-            assert outputs.contains(e);
-            outputs.remove(e);
-            assert b.inputs.contains(e);
-            b.inputs.remove(e);
-        }
+        nodes = new ArrayList<>();
+        successors = new LinkedHashSet<>(2);
     }
 
     public String getName() {
         return name;
     }
 
-    public void setName(String s) {
-        name = s;
-    }
-
     public List<InputNode> getNodes() {
         return Collections.unmodifiableList(nodes);
     }
 
     public void addNode(int id) {
-        InputNode n = graph.getNode(id);
-        assert n != null;
-        graph.setBlock(n, this);
-        addNode(graph.getNode(id));
-    }
-
-    public void addNode(InputNode node) {
-        assert !nodes.contains(node);
+        InputNode node = graph.getNode(id);
+        assert node != null;
+        assert !nodes.contains(node) : "duplicate : " + node;
+        graph.setBlock(node, this);
         nodes.add(node);
     }
 
-    public Set<InputBlock> getPredecessors() {
-        return Collections.unmodifiableSet(predecessors);
-    }
-
     public Set<InputBlock> getSuccessors() {
         return Collections.unmodifiableSet(successors);
     }
 
-    public Set<InputBlockEdge> getInputs() {
-        return Collections.unmodifiableSet(inputs);
-    }
-
-    public Set<InputBlockEdge> getOutputs() {
-        return Collections.unmodifiableSet(outputs);
-    }
-
-    // resolveBlockLinks must be called afterwards
-    public void addSuccessor(String name) {
-        successorNames.add(name);
+    @Override
+    public String toString() {
+        return "Block " + this.getName();
     }
 
-    public void resolveBlockLinks() {
-        for (String s : successorNames) {
-            InputBlock b = graph.getBlock(s);
-            addSuccessor(b);
-        }
-
-        successorNames.clear();
-    }
-
-    public void addSuccessor(InputBlock b) {
+    void addSuccessor(InputBlock b) {
         if (!successors.contains(b)) {
             successors.add(b);
-            b.predecessors.add(this);
-            InputBlockEdge e = new InputBlockEdge(this, b);
-            outputs.add(e);
-            b.inputs.add(e);
         }
     }
-
-    @Override
-    public String toString() {
-        return this.getName();
-    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlockEdge.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlockEdge.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,8 +29,15 @@
  */
 public class InputBlockEdge {
 
+    public enum State {
+        SAME,
+        NEW,
+        DELETED
+    }
+
     private InputBlock from;
     private InputBlock to;
+    private State state = State.SAME;
 
     public InputBlockEdge(InputBlock from, InputBlock to) {
         assert from != null;
@@ -47,13 +54,21 @@
         return to;
     }
 
+    public State getState() {
+        return state;
+    }
+
+    public void setState(State state) {
+        this.state = state;
+    }
+
     @Override
     public boolean equals(Object obj) {
-        if (obj instanceof InputBlockEdge && obj != null) {
+        if (obj != null && obj instanceof InputBlockEdge) {
             InputBlockEdge e = (InputBlockEdge) obj;
             return e.from.equals(from) && e.to.equals(to);
         }
-        return super.equals(obj);
+        return false;
     }
 
     @Override
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBytecode.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBytecode.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,11 +31,15 @@
 
     private int bci;
     private String name;
+    private String operands;
+    private String comment;
     private InputMethod inlined;
 
-    public InputBytecode(int bci, String name) {
+    public InputBytecode(int bci, String name, String operands, String comment) {
         this.bci = bci;
         this.name = name;
+        this.operands = operands;
+        this.comment = comment;
     }
 
     public InputMethod getInlined() {
@@ -53,4 +57,12 @@
     public String getName() {
         return name;
     }
+
+    public String getOperands() {
+        return operands;
+    }
+
+    public String getComment() {
+        return comment;
+    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,10 @@
  */
 package com.sun.hotspot.igv.data;
 
+import java.util.Comparator;
+import java.util.WeakHashMap;
+import java.lang.ref.WeakReference;
+
 /**
  *
  * @author Thomas Wuerthinger
@@ -30,21 +34,83 @@
 public class InputEdge {
 
     public enum State {
-
+        IMMUTABLE,
         SAME,
         NEW,
         DELETED
     }
-    private char toIndex;
-    private int from;
-    private int to;
+
+    public static final Comparator<InputEdge> OUTGOING_COMPARATOR = new Comparator<InputEdge>(){
+
+        @Override
+            public int compare(InputEdge o1, InputEdge o2) {
+                if(o1.getFromIndex() == o2.getFromIndex()) {
+                    return o1.getTo() - o2.getTo();
+                }
+                return o1.getFromIndex() - o2.getFromIndex();
+            }
+    };
+
+    public static final Comparator<InputEdge> INGOING_COMPARATOR = new Comparator<InputEdge>(){
+
+        @Override
+            public int compare(InputEdge o1, InputEdge o2) {
+                if(o1.getToIndex() == o2.getToIndex()) {
+                    return o1.getFrom() - o2.getFrom();
+                }
+                return o1.getToIndex() - o2.getToIndex();
+            }
+    };
+
+    private final char toIndex;
+    private final char fromIndex;
+    private final int from;
+    private final int to;
+    private final String label;
+    private final String type;
     private State state;
 
     public InputEdge(char toIndex, int from, int to) {
+        this((char) 0, toIndex, from, to, null, null);
+    }
+
+    public InputEdge(char fromIndex, char toIndex, int from, int to) {
+        this(fromIndex, toIndex, from, to, null, null);
+    }
+
+    public InputEdge(char fromIndex, char toIndex, int from, int to, String label, String type) {
         this.toIndex = toIndex;
+        this.fromIndex = fromIndex;
         this.from = from;
         this.to = to;
         this.state = State.SAME;
+        this.label = label;
+        this.type = type.intern();
+    }
+
+    static WeakHashMap<InputEdge, WeakReference<InputEdge>> immutableCache = new WeakHashMap<>();
+
+    public static synchronized InputEdge createImmutable(char fromIndex, char toIndex, int from, int to, String label, String type) {
+        InputEdge edge = new InputEdge(fromIndex, toIndex, from, to, label, type, State.IMMUTABLE);
+        WeakReference<InputEdge> result = immutableCache.get(edge);
+        if (result != null) {
+            InputEdge edge2 = result.get();
+            if (edge2 != null) {
+                return edge2;
+            }
+        }
+        immutableCache.put(edge, new WeakReference<>(edge));
+        return edge;
+    }
+
+    public InputEdge(char fromIndex, char toIndex, int from, int to, String label, String type, State state) {
+        this.toIndex = toIndex;
+        this.fromIndex = fromIndex;
+        this.from = from;
+        this.to = to;
+        this.state = state;
+        this.label = label;
+        this.type = type;
     }
 
     public State getState() {
@@ -52,6 +118,9 @@
     }
 
     public void setState(State x) {
+        if (state == State.IMMUTABLE) {
+            throw new InternalError("Can't change immutable instances");
+        }
         this.state = x;
     }
 
@@ -59,6 +128,10 @@
         return toIndex;
     }
 
+    public char getFromIndex() {
+        return fromIndex;
+    }
+
     public String getName() {
         return "in" + toIndex;
     }
@@ -71,22 +144,35 @@
         return to;
     }
 
+    public String getLabel() {
+        return label;
+    }
+
+    public String getType() {
+        return type;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (o == null || !(o instanceof InputEdge)) {
             return false;
         }
         InputEdge conn2 = (InputEdge) o;
-        return conn2.toIndex == toIndex && conn2.from == from && conn2.to == to;
+        boolean result = conn2.fromIndex == fromIndex && conn2.toIndex == toIndex && conn2.from == from && conn2.to == to;
+        if (result && (state == State.IMMUTABLE || conn2.state == State.IMMUTABLE)) {
+            // Immutable instances must be exactly the same
+            return conn2.label == label && conn2.state == state;
+        }
+        return result;
     }
 
     @Override
     public String toString() {
-        return "Edge from " + from + " to " + to + "(" + (int) toIndex + ") ";
+        return "Edge from " + from + " to " + to + "(" + (int) fromIndex + ", " + (int) toIndex + ") ";
     }
 
     @Override
     public int hashCode() {
-        return (from << 20 | to << 8 | toIndex);
+        return (from << 20 | to << 8 | toIndex << 4 | fromIndex);
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,65 +23,141 @@
  */
 package com.sun.hotspot.igv.data;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Set;
+import java.util.*;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class InputGraph extends Properties.Entity {
+public class InputGraph extends Properties.Entity implements FolderElement {
+
+    private Map<Integer, InputNode> nodes;
+    private List<InputEdge> edges;
+    private Folder parent;
+    private Group parentGroup;
+    private Map<String, InputBlock> blocks;
+    private List<InputBlockEdge> blockEdges;
+    private Map<Integer, InputBlock> nodeToBlock;
+
+    public InputGraph(String name) {
+        setName(name);
+        nodes = new LinkedHashMap<>();
+        edges = new ArrayList<>();
+        blocks = new LinkedHashMap<>();
+        blockEdges = new ArrayList<>();
+        nodeToBlock = new LinkedHashMap<>();
+    }
 
-    private HashMap<Integer, InputNode> nodes;
-    private ArrayList<InputEdge> edges;
-    private Group parent;
-    private HashMap<String, InputBlock> blocks;
-    private HashMap<Integer, InputBlock> nodeToBlock;
-    private boolean isDifferenceGraph;
+    @Override
+    public void setParent(Folder parent) {
+        this.parent = parent;
+        if (parent instanceof Group) {
+            assert this.parentGroup == null;
+            this.parentGroup = (Group) parent;
+        }
+    }
 
-    public InputGraph(Group parent) {
-        this(parent, null);
+    public InputBlockEdge addBlockEdge(InputBlock left, InputBlock right) {
+        InputBlockEdge edge = new InputBlockEdge(left, right);
+        blockEdges.add(edge);
+        left.addSuccessor(right);
+        return edge;
+    }
+
+    public List<InputNode> findRootNodes() {
+        List<InputNode> result = new ArrayList<>();
+        Set<Integer> nonRoot = new HashSet<>();
+        for(InputEdge curEdges : getEdges()) {
+            nonRoot.add(curEdges.getTo());
+        }
+
+        for(InputNode node : getNodes()) {
+            if(!nonRoot.contains(node.getId())) {
+                result.add(node);
+            }
+        }
+
+        return result;
     }
 
-    public InputGraph(Group parent, InputGraph last) {
-        this(parent, last, "");
+    public Map<InputNode, List<InputEdge>> findAllOutgoingEdges() {
+        Map<InputNode, List<InputEdge>> result = new HashMap<>(getNodes().size());
+        for(InputNode n : this.getNodes()) {
+            result.put(n, new ArrayList<InputEdge>());
+        }
+
+        for(InputEdge e : this.edges) {
+            int from = e.getFrom();
+            InputNode fromNode = this.getNode(from);
+            List<InputEdge> fromList = result.get(fromNode);
+            assert fromList != null;
+            fromList.add(e);
+        }
+
+        for(InputNode n : this.getNodes()) {
+            List<InputEdge> list = result.get(n);
+            Collections.sort(list, InputEdge.OUTGOING_COMPARATOR);
+        }
+
+        return result;
     }
 
-    private void clearBlocks() {
+    public Map<InputNode, List<InputEdge>> findAllIngoingEdges() {
+        Map<InputNode, List<InputEdge>> result = new HashMap<>(getNodes().size());
+        for(InputNode n : this.getNodes()) {
+            result.put(n, new ArrayList<InputEdge>());
+        }
+
+        for(InputEdge e : this.edges) {
+            int to = e.getTo();
+            InputNode toNode = this.getNode(to);
+            List<InputEdge> toList = result.get(toNode);
+            assert toList != null;
+            toList.add(e);
+        }
+
+        for(InputNode n : this.getNodes()) {
+            List<InputEdge> list = result.get(n);
+            Collections.sort(list, InputEdge.INGOING_COMPARATOR);
+        }
+
+        return result;
+    }
+
+    public List<InputEdge> findOutgoingEdges(InputNode n) {
+        List<InputEdge> result = new ArrayList<>();
+
+        for(InputEdge e : this.edges) {
+            if(e.getFrom() == n.getId()) {
+                result.add(e);
+            }
+        }
+
+        Collections.sort(result, InputEdge.OUTGOING_COMPARATOR);
+
+        return result;
+    }
+
+    public void clearBlocks() {
         blocks.clear();
         nodeToBlock.clear();
     }
 
-    public InputGraph(Group parent, InputGraph last, String name) {
-        this.parent = parent;
-        setName(name);
-        nodes = new HashMap<Integer, InputNode>();
-        edges = new ArrayList<InputEdge>();
-        blocks = new HashMap<String, InputBlock>();
-        nodeToBlock = new HashMap<Integer, InputBlock>();
-        if (last != null) {
+    public void setEdge(int fromIndex, int toIndex, int from, int to) {
+        assert fromIndex == ((char)fromIndex) : "Downcast must be safe";
+        assert toIndex == ((char)toIndex) : "Downcast must be safe";
 
-            for (InputNode n : last.getNodes()) {
-                addNode(n);
-            }
-
-            for (InputEdge c : last.getEdges()) {
-                addEdge(c);
-            }
+        InputEdge edge = new InputEdge((char)fromIndex, (char)toIndex, from, to);
+        if(!this.getEdges().contains(edge)) {
+            this.addEdge(edge);
         }
     }
 
-    public void schedule(Collection<InputBlock> newBlocks) {
-        clearBlocks();
-        InputBlock noBlock = new InputBlock(this, "no block");
-        Set<InputNode> scheduledNodes = new HashSet<InputNode>();
+    public void ensureNodesInBlocks() {
+        InputBlock noBlock = null;
+        Set<InputNode> scheduledNodes = new HashSet<>();
 
-        for (InputBlock b : newBlocks) {
+        for (InputBlock b : getBlocks()) {
             for (InputNode n : b.getNodes()) {
                 assert !scheduledNodes.contains(n);
                 scheduledNodes.add(n);
@@ -91,18 +167,11 @@
         for (InputNode n : this.getNodes()) {
             assert nodes.get(n.getId()) == n;
             if (!scheduledNodes.contains(n)) {
+                if (noBlock == null) {
+                    noBlock = this.addBlock("(no block)");
+                }
                 noBlock.addNode(n.getId());
             }
-        }
-
-        if (noBlock.getNodes().size() != 0) {
-            newBlocks.add(noBlock);
-        }
-        for (InputBlock b : newBlocks) {
-            addBlock(b);
-        }
-
-        for (InputNode n : this.getNodes()) {
             assert this.getBlock(n) != null;
         }
     }
@@ -116,45 +185,26 @@
     }
 
     public InputBlock getBlock(InputNode node) {
+        assert nodes.containsKey(node.getId());
+        assert nodes.get(node.getId()).equals(node);
         return getBlock(node.getId());
     }
 
     public InputGraph getNext() {
-        List<InputGraph> list = parent.getGraphs();
-        if (!list.contains(this)) {
-            return null;
-        }
-        int index = list.indexOf(this);
-        if (index == list.size() - 1) {
-            return null;
-        } else {
-            return list.get(index + 1);
-        }
+        return parentGroup.getNext(this);
     }
 
     public InputGraph getPrev() {
-        List<InputGraph> list = parent.getGraphs();
-        if (!list.contains(this)) {
-            return null;
-        }
-        int index = list.indexOf(this);
-        if (index == 0) {
-            return null;
-        } else {
-            return list.get(index - 1);
-        }
+        return parentGroup.getPrev(this);
     }
 
-    public String getName() {
-        return getProperties().get("name");
+    private void setName(String name) {
+        this.getProperties().setProperty("name", name);
     }
 
-    public String getAbsoluteName() {
-        String result = getName();
-        if (this.parent != null) {
-            result = parent.getName() + ": " + result;
-        }
-        return result;
+    @Override
+    public String getName() {
+        return getProperties().get("name");
     }
 
     public Collection<InputNode> getNodes() {
@@ -186,25 +236,22 @@
     }
 
     public void removeEdge(InputEdge c) {
-        assert edges.contains(c);
-        edges.remove(c);
-        assert !edges.contains(c);
+        boolean removed = edges.remove(c);
+        assert removed;
     }
 
     public void addEdge(InputEdge c) {
-        assert !edges.contains(c);
         edges.add(c);
-        assert edges.contains(c);
     }
 
     public Group getGroup() {
-        return parent;
+        return parentGroup;
     }
 
     @Override
     public String toString() {
         StringBuilder sb = new StringBuilder();
-        sb.append("Graph " + getName() + " " + getProperties().toString() + "\n");
+        sb.append("Graph ").append(getName()).append(" ").append(getProperties().toString()).append("\n");
         for (InputNode n : nodes.values()) {
             sb.append(n.toString());
             sb.append("\n");
@@ -214,35 +261,31 @@
             sb.append(c.toString());
             sb.append("\n");
         }
+
+        for (InputBlock b : getBlocks()) {
+            sb.append(b.toString());
+            sb.append("\n");
+        }
+
         return sb.toString();
     }
 
-    public void addBlock(InputBlock b) {
+    public InputBlock addBlock(String name) {
+        final InputBlock b = new InputBlock(this, name);
         blocks.put(b.getName(), b);
-        for (InputNode n : b.getNodes()) {
-            this.nodeToBlock.put(n.getId(), b);
-        }
-    }
-
-    public void resolveBlockLinks() {
-        for (InputBlock b : blocks.values()) {
-            b.resolveBlockLinks();
-        }
-    }
-
-    public void setName(String s) {
-        getProperties().setProperty("name", s);
+        return b;
     }
 
     public InputBlock getBlock(String s) {
         return blocks.get(s);
     }
 
-    public boolean isDifferenceGraph() {
-        return this.isDifferenceGraph;
+    public Collection<InputBlockEdge> getBlockEdges() {
+        return Collections.unmodifiableList(blockEdges);
     }
 
-    public void setIsDifferenceGraph(boolean b) {
-        isDifferenceGraph = b;
+    @Override
+    public Folder getParent() {
+        return parent;
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,10 +23,11 @@
  */
 package com.sun.hotspot.igv.data;
 
-import com.sun.hotspot.igv.data.Properties;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  *
@@ -42,14 +43,37 @@
     private Group group;
     private List<InputBytecode> bytecodes;
 
+    @Override
+    public int hashCode() {
+        int result = name.hashCode();
+        result = result * 31 + bci;
+        result = result * 31 + shortName.hashCode();
+        result = result * 31 + inlined.hashCode();
+        result = result * 31 + bytecodes.hashCode();
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || (!(o instanceof InputMethod))) {
+            return false;
+        }
+
+        final InputMethod im = (InputMethod)o;
+        return name.equals(im.name) && bci == im.bci && shortName.equals(im.shortName) &&
+               inlined.equals(im.inlined) && bytecodes.equals(im.bytecodes);
+    }
+
+
+
     /** Creates a new instance of InputMethod */
     public InputMethod(Group parent, String name, String shortName, int bci) {
         this.group = parent;
         this.name = name;
         this.bci = bci;
         this.shortName = shortName;
-        inlined = new ArrayList<InputMethod>();
-        bytecodes = new ArrayList<InputBytecode>();
+        inlined = new ArrayList<>();
+        bytecodes = new ArrayList<>();
     }
 
     public List<InputBytecode> getBytecodes() {
@@ -87,31 +111,42 @@
     }
 
     public void setBytecodes(String text) {
-
+        Pattern instruction = Pattern.compile("\\s*(\\d+)\\s*:?\\s*(\\w+)\\s*(.*)(?://(.*))?");
         String[] strings = text.split("\n");
-        int oldNumber = -1;
+        int oldBci = -1;
         for (String s : strings) {
-
-            if (s.length() > 0 && Character.isDigit(s.charAt(0))) {
-                s = s.trim();
-                int spaceIndex = s.indexOf(' ');
-                String numberString = s.substring(0, spaceIndex);
-                String tmpName = s.substring(spaceIndex + 1, s.length());
+            if (s.startsWith(" ")) {
+                // indented lines are extra textual information
+                continue;
+            }
+            s = s.trim();
+            if (s.length() != 0) {
+                final Matcher matcher = instruction.matcher(s);
+                if (matcher.matches()) {
+                    String bciString = matcher.group(1);
+                    String opcode = matcher.group(2);
+                    String operands = matcher.group(3).trim();
+                    String comment = matcher.group(4);
+                    if (comment != null) {
+                        comment = comment.trim();
+                    }
 
-                int number = -1;
-                number = Integer.parseInt(numberString);
+                    int bci = Integer.parseInt(bciString);
 
-                // assert correct order of bytecodes
-                assert number > oldNumber;
+                    // assert correct order of bytecodes
+                    assert bci > oldBci;
+
+                    InputBytecode bc = new InputBytecode(bci, opcode, operands, comment);
+                    bytecodes.add(bc);
 
-                InputBytecode bc = new InputBytecode(number, tmpName);
-                bytecodes.add(bc);
-
-                for (InputMethod m : inlined) {
-                    if (m.getBci() == number) {
-                        bc.setInlined(m);
-                        break;
+                    for (InputMethod m : inlined) {
+                        if (m.getBci() == bci) {
+                            bc.setInlined(m);
+                            break;
+                        }
                     }
+                } else {
+                    System.out.println("no match: " + s);
                 }
             }
         }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,10 @@
  */
 package com.sun.hotspot.igv.data;
 
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
 /**
  *
  * @author Thomas Wuerthinger
@@ -30,6 +34,37 @@
 public class InputNode extends Properties.Entity {
 
     private int id;
+    private List<InputGraph> subgraphs;
+
+    public static final Comparator<InputNode> COMPARATOR = new Comparator<InputNode>() {
+        @Override
+        public int compare(InputNode o1, InputNode o2) {
+            return o1.getId() - o2.getId();
+        }
+    };
+
+    public static Comparator<InputNode> getPropertyComparator(final String propertyName) {
+        return new Comparator<InputNode>() {
+
+            @Override
+            public int compare(InputNode o1, InputNode o2) {
+
+                int i1 = 0;
+                try {
+                    i1 = Integer.parseInt(o1.getProperties().get(propertyName));
+                } catch(NumberFormatException e) {
+                }
+
+                int i2 = 0;
+                try {
+                    i2 = Integer.parseInt(o2.getProperties().get(propertyName));
+                } catch(NumberFormatException e) {
+                }
+
+                return i1 - i2;
+            }
+        };
+    }
 
     public InputNode(InputNode n) {
         super(n);
@@ -49,21 +84,29 @@
         return id;
     }
 
+    public void addSubgraph(InputGraph graph) {
+        if (subgraphs == null) {
+            subgraphs = new ArrayList<>();
+        }
+        subgraphs.add(graph);
+    }
+
+    public List<InputGraph> getSubgraphs() {
+        return subgraphs;
+    }
+
     @Override
     public boolean equals(Object o) {
         if (!(o instanceof InputNode)) {
             return false;
         }
         InputNode n = (InputNode) o;
-        if (n.id != id) {
-            return false;
-        }
-        return getProperties().equals(n.getProperties());
+        return n.id == id;
     }
 
     @Override
     public int hashCode() {
-        return id;
+        return id * 13;
     }
 
     @Override
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Pair.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Pair.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,15 +58,30 @@
 
     @Override
     public boolean equals(Object o) {
-        if (!(o instanceof Pair)) {
+        if (o == null || !(o instanceof Pair)) {
             return false;
         }
-        Pair obj = (Pair) o;
-        return l.equals(obj.l) && r.equals(obj.r);
+        Pair<?,?> obj = (Pair<?,?>) o;
+        boolean b1 = (l == obj.l);
+        if (l != null) {
+            b1 = l.equals(obj.l);
+        }
+
+        boolean b2 = (r == obj.r);
+        if (r != null) {
+            b2 = r.equals(obj.r);
+        }
+
+        return b1 && b2;
     }
 
     @Override
     public int hashCode() {
-        return l.hashCode() * 71 + r.hashCode();
+        return ((l == null) ? 0 : l.hashCode()) * 71 + ((r == null) ? 0 : r.hashCode());
+    }
+
+    @Override
+    public String toString() {
+        return "[" + l + "/" + r + "]";
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,13 +24,10 @@
 package com.sun.hotspot.igv.data;
 
 import java.io.Serializable;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
+import java.util.*;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
-
+import java.util.regex.PatternSyntaxException;
 
 /**
  *
@@ -58,13 +55,30 @@
                 return false;
             }
         }
+
+        for (Property prop : p) {
+            String value = this.get(prop.getName());
+            if (value == null || !value.equals(prop.getValue())) {
+                return false;
+            }
+        }
+
         return true;
     }
 
     @Override
     public int hashCode() {
         int hash = 5;
-        hash = 83 * hash + (this.map != null ? this.map.hashCode() : 0);
+
+        if (map != null) {
+            for (int i = 0; i < this.map.length; i++) {
+                if (map[i] == null) {
+                    i++;
+                } else {
+                    hash = hash * 83 + map[i].hashCode();
+                }
+            }
+        }
         return hash;
     }
 
@@ -85,7 +99,7 @@
 
     public Properties(Properties p) {
         map = new String[p.map.length];
-        System.arraycopy(map, 0, p.map, 0, p.map.length);
+        System.arraycopy(p.map, 0, map, 0, p.map.length);
     }
 
     public static class Entity implements Provider {
@@ -100,19 +114,12 @@
             properties = new Properties(object.getProperties());
         }
 
+        @Override
         public Properties getProperties() {
             return properties;
         }
     }
 
-    private String getProperty(String key) {
-        for (int i = 0; i < map.length; i += 2)
-            if (map[i] != null && map[i].equals(key)) {
-                return map[i + 1];
-            }
-        return null;
-    }
-
     public interface PropertyMatcher {
 
         String getName();
@@ -128,11 +135,16 @@
             this.matcher = matcher;
         }
 
+        @Override
         public String getName() {
             return matcher.getName();
         }
 
+        @Override
         public boolean match(String p) {
+            if (p == null) {
+                return false;
+            }
             return !matcher.match(p);
         }
     }
@@ -143,15 +155,26 @@
         private String value;
 
         public StringPropertyMatcher(String name, String value) {
+            if (name == null) {
+                throw new IllegalArgumentException("Property name must not be null!");
+            }
+            if (value == null) {
+                throw new IllegalArgumentException("Property value must not be null!");
+            }
             this.name = name;
             this.value = value;
         }
 
+        @Override
         public String getName() {
             return name;
         }
 
+        @Override
         public boolean match(String p) {
+            if (p == null) {
+                throw new IllegalArgumentException("Property value must not be null!");
+            }
             return p.equals(value);
         }
     }
@@ -162,30 +185,55 @@
         private Pattern valuePattern;
 
         public RegexpPropertyMatcher(String name, String value) {
-            this.name = name;
-            valuePattern = Pattern.compile(value);
+            this(name, value, 0);
         }
 
+        public RegexpPropertyMatcher(String name, String value, int flags) {
+
+            if (name == null) {
+                throw new IllegalArgumentException("Property name must not be null!");
+            }
+
+            if (value == null) {
+                throw new IllegalArgumentException("Property value pattern must not be null!");
+            }
+
+            this.name = name;
+
+            try {
+                valuePattern = Pattern.compile(value, flags);
+            } catch (PatternSyntaxException e) {
+                throw new IllegalArgumentException("Bad pattern: " + value);
+            }
+        }
+
+        @Override
         public String getName() {
             return name;
         }
 
+        @Override
         public boolean match(String p) {
+            if (p == null) {
+                throw new IllegalArgumentException("Property value must not be null!");
+            }
             Matcher m = valuePattern.matcher(p);
             return m.matches();
         }
     }
 
     public Property selectSingle(PropertyMatcher matcher) {
+
+        final String name = matcher.getName();
         String value = null;
         for (int i = 0; i < map.length; i += 2) {
-            if (map[i] != null && matcher.getName().equals(map[i]))  {
+            if (map[i] != null && name.equals(map[i])) {
                 value = map[i + 1];
                 break;
             }
         }
         if (value != null && matcher.match(value)) {
-            return new Property(matcher.getName(), value);
+            return new Property(name, value);
         } else {
             return null;
         }
@@ -198,13 +246,32 @@
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("[");
+        List<String[]> pairs = new ArrayList<>();
         for (int i = 0; i < map.length; i += 2) {
             if (map[i + 1] != null) {
-                String p = map[i + 1];
-                sb.append(map[i] + " = " + map[i + 1] + "; ");
+                pairs.add(new String[]{map[i], map[i + 1]});
+            }
+        }
+
+        Collections.sort(pairs, new Comparator<String[]>() {
+            @Override
+            public int compare(String[] o1, String[] o2) {
+                assert o1.length == 2;
+                assert o2.length == 2;
+                return o1[0].compareTo(o2[0]);
             }
+        });
+
+        StringBuilder sb = new StringBuilder();
+        sb.append("[");
+        boolean first = true;
+        for (String[] p : pairs) {
+            if (first) {
+                first = false;
+            } else {
+                sb.append(", ");
+            }
+            sb.append(p[0]).append("=").append(p[1]);
         }
         return sb.append("]").toString();
     }
@@ -217,10 +284,6 @@
             this.objects = objects;
         }
 
-        public T selectSingle(final String name, final String value) {
-            return selectSingle(new StringPropertyMatcher(name, value));
-        }
-
         public T selectSingle(PropertyMatcher matcher) {
 
             for (T t : objects) {
@@ -233,18 +296,16 @@
             return null;
         }
 
-        public List<T> selectMultiple(final String name, final String value) {
-            return selectMultiple(new StringPropertyMatcher(name, value));
-        }
+        public List<T> selectMultiple(PropertyMatcher matcher) {
+            List<T> result = new ArrayList<>();
 
-        public List<T> selectMultiple(PropertyMatcher matcher) {
-            List<T> result = new ArrayList<T>();
             for (T t : objects) {
                 Property p = t.getProperties().selectSingle(matcher);
                 if (p != null) {
                     result.add(t);
                 }
             }
+
             return result;
         }
     }
@@ -259,6 +320,10 @@
     }
 
     public void setProperty(String name, String value) {
+        setPropertyInternal(name.intern(), value != null ? value.intern() : null);
+    }
+    private void setPropertyInternal(String name, String value) {
+
         for (int i = 0; i < map.length; i += 2) {
             if (map[i] != null && map[i].equals(name)) {
                 String p = map[i + 1];
@@ -289,34 +354,26 @@
         map = newMap;
     }
 
-    public  Iterator<Property> getProperties() {
-        return iterator();
-    }
-
     public void add(Properties properties) {
         for (Property p : properties) {
-            add(p);
+            // Already interned
+            setPropertyInternal(p.getName(), p.getValue());
         }
     }
 
-    public void add(Property property) {
-        assert property.getName() != null;
-        assert property.getValue() != null;
-        setProperty(property.getName(), property.getValue());
-    }
-    class PropertiesIterator implements Iterator<Property>, Iterable<Property> {
-        public Iterator<Property> iterator() {
-                return this;
-        }
+    private class PropertiesIterator implements Iterator<Property> {
 
         int index;
 
+        @Override
         public boolean hasNext() {
-            while (index < map.length && map[index + 1] == null)
+            while (index < map.length && map[index + 1] == null) {
                 index += 2;
+            }
             return index < map.length;
         }
 
+        @Override
         public Property next() {
             if (index < map.length) {
                 index += 2;
@@ -325,11 +382,13 @@
             return null;
         }
 
+        @Override
         public void remove() {
             throw new UnsupportedOperationException("Not supported yet.");
         }
+    }
 
-    }
+    @Override
     public Iterator<Property> iterator() {
         return new PropertiesIterator();
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,25 +32,20 @@
 public class Property implements Serializable {
 
     public static final long serialVersionUID = 1L;
-
     private String name;
     private String value;
 
-    private Property() {
-        this(null, null);
-    }
-
-    private Property(Property p) {
-        this(p.getName(), p.getValue());
-    }
-
-    private Property(String name) {
-        this(name, null);
-    }
-
-    public Property(String name, String value) {
+    Property(String name, String value) {
         this.name = name;
         this.value = value;
+
+        if (value == null) {
+            throw new IllegalArgumentException("Property value must not be null!");
+        }
+
+        if (name == null) {
+            throw new IllegalArgumentException("Property name must not be null!");
+        }
     }
 
     public String getName() {
@@ -63,17 +58,20 @@
 
     @Override
     public String toString() {
-        return name + " = " + value + "; ";
+        return name + "=" + value;
     }
 
     @Override
     public boolean equals(Object o) {
-        if (!(o instanceof Property)) return false;
-        Property p2 = (Property)o;
+        if (!(o instanceof Property)) {
+            return false;
+        }
+        Property p2 = (Property) o;
         return name.equals(p2.name) && value.equals(p2.value);
     }
+
     @Override
     public int hashCode() {
-        return name.hashCode() + value == null ? 0 : value.hashCode();
+        return name.hashCode() * 13 + value.hashCode();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Source.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+import java.util.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Source {
+
+    private List<InputNode> sourceNodes;
+    private Set<Integer> set;
+
+    public Source() {
+        sourceNodes = new ArrayList<>(1);
+        set = new LinkedHashSet<>(1);
+    }
+
+    public List<InputNode> getSourceNodes() {
+        return Collections.unmodifiableList(sourceNodes);
+    }
+
+    public Set<Integer> getSourceNodesAsSet() {
+        return Collections.unmodifiableSet(set);
+    }
+
+    public void addSourceNode(InputNode n) {
+        if (!set.contains(n.getId())) {
+            sourceNodes.add(n);
+            set.add(n.getId());
+        }
+    }
+
+    public interface Provider {
+
+        public Source getSource();
+    }
+
+    public void addSourceNodes(Source s) {
+        for (InputNode n : s.getSourceNodes()) {
+            addSourceNode(n);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/BinaryParser.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,900 @@
+/*
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.hotspot.igv.data.serialization;
+
+import com.sun.hotspot.igv.data.*;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.services.GroupCallback;
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ReadableByteChannel;
+import java.util.*;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.swing.SwingUtilities;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class BinaryParser implements GraphParser {
+    private static final int BEGIN_GROUP = 0x00;
+    private static final int BEGIN_GRAPH = 0x01;
+    private static final int CLOSE_GROUP = 0x02;
+
+    private static final int POOL_NEW = 0x00;
+    private static final int POOL_STRING = 0x01;
+    private static final int POOL_ENUM = 0x02;
+    private static final int POOL_CLASS = 0x03;
+    private static final int POOL_METHOD = 0x04;
+    private static final int POOL_NULL = 0x05;
+    private static final int POOL_NODE_CLASS = 0x06;
+    private static final int POOL_FIELD = 0x07;
+    private static final int POOL_SIGNATURE = 0x08;
+
+    private static final int KLASS = 0x00;
+    private static final int ENUM_KLASS = 0x01;
+
+    private static final int PROPERTY_POOL = 0x00;
+    private static final int PROPERTY_INT = 0x01;
+    private static final int PROPERTY_LONG = 0x02;
+    private static final int PROPERTY_DOUBLE = 0x03;
+    private static final int PROPERTY_FLOAT = 0x04;
+    private static final int PROPERTY_TRUE = 0x05;
+    private static final int PROPERTY_FALSE = 0x06;
+    private static final int PROPERTY_ARRAY = 0x07;
+    private static final int PROPERTY_SUBGRAPH = 0x08;
+
+    private static final String NO_BLOCK = "noBlock";
+
+    private final GroupCallback callback;
+    private final List<Object> constantPool;
+    private final ByteBuffer buffer;
+    private final ReadableByteChannel channel;
+    private final GraphDocument rootDocument;
+    private final Deque<Folder> folderStack;
+    private final Deque<byte[]> hashStack;
+    private final ParseMonitor monitor;
+
+    private MessageDigest digest;
+
+    private enum Length {
+        S,
+        M,
+        L
+    }
+
+    private interface LengthToString {
+        String toString(Length l);
+    }
+
+    private static abstract class Member implements LengthToString {
+        public final Klass holder;
+        public final int accessFlags;
+        public final String name;
+        public Member(Klass holder, String name, int accessFlags) {
+            this.holder = holder;
+            this.accessFlags = accessFlags;
+            this.name = name;
+        }
+    }
+
+    private static class Method extends Member {
+        public final Signature signature;
+        public final byte[] code;
+        public Method(String name, Signature signature, byte[] code, Klass holder, int accessFlags) {
+            super(holder, name, accessFlags);
+            this.signature = signature;
+            this.code = code;
+        }
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(holder).append('.').append(name).append('(');
+            for (int i = 0; i < signature.argTypes.length; i++) {
+                if (i > 0) {
+                    sb.append(", ");
+                }
+                sb.append(signature.argTypes[i]);
+            }
+            sb.append(')');
+            return sb.toString();
+        }
+        @Override
+        public String toString(Length l) {
+            switch(l) {
+                case M:
+                    return holder.toString(Length.L) + "." + name;
+                case S:
+                    return holder.toString(Length.S) + "." + name;
+                default:
+                case L:
+                    return toString();
+            }
+        }
+    }
+
+    private static class Signature {
+        public final String returnType;
+        public final String[] argTypes;
+        public Signature(String returnType, String[] argTypes) {
+            this.returnType = returnType;
+            this.argTypes = argTypes;
+        }
+    }
+
+    private static class Field extends Member {
+        public final String type;
+        public Field(String type, Klass holder, String name, int accessFlags) {
+            super(holder, name, accessFlags);
+            this.type = type;
+        }
+        @Override
+        public String toString() {
+            return holder + "." + name;
+        }
+        @Override
+        public String toString(Length l) {
+            switch(l) {
+                case M:
+                    return holder.toString(Length.L) + "." + name;
+                case S:
+                    return holder.toString(Length.S) + "." + name;
+                default:
+                case L:
+                    return toString();
+            }
+        }
+    }
+
+    private static class Klass implements LengthToString {
+        public final String name;
+        public final String simpleName;
+        public Klass(String name) {
+            this.name = name;
+            String simple;
+            try {
+                simple = name.substring(name.lastIndexOf('.') + 1);
+            } catch (IndexOutOfBoundsException ioobe) {
+                simple = name;
+            }
+            this.simpleName = simple;
+        }
+        @Override
+        public String toString() {
+            return name;
+        }
+        @Override
+        public String toString(Length l) {
+            switch(l) {
+                case S:
+                    return simpleName;
+                default:
+                case L:
+                case M:
+                    return toString();
+            }
+        }
+    }
+
+    private static class EnumKlass extends Klass {
+        public final String[] values;
+        public EnumKlass(String name, String[] values) {
+            super(name);
+            this.values = values;
+        }
+    }
+
+    private static class Port {
+        public final boolean isList;
+        public final String name;
+        private Port(boolean isList, String name) {
+            this.isList = isList;
+            this.name = name;
+        }
+    }
+
+    private static class TypedPort extends Port {
+        public final EnumValue type;
+        private TypedPort(boolean isList, String name, EnumValue type) {
+            super(isList, name);
+            this.type = type;
+        }
+    }
+
+    private static class NodeClass {
+        public final String className;
+        public final String nameTemplate;
+        public final List<TypedPort> inputs;
+        public final List<Port> sux;
+        private NodeClass(String className, String nameTemplate, List<TypedPort> inputs, List<Port> sux) {
+            this.className = className;
+            this.nameTemplate = nameTemplate;
+            this.inputs = inputs;
+            this.sux = sux;
+        }
+        @Override
+        public String toString() {
+            return className;
+        }
+    }
+
+    private static class EnumValue implements LengthToString {
+        public EnumKlass enumKlass;
+        public int ordinal;
+        public EnumValue(EnumKlass enumKlass, int ordinal) {
+            this.enumKlass = enumKlass;
+            this.ordinal = ordinal;
+        }
+        @Override
+        public String toString() {
+            return enumKlass.simpleName + "." + enumKlass.values[ordinal];
+        }
+        @Override
+        public String toString(Length l) {
+            switch(l) {
+                case S:
+                    return enumKlass.values[ordinal];
+                default:
+                case M:
+                case L:
+                    return toString();
+            }
+        }
+    }
+
+    public BinaryParser(ReadableByteChannel channel, ParseMonitor monitor, GraphDocument rootDocument, GroupCallback callback) {
+        this.callback = callback;
+        constantPool = new ArrayList<>();
+        buffer = ByteBuffer.allocateDirect(256 * 1024);
+        buffer.flip();
+        this.channel = channel;
+        this.rootDocument = rootDocument;
+        folderStack = new LinkedList<>();
+        hashStack = new LinkedList<>();
+        this.monitor = monitor;
+        try {
+            this.digest = MessageDigest.getInstance("SHA-256");
+        } catch (NoSuchAlgorithmException e) {
+        }
+    }
+
+    private void fill() throws IOException {
+        buffer.compact();
+        if (channel.read(buffer) < 0) {
+            throw new EOFException();
+        }
+        buffer.flip();
+    }
+
+    private void ensureAvailable(int i) throws IOException {
+        while (buffer.remaining() < i) {
+            fill();
+        }
+        buffer.mark();
+        byte[] result = new byte[i];
+        buffer.get(result);
+        digest.update(result);
+        buffer.reset();
+    }
+
+    private int readByte() throws IOException {
+        ensureAvailable(1);
+        return ((int)buffer.get()) & 0xff;
+    }
+
+    private int readInt() throws IOException {
+        ensureAvailable(4);
+        return buffer.getInt();
+    }
+
+    private char readShort() throws IOException {
+        ensureAvailable(2);
+        return buffer.getChar();
+    }
+
+    private long readLong() throws IOException {
+        ensureAvailable(8);
+        return buffer.getLong();
+    }
+
+    private double readDouble() throws IOException {
+        ensureAvailable(8);
+        return buffer.getDouble();
+    }
+
+    private float readFloat() throws IOException {
+        ensureAvailable(4);
+        return buffer.getFloat();
+    }
+
+    private String readString() throws IOException {
+        int len = readInt();
+        ensureAvailable(len * 2);
+        char[] chars = new char[len];
+        buffer.asCharBuffer().get(chars);
+        buffer.position(buffer.position() + len * 2);
+        return new String(chars).intern();
+    }
+
+    private byte[] readBytes() throws IOException {
+        int len = readInt();
+        if (len < 0) {
+            return null;
+        }
+        ensureAvailable(len);
+        byte[] data = new byte[len];
+        buffer.get(data);
+        return data;
+    }
+
+    private String readIntsToString() throws IOException {
+        int len = readInt();
+        if (len < 0) {
+            return "null";
+        }
+        ensureAvailable(len * 4);
+        StringBuilder sb = new StringBuilder().append('[');
+        for (int i = 0; i < len; i++) {
+            sb.append(buffer.getInt());
+            if (i < len - 1) {
+                sb.append(", ");
+            }
+        }
+        sb.append(']');
+        return sb.toString().intern();
+    }
+
+    private String readDoublesToString() throws IOException {
+        int len = readInt();
+        if (len < 0) {
+            return "null";
+        }
+        ensureAvailable(len * 8);
+        StringBuilder sb = new StringBuilder().append('[');
+        for (int i = 0; i < len; i++) {
+            sb.append(buffer.getDouble());
+            if (i < len - 1) {
+                sb.append(", ");
+            }
+        }
+        sb.append(']');
+        return sb.toString().intern();
+    }
+
+    private String readPoolObjectsToString() throws IOException {
+        int len = readInt();
+        if (len < 0) {
+            return "null";
+        }
+        StringBuilder sb = new StringBuilder().append('[');
+        for (int i = 0; i < len; i++) {
+            sb.append(readPoolObject(Object.class));
+            if (i < len - 1) {
+                sb.append(", ");
+            }
+        }
+        sb.append(']');
+        return sb.toString().intern();
+    }
+
+    private <T> T readPoolObject(Class<T> klass) throws IOException {
+        int type = readByte();
+        if (type == POOL_NULL) {
+            return null;
+        }
+        if (type == POOL_NEW) {
+            return (T) addPoolEntry(klass);
+        }
+        assert assertObjectType(klass, type);
+        char index = readShort();
+        if (index < 0 || index >= constantPool.size()) {
+            throw new IOException("Invalid constant pool index : " + index);
+        }
+        Object obj = constantPool.get(index);
+        return (T) obj;
+    }
+
+    private boolean assertObjectType(Class<?> klass, int type) {
+        switch(type) {
+            case POOL_CLASS:
+                return klass.isAssignableFrom(EnumKlass.class);
+            case POOL_ENUM:
+                return klass.isAssignableFrom(EnumValue.class);
+            case POOL_METHOD:
+                return klass.isAssignableFrom(Method.class);
+            case POOL_STRING:
+                return klass.isAssignableFrom(String.class);
+            case POOL_NODE_CLASS:
+                return klass.isAssignableFrom(NodeClass.class);
+            case POOL_FIELD:
+                return klass.isAssignableFrom(Field.class);
+            case POOL_SIGNATURE:
+                return klass.isAssignableFrom(Signature.class);
+            case POOL_NULL:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private Object addPoolEntry(Class<?> klass) throws IOException {
+        char index = readShort();
+        int type = readByte();
+        assert assertObjectType(klass, type) : "Wrong object type : " + klass + " != " + type;
+        Object obj;
+        switch(type) {
+            case POOL_CLASS: {
+                String name = readString();
+                int klasstype = readByte();
+                if (klasstype == ENUM_KLASS) {
+                    int len = readInt();
+                    String[] values = new String[len];
+                    for (int i = 0; i < len; i++) {
+                        values[i] = readPoolObject(String.class);
+                    }
+                    obj = new EnumKlass(name, values);
+                } else if (klasstype == KLASS) {
+                    obj = new Klass(name);
+                } else {
+                    throw new IOException("unknown klass type : " + klasstype);
+                }
+                break;
+            }
+            case POOL_ENUM: {
+                EnumKlass enumClass = readPoolObject(EnumKlass.class);
+                int ordinal = readInt();
+                obj = new EnumValue(enumClass, ordinal);
+                break;
+            }
+            case POOL_NODE_CLASS: {
+                String className = readString();
+                String nameTemplate = readString();
+                int inputCount = readShort();
+                List<TypedPort> inputs = new ArrayList<>(inputCount);
+                for (int i = 0; i < inputCount; i++) {
+                    boolean isList = readByte() != 0;
+                    String name = readPoolObject(String.class);
+                    EnumValue inputType = readPoolObject(EnumValue.class);
+                    inputs.add(new TypedPort(isList, name, inputType));
+                }
+                int suxCount = readShort();
+                List<Port> sux = new ArrayList<>(suxCount);
+                for (int i = 0; i < suxCount; i++) {
+                    boolean isList = readByte() != 0;
+                    String name = readPoolObject(String.class);
+                    sux.add(new Port(isList, name));
+                }
+                obj = new NodeClass(className, nameTemplate, inputs, sux);
+                break;
+            }
+            case POOL_METHOD: {
+                Klass holder = readPoolObject(Klass.class);
+                String name = readPoolObject(String.class);
+                Signature sign = readPoolObject(Signature.class);
+                int flags = readInt();
+                byte[] code = readBytes();
+                obj = new Method(name, sign, code, holder, flags);
+                break;
+            }
+            case POOL_FIELD: {
+                Klass holder = readPoolObject(Klass.class);
+                String name = readPoolObject(String.class);
+                String fType = readPoolObject(String.class);
+                int flags = readInt();
+                obj = new Field(fType, holder, name, flags);
+                break;
+            }
+            case POOL_SIGNATURE: {
+                int argc = readShort();
+                String[] args = new String[argc];
+                for (int i = 0; i < argc; i++) {
+                    args[i] = readPoolObject(String.class);
+                }
+                String returnType = readPoolObject(String.class);
+                obj = new Signature(returnType, args);
+                break;
+            }
+            case POOL_STRING: {
+                obj = readString();
+                break;
+            }
+            default:
+                throw new IOException("unknown pool type");
+        }
+        while (constantPool.size() <= index) {
+            constantPool.add(null);
+        }
+        constantPool.set(index, obj);
+        return obj;
+    }
+
+    private Object readPropertyObject() throws IOException {
+        int type = readByte();
+        switch (type) {
+            case PROPERTY_INT:
+                return readInt();
+            case PROPERTY_LONG:
+                return readLong();
+            case PROPERTY_FLOAT:
+                return readFloat();
+            case PROPERTY_DOUBLE:
+                return readDouble();
+            case PROPERTY_TRUE:
+                return Boolean.TRUE;
+            case PROPERTY_FALSE:
+                return Boolean.FALSE;
+            case PROPERTY_POOL:
+                return readPoolObject(Object.class);
+            case PROPERTY_ARRAY:
+                int subType = readByte();
+                switch(subType) {
+                    case PROPERTY_INT:
+                        return readIntsToString();
+                    case PROPERTY_DOUBLE:
+                        return readDoublesToString();
+                    case PROPERTY_POOL:
+                        return readPoolObjectsToString();
+                    default:
+                        throw new IOException("Unknown type");
+                }
+            case PROPERTY_SUBGRAPH:
+                InputGraph graph = parseGraph("");
+                new Group(null).addElement(graph);
+                return graph;
+            default:
+                throw new IOException("Unknown type");
+        }
+    }
+
+    @Override
+    public GraphDocument parse() throws IOException {
+        folderStack.push(rootDocument);
+        hashStack.push(null);
+        if (monitor != null) {
+            monitor.setState("Starting parsing");
+        }
+        try {
+            while(true) {
+                parseRoot();
+            }
+        } catch (EOFException e) {
+
+        }
+        if (monitor != null) {
+            monitor.setState("Finished parsing");
+        }
+        return rootDocument;
+    }
+
+    private void parseRoot() throws IOException {
+        int type = readByte();
+        switch(type) {
+            case BEGIN_GRAPH: {
+                final Folder parent = folderStack.peek();
+                final InputGraph graph = parseGraph();
+                SwingUtilities.invokeLater(new Runnable(){
+                    @Override
+                    public void run() {
+                        parent.addElement(graph);
+                    }
+                });
+                break;
+            }
+            case BEGIN_GROUP: {
+                final Folder parent = folderStack.peek();
+                final Group group = parseGroup(parent);
+                if (callback == null || parent instanceof Group) {
+                    SwingUtilities.invokeLater(new Runnable(){
+                        @Override
+                        public void run() {
+                            parent.addElement(group);
+                        }
+                    });
+                }
+                folderStack.push(group);
+                hashStack.push(null);
+                if (callback != null && parent instanceof GraphDocument) {
+                    callback.started(group);
+                }
+                break;
+            }
+            case CLOSE_GROUP: {
+                if (folderStack.isEmpty()) {
+                    throw new IOException("Unbalanced groups");
+                }
+                folderStack.pop();
+                hashStack.pop();
+                break;
+            }
+            default:
+                throw new IOException("unknown root : " + type);
+        }
+    }
+
+    private Group parseGroup(Folder parent) throws IOException {
+        String name = readPoolObject(String.class);
+        String shortName = readPoolObject(String.class);
+        if (monitor != null) {
+            monitor.setState(shortName);
+        }
+        Method method = readPoolObject(Method.class);
+        int bci = readInt();
+        Group group = new Group(parent);
+        group.getProperties().setProperty("name", name);
+        if (method != null) {
+            InputMethod inMethod = new InputMethod(group, method.name, shortName, bci);
+            inMethod.setBytecodes("TODO");
+            group.setMethod(inMethod);
+        }
+        return group;
+    }
+
+    private InputGraph parseGraph() throws IOException {
+        if (monitor != null) {
+            monitor.updateProgress();
+        }
+        String title = readPoolObject(String.class);
+        digest.reset();
+        InputGraph graph = parseGraph(title);
+        byte[] d = digest.digest();
+        byte[] hash = hashStack.peek();
+        if (hash != null && Arrays.equals(hash, d)) {
+            graph.getProperties().setProperty("_isDuplicate", "true");
+        } else {
+            hashStack.pop();
+            hashStack.push(d);
+        }
+        return graph;
+    }
+
+    private InputGraph parseGraph(String title) throws IOException {
+        InputGraph graph = new InputGraph(title);
+        parseNodes(graph);
+        parseBlocks(graph);
+        graph.ensureNodesInBlocks();
+        return graph;
+    }
+
+    private void parseBlocks(InputGraph graph) throws IOException {
+        int blockCount = readInt();
+        List<Edge> edges = new LinkedList<>();
+        for (int i = 0; i < blockCount; i++) {
+            int id = readInt();
+            String name = id >= 0 ? Integer.toString(id) : NO_BLOCK;
+            InputBlock block = graph.addBlock(name);
+            int nodeCount = readInt();
+            for (int j = 0; j < nodeCount; j++) {
+                int nodeId = readInt();
+                if (nodeId < 0) {
+                    continue;
+                }
+                final Properties properties = graph.getNode(nodeId).getProperties();
+                final String oldBlock = properties.get("block");
+                if(oldBlock != null) {
+                    properties.setProperty("block", oldBlock + ", " + name);
+                } else {
+                    block.addNode(nodeId);
+                    properties.setProperty("block", name);
+                }
+            }
+            int edgeCount = readInt();
+            for (int j = 0; j < edgeCount; j++) {
+                int to = readInt();
+                edges.add(new Edge(id, to));
+            }
+        }
+        for (Edge e : edges) {
+            String fromName = e.from >= 0 ? Integer.toString(e.from) : NO_BLOCK;
+            String toName = e.to >= 0 ? Integer.toString(e.to) : NO_BLOCK;
+            graph.addBlockEdge(graph.getBlock(fromName), graph.getBlock(toName));
+        }
+    }
+
+    private void parseNodes(InputGraph graph) throws IOException {
+        int count = readInt();
+        Map<String, Object> props = new HashMap<>();
+        List<Edge> inputEdges = new ArrayList<>(count);
+        List<Edge> succEdges = new ArrayList<>(count);
+        for (int i = 0; i < count; i++) {
+            int id = readInt();
+            InputNode node = new InputNode(id);
+            final Properties properties = node.getProperties();
+            NodeClass nodeClass = readPoolObject(NodeClass.class);
+            int preds = readByte();
+            if (preds > 0) {
+                properties.setProperty("hasPredecessor", "true");
+            }
+            properties.setProperty("idx", Integer.toString(id));
+            int propCount = readShort();
+            for (int j = 0; j < propCount; j++) {
+                String key = readPoolObject(String.class);
+                if (key.equals("hasPredecessor") || key.equals("name") || key.equals("class") || key.equals("id") || key.equals("idx")) {
+                    key = "!data." + key;
+                }
+                Object value = readPropertyObject();
+                if (value instanceof InputGraph) {
+                    InputGraph subgraph = (InputGraph) value;
+                    subgraph.getProperties().setProperty("name", node.getId() + ":" + key);
+                    node.addSubgraph((InputGraph) value);
+                } else {
+                    properties.setProperty(key, value != null ? value.toString() : "null");
+                    props.put(key, value);
+                }
+            }
+            ArrayList<Edge> currentEdges = new ArrayList<>();
+            int portNum = 0;
+            for (TypedPort p : nodeClass.inputs) {
+                if (p.isList) {
+                    int size = readShort();
+                    for (int j = 0; j < size; j++) {
+                        int in = readInt();
+                        if (in >= 0) {
+                            Edge e = new Edge(in, id, (char) (preds + portNum), p.name + "[" + j + "]", p.type.toString(Length.S), true);
+                            currentEdges.add(e);
+                            inputEdges.add(e);
+                            portNum++;
+                        }
+                    }
+                } else {
+                    int in = readInt();
+                    if (in >= 0) {
+                        Edge e = new Edge(in, id, (char) (preds + portNum), p.name, p.type.toString(Length.S), true);
+                        currentEdges.add(e);
+                        inputEdges.add(e);
+                        portNum++;
+                    }
+                }
+
+            }
+            portNum = 0;
+            for (Port p : nodeClass.sux) {
+                if (p.isList) {
+                    int size = readShort();
+                    for (int j = 0; j < size; j++) {
+                        int sux = readInt();
+                        if (sux >= 0) {
+                            Edge e = new Edge(id, sux, (char) portNum, p.name + "[" + j + "]", "Successor", false);
+                            currentEdges.add(e);
+                            succEdges.add(e);
+                            portNum++;
+                        }
+                    }
+                } else {
+                    int sux = readInt();
+                    if (sux >= 0) {
+                        Edge e = new Edge(id, sux, (char) portNum, p.name, "Successor", false);
+                        currentEdges.add(e);
+                        succEdges.add(e);
+                        portNum++;
+                    }
+                }
+            }
+            properties.setProperty("name", createName(currentEdges, props, nodeClass.nameTemplate));
+            properties.setProperty("class", nodeClass.className);
+            switch (nodeClass.className) {
+                case "BeginNode":
+                    properties.setProperty("shortName", "B");
+                    break;
+                case "EndNode":
+                    properties.setProperty("shortName", "E");
+                    break;
+            }
+            graph.addNode(node);
+            props.clear();
+        }
+
+        Set<InputNode> nodesWithSuccessor = new HashSet<>();
+
+        for (Edge e : succEdges) {
+            assert !e.input;
+            char fromIndex = e.num;
+            nodesWithSuccessor.add(graph.getNode(e.from));
+            char toIndex = 0;
+            graph.addEdge(InputEdge.createImmutable(fromIndex, toIndex, e.from, e.to, e.label, e.type));
+        }
+        for (Edge e : inputEdges) {
+            assert e.input;
+            char fromIndex = (char) (nodesWithSuccessor.contains(graph.getNode(e.from)) ? 1 : 0);
+            char toIndex = e.num;
+            graph.addEdge(InputEdge.createImmutable(fromIndex, toIndex, e.from, e.to, e.label, e.type));
+        }
+    }
+
+    private String createName(List<Edge> edges, Map<String, Object> properties, String template) {
+        Pattern p = Pattern.compile("\\{(p|i)#([a-zA-Z0-9$_]+)(/(l|m|s))?\\}");
+        Matcher m = p.matcher(template);
+        StringBuffer sb = new StringBuffer();
+        while (m.find()) {
+            String name = m.group(2);
+            String type = m.group(1);
+            String result;
+            switch (type) {
+                case "i":
+                    StringBuilder inputString = new StringBuilder();
+                    for(Edge edge : edges) {
+                        if (edge.label.startsWith(name) && (name.length() == edge.label.length() || edge.label.charAt(name.length()) == '[')) {
+                            if (inputString.length() > 0) {
+                                inputString.append(", ");
+                            }
+                            inputString.append(edge.from);
+                        }
+                    }
+                    result = inputString.toString();
+                    break;
+                case "p":
+                    Object prop = properties.get(name);
+                    String length = m.group(4);
+                    if (prop == null) {
+                        result = "?";
+                    } else if (length != null && prop instanceof LengthToString) {
+                        LengthToString lengthProp = (LengthToString) prop;
+                        switch(length) {
+                            default:
+                            case "l":
+                                result = lengthProp.toString(Length.L);
+                                break;
+                            case "m":
+                                result = lengthProp.toString(Length.M);
+                                break;
+                            case "s":
+                                result = lengthProp.toString(Length.S);
+                                break;
+                        }
+                    } else {
+                        result = prop.toString();
+                    }
+                    break;
+                default:
+                    result = "#?#";
+                    break;
+            }
+            result = result.replace("\\", "\\\\");
+            result = result.replace("$", "\\$");
+            m.appendReplacement(sb, result);
+        }
+        m.appendTail(sb);
+        return sb.toString().intern();
+    }
+
+    private static class Edge {
+        final int from;
+        final int to;
+        final char num;
+        final String label;
+        final String type;
+        final boolean input;
+        public Edge(int from, int to) {
+            this(from, to, (char) 0, null, null, false);
+        }
+        public Edge(int from, int to, char num, String label, String type, boolean input) {
+            this.from = from;
+            this.to = to;
+            this.label = label != null ? label.intern() : label;
+            this.type = type != null ? type.intern() : type;
+            this.num = num;
+            this.input = input;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/GraphParser.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.hotspot.igv.data.serialization;
+
+import com.sun.hotspot.igv.data.GraphDocument;
+import java.io.IOException;
+
+public interface GraphParser {
+    public GraphDocument parse() throws IOException;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/ParseMonitor.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.hotspot.igv.data.serialization;
+
+public interface ParseMonitor {
+
+    public void updateProgress();
+
+    public void setState(String state);
+
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,31 +23,34 @@
  */
 package com.sun.hotspot.igv.data.serialization;
 
-import com.sun.hotspot.igv.data.GraphDocument;
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.data.InputEdge;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.InputMethod;
-import com.sun.hotspot.igv.data.InputNode;
-import com.sun.hotspot.igv.data.Properties;
-import com.sun.hotspot.igv.data.Property;
-import com.sun.hotspot.igv.data.services.GroupCallback;
+import com.sun.hotspot.igv.data.*;
 import com.sun.hotspot.igv.data.serialization.XMLParser.ElementHandler;
 import com.sun.hotspot.igv.data.serialization.XMLParser.HandoverElementHandler;
-import com.sun.hotspot.igv.data.serialization.XMLParser.ParseMonitor;
 import com.sun.hotspot.igv.data.serialization.XMLParser.TopElementHandler;
+import com.sun.hotspot.igv.data.services.GroupCallback;
 import java.io.IOException;
+import java.io.InputStream;
+import java.nio.channels.Channels;
+import java.nio.channels.ReadableByteChannel;
+import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.Map;
+import javax.swing.SwingUtilities;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.parsers.SAXParserFactory;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.SchemaFactory;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
 import org.xml.sax.XMLReader;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class Parser {
+public class Parser implements GraphParser {
 
     public static final String INDENT = "  ";
     public static final String TOP_ELEMENT = "graphDocument";
@@ -63,6 +66,7 @@
     public static final String REMOVE_EDGE_ELEMENT = "removeEdge";
     public static final String REMOVE_NODE_ELEMENT = "removeNode";
     public static final String METHOD_NAME_PROPERTY = "name";
+    public static final String GROUP_NAME_PROPERTY = "name";
     public static final String METHOD_IS_PUBLIC_PROPERTY = "public";
     public static final String METHOD_IS_STATIC_PROPERTY = "static";
     public static final String TRUE_VALUE = "true";
@@ -71,9 +75,13 @@
     public static final String NODE_ID_PROPERTY = "id";
     public static final String FROM_PROPERTY = "from";
     public static final String TO_PROPERTY = "to";
+    public static final String TYPE_PROPERTY = "type";
     public static final String PROPERTY_NAME_PROPERTY = "name";
     public static final String GRAPH_NAME_PROPERTY = "name";
-    public static final String TO_INDEX_PROPERTY = "index";
+    public static final String FROM_INDEX_PROPERTY = "fromIndex";
+    public static final String TO_INDEX_PROPERTY = "toIndex";
+    public static final String TO_INDEX_ALT_PROPERTY = "index";
+    public static final String LABEL_PROPERTY = "label";
     public static final String METHOD_ELEMENT = "method";
     public static final String INLINE_ELEMENT = "inline";
     public static final String BYTECODES_ELEMENT = "bytecodes";
@@ -86,13 +94,23 @@
     public static final String SUCCESSOR_ELEMENT = "successor";
     public static final String ASSEMBLY_ELEMENT = "assembly";
     public static final String DIFFERENCE_PROPERTY = "difference";
-    private TopElementHandler xmlDocument = new TopElementHandler();
-    private boolean difference;
+    private TopElementHandler<GraphDocument> xmlDocument = new TopElementHandler<>();
+    private Map<Group, Boolean> differenceEncoding = new HashMap<>();
+    private Map<Group, InputGraph> lastParsedGraph = new HashMap<>();
     private GroupCallback groupCallback;
-    private HashMap<String, Integer> idCache = new HashMap<String, Integer>();
+    private HashMap<String, Integer> idCache = new HashMap<>();
+    private ArrayList<Pair<String, String>> blockConnections = new ArrayList<>();
     private int maxId = 0;
+    private GraphDocument graphDocument;
+    private final ParseMonitor monitor;
+    private final ReadableByteChannel channel;
 
     private int lookupID(String i) {
+        try {
+            return Integer.parseInt(i);
+        } catch (NumberFormatException nfe) {
+            // ignore
+        }
         Integer id = idCache.get(i);
         if (id == null) {
             id = maxId++;
@@ -106,41 +124,40 @@
 
         @Override
         protected GraphDocument start() throws SAXException {
-            return new GraphDocument();
+            graphDocument = new GraphDocument();
+            return graphDocument;
         }
     };
     // <group>
-    private ElementHandler<Group, GraphDocument> groupHandler = new XMLParser.ElementHandler<Group, GraphDocument>(GROUP_ELEMENT) {
+    private ElementHandler<Group, Folder> groupHandler = new XMLParser.ElementHandler<Group, Folder>(GROUP_ELEMENT) {
 
         @Override
         protected Group start() throws SAXException {
-            Group group = new Group();
-            Parser.this.difference = false;
+            final Group group = new Group(this.getParentObject());
+
             String differenceProperty = this.readAttribute(DIFFERENCE_PROPERTY);
-            if (differenceProperty != null && (differenceProperty.equals("1") || differenceProperty.equals("true"))) {
-                Parser.this.difference = true;
-            }
+            Parser.this.differenceEncoding.put(group, (differenceProperty != null && (differenceProperty.equals("1") || differenceProperty.equals("true"))));
 
             ParseMonitor monitor = getMonitor();
             if (monitor != null) {
                 monitor.setState(group.getName());
             }
 
+            final Folder parent = getParentObject();
+            if (groupCallback == null || parent instanceof Group) {
+                SwingUtilities.invokeLater(new Runnable(){
+                    @Override
+                    public void run() {
+                        parent.addElement(group);
+                    }
+                });
+            }
+
             return group;
         }
 
         @Override
         protected void end(String text) throws SAXException {
-            if (groupCallback == null) {
-                getParentObject().addGroup(getObject());
-            }
-        }
-    };
-    private HandoverElementHandler<Group> assemblyHandler = new XMLParser.HandoverElementHandler<Group>(ASSEMBLY_ELEMENT, true) {
-
-        @Override
-        protected void end(String text) throws SAXException {
-            getParentObject().setAssembly(text);
         }
     };
     // <method>
@@ -155,7 +172,7 @@
         }
     };
 
-    private InputMethod parseMethod(XMLParser.ElementHandler handler, Group group) throws SAXException {
+    private InputMethod parseMethod(XMLParser.ElementHandler<?,?> handler, Group group) throws SAXException {
         String s = handler.readRequiredAttribute(METHOD_BCI_PROPERTY);
         int bci = 0;
         try {
@@ -175,7 +192,7 @@
         }
     };
     // <inlined>
-    private HandoverElementHandler<InputMethod> inlinedHandler = new XMLParser.HandoverElementHandler<InputMethod>(INLINE_ELEMENT);
+    private HandoverElementHandler<InputMethod> inlinedHandler = new XMLParser.HandoverElementHandler<>(INLINE_ELEMENT);
     // <inlined><method>
     private ElementHandler<InputMethod, InputMethod> inlinedMethodHandler = new XMLParser.ElementHandler<InputMethod, InputMethod>(METHOD_ELEMENT) {
 
@@ -189,45 +206,110 @@
     // <graph>
     private ElementHandler<InputGraph, Group> graphHandler = new XMLParser.ElementHandler<InputGraph, Group>(GRAPH_ELEMENT) {
 
-        private InputGraph graph;
-
         @Override
         protected InputGraph start() throws SAXException {
-
             String name = readAttribute(GRAPH_NAME_PROPERTY);
-            InputGraph previous = getParentObject().getLastAdded();
-            if (!difference) {
-                previous = null;
+            InputGraph curGraph = new InputGraph(name);
+            if (differenceEncoding.get(getParentObject())) {
+                InputGraph previous = lastParsedGraph.get(getParentObject());
+                lastParsedGraph.put(getParentObject(), curGraph);
+                if (previous != null) {
+                    for (InputNode n : previous.getNodes()) {
+                        curGraph.addNode(n);
+                    }
+                    for (InputEdge e : previous.getEdges()) {
+                        curGraph.addEdge(e);
+                    }
+                }
             }
-            InputGraph curGraph = new InputGraph(getParentObject(), previous, name);
-            this.graph = curGraph;
+            ParseMonitor monitor = getMonitor();
+            if (monitor != null) {
+                monitor.updateProgress();
+            }
             return curGraph;
         }
 
         @Override
         protected void end(String text) throws SAXException {
-            getParentObject().addGraph(graph);
-            graph.resolveBlockLinks();
+            // NOTE: Some graphs intentionally don't provide blocks. Instead
+            //       they later generate the blocks from other information such
+            //       as node properties (example: ServerCompilerScheduler).
+            //       Thus, we shouldn't assign nodes that don't belong to any
+            //       block to some artificial block below unless blocks are
+            //       defined and nodes are assigned to them.
+
+            final InputGraph graph = getObject();
+            final Group parent = getParentObject();
+            if (graph.getBlocks().size() > 0) {
+                boolean blocksContainNodes = false;
+                for (InputBlock b : graph.getBlocks()) {
+                    if (b.getNodes().size() > 0) {
+                        blocksContainNodes = true;
+                        break;
+                    }
+                }
+
+                if (!blocksContainNodes) {
+                    graph.clearBlocks();
+                    blockConnections.clear();
+                } else {
+                    // Blocks and their nodes defined: add other nodes to an
+                    //  artificial "no block" block
+                    InputBlock noBlock = null;
+                    for (InputNode n : graph.getNodes()) {
+                        if (graph.getBlock(n) == null) {
+                            if (noBlock == null) {
+                                noBlock = graph.addBlock("(no block)");
+                            }
+
+                            noBlock.addNode(n.getId());
+                        }
+
+                        assert graph.getBlock(n) != null;
+                    }
+                }
+            }
+
+            // Resolve block successors
+            for (Pair<String, String> p : blockConnections) {
+                final InputBlock left = graph.getBlock(p.getLeft());
+                assert left != null;
+                final InputBlock right = graph.getBlock(p.getRight());
+                assert right != null;
+                graph.addBlockEdge(left, right);
+            }
+            blockConnections.clear();
+
+            SwingUtilities.invokeLater(new Runnable(){
+
+                @Override
+                public void run() {
+                    // Add to group
+                    parent.addElement(graph);
+                }
+            });
         }
     };
     // <nodes>
-    private HandoverElementHandler<InputGraph> nodesHandler = new HandoverElementHandler<InputGraph>(NODES_ELEMENT);
+    private HandoverElementHandler<InputGraph> nodesHandler = new HandoverElementHandler<>(NODES_ELEMENT);
     // <controlFlow>
-    private HandoverElementHandler<InputGraph> controlFlowHandler = new HandoverElementHandler<InputGraph>(CONTROL_FLOW_ELEMENT);
+    private HandoverElementHandler<InputGraph> controlFlowHandler = new HandoverElementHandler<>(CONTROL_FLOW_ELEMENT);
     // <block>
     private ElementHandler<InputBlock, InputGraph> blockHandler = new ElementHandler<InputBlock, InputGraph>(BLOCK_ELEMENT) {
 
         @Override
         protected InputBlock start() throws SAXException {
             InputGraph graph = getParentObject();
-            String name = readRequiredAttribute(BLOCK_NAME_PROPERTY).intern();
-            InputBlock b = new InputBlock(getParentObject(), name);
-            graph.addBlock(b);
+            String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
+            InputBlock b = graph.addBlock(name);
+            for (InputNode n : b.getNodes()) {
+                assert graph.getBlock(n).equals(b);
+            }
             return b;
         }
     };
     // <nodes>
-    private HandoverElementHandler<InputBlock> blockNodesHandler = new HandoverElementHandler<InputBlock>(NODES_ELEMENT);
+    private HandoverElementHandler<InputBlock> blockNodesHandler = new HandoverElementHandler<>(NODES_ELEMENT);
     // <node>
     private ElementHandler<InputBlock, InputBlock> blockNodeHandler = new ElementHandler<InputBlock, InputBlock>(NODE_ELEMENT) {
 
@@ -246,14 +328,14 @@
         }
     };
     // <successors>
-    private HandoverElementHandler<InputBlock> successorsHandler = new HandoverElementHandler<InputBlock>(SUCCESSORS_ELEMENT);
+    private HandoverElementHandler<InputBlock> successorsHandler = new HandoverElementHandler<>(SUCCESSORS_ELEMENT);
     // <successor>
     private ElementHandler<InputBlock, InputBlock> successorHandler = new ElementHandler<InputBlock, InputBlock>(SUCCESSOR_ELEMENT) {
 
         @Override
         protected InputBlock start() throws SAXException {
             String name = readRequiredAttribute(BLOCK_NAME_PROPERTY);
-            getParentObject().addSuccessor(name);
+            blockConnections.add(new Pair<>(getParentObject().getName(), name));
             return getParentObject();
         }
     };
@@ -290,7 +372,7 @@
         }
     };
     // <graph>
-    private HandoverElementHandler<InputGraph> edgesHandler = new HandoverElementHandler<InputGraph>(EDGES_ELEMENT);
+    private HandoverElementHandler<InputGraph> edgesHandler = new HandoverElementHandler<>(EDGES_ELEMENT);
 
     // Local class for edge elements
     private class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> {
@@ -301,24 +383,37 @@
 
         @Override
         protected InputEdge start() throws SAXException {
+            int fromIndex = 0;
             int toIndex = 0;
             int from = -1;
             int to = -1;
+            String label = null;
+            String type = null;
 
             try {
+                String fromIndexString = readAttribute(FROM_INDEX_PROPERTY);
+                if (fromIndexString != null) {
+                    fromIndex = Integer.parseInt(fromIndexString);
+                }
+
                 String toIndexString = readAttribute(TO_INDEX_PROPERTY);
+                if (toIndexString == null) {
+                    toIndexString = readAttribute(TO_INDEX_ALT_PROPERTY);
+                }
                 if (toIndexString != null) {
                     toIndex = Integer.parseInt(toIndexString);
                 }
 
+                label = readAttribute(LABEL_PROPERTY);
+                type = readAttribute(TYPE_PROPERTY);
+
                 from = lookupID(readRequiredAttribute(FROM_PROPERTY));
                 to = lookupID(readRequiredAttribute(TO_PROPERTY));
             } catch (NumberFormatException e) {
                 throw new SAXException(e);
             }
 
-
-            InputEdge conn = new InputEdge((char) toIndex, from, to);
+            InputEdge conn = new InputEdge((char) fromIndex, (char) toIndex, from, to, label, type == null ? "" : type);
             return start(conn);
         }
 
@@ -345,14 +440,20 @@
         }
     };
     // <properties>
-    private HandoverElementHandler<Properties.Provider> propertiesHandler = new HandoverElementHandler<Properties.Provider>(PROPERTIES_ELEMENT);
+    private HandoverElementHandler<Properties.Provider> propertiesHandler = new HandoverElementHandler<>(PROPERTIES_ELEMENT);
     // <properties>
     private HandoverElementHandler<Group> groupPropertiesHandler = new HandoverElementHandler<Group>(PROPERTIES_ELEMENT) {
 
         @Override
         public void end(String text) throws SAXException {
-            if (groupCallback != null) {
-                groupCallback.started(getParentObject());
+            if (groupCallback != null && getParentObject().getParent() instanceof GraphDocument) {
+                final Group group = getParentObject();
+                SwingUtilities.invokeLater(new Runnable() {
+                    @Override
+                    public void run() {
+                        groupCallback.started(group);
+                    }
+                });
             }
         }
     };
@@ -361,30 +462,32 @@
 
         @Override
         public String start() throws SAXException {
-            return readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
-        }
+            return readRequiredAttribute(PROPERTY_NAME_PROPERTY);
+         }
 
         @Override
         public void end(String text) {
-            getParentObject().getProperties().setProperty(getObject(), text.trim().intern());
+            getParentObject().getProperties().setProperty(getObject(), text.trim());
         }
     };
 
-    public Parser() {
-        this(null);
+    public Parser(ReadableByteChannel channel) {
+        this(channel, null, null);
     }
 
-    public Parser(GroupCallback groupCallback) {
+    public Parser(ReadableByteChannel channel, ParseMonitor monitor, GroupCallback groupCallback) {
 
         this.groupCallback = groupCallback;
+        this.monitor = monitor;
+        this.channel = channel;
 
         // Initialize dependencies
         xmlDocument.addChild(topHandler);
         topHandler.addChild(groupHandler);
 
         groupHandler.addChild(methodHandler);
-        groupHandler.addChild(assemblyHandler);
         groupHandler.addChild(graphHandler);
+        groupHandler.addChild(groupHandler);
 
         methodHandler.addChild(inlinedHandler);
         methodHandler.addChild(bytecodesHandler);
@@ -420,14 +523,40 @@
     }
 
     // Returns a new GraphDocument object deserialized from an XML input source.
-    public GraphDocument parse(XMLReader reader, InputSource source, XMLParser.ParseMonitor monitor) throws SAXException {
-        reader.setContentHandler(new XMLParser(xmlDocument, monitor));
+    @Override
+    public GraphDocument parse() throws IOException {
+        if (monitor != null) {
+            monitor.setState("Starting parsing");
+        }
         try {
-            reader.parse(source);
-        } catch (IOException ex) {
+            XMLReader reader = createReader();
+            reader.setContentHandler(new XMLParser(xmlDocument, monitor));
+            reader.parse(new InputSource(Channels.newInputStream(channel)));
+        } catch (SAXException ex) {
+            if (!(ex instanceof SAXParseException) || !"XML document structures must start and end within the same entity.".equals(ex.getMessage())) {
+                throw new IOException(ex);
+            }
+        }
+        if (monitor != null) {
+            monitor.setState("Finished parsing");
+        }
+        return graphDocument;
+    }
+
+    private XMLReader createReader() throws SAXException {
+        try {
+            SAXParserFactory pfactory = SAXParserFactory.newInstance();
+            pfactory.setValidating(true);
+            pfactory.setNamespaceAware(true);
+
+            // Enable schema validation
+            SchemaFactory sfactory = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
+            InputStream stream = Parser.class.getResourceAsStream("graphdocument.xsd");
+            pfactory.setSchema(sfactory.newSchema(new Source[]{new StreamSource(stream)}));
+
+            return pfactory.newSAXParser().getXMLReader();
+        } catch (ParserConfigurationException ex) {
             throw new SAXException(ex);
         }
-
-        return topHandler.getObject();
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,17 +23,9 @@
  */
 package com.sun.hotspot.igv.data.serialization;
 
-import com.sun.hotspot.igv.data.GraphDocument;
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.data.InputBytecode;
-import com.sun.hotspot.igv.data.InputEdge;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.InputMethod;
-import com.sun.hotspot.igv.data.InputNode;
-import com.sun.hotspot.igv.data.Properties;
-import com.sun.hotspot.igv.data.Property;
+import com.sun.hotspot.igv.data.*;
 import java.io.IOException;
+import java.io.InputStream;
 import java.io.Writer;
 import java.util.HashSet;
 import java.util.Set;
@@ -44,6 +36,16 @@
  */
 public class Printer {
 
+    private InputStream in;
+
+    public Printer() {
+        this(null);
+    }
+
+    public Printer(InputStream inputStream) {
+        this.in = inputStream;
+    }
+
     public void export(Writer writer, GraphDocument document) {
 
         XMLWriter xmlWriter = new XMLWriter(writer);
@@ -57,8 +59,12 @@
     private void export(XMLWriter xmlWriter, GraphDocument document) throws IOException {
         xmlWriter.startTag(Parser.ROOT_ELEMENT);
         xmlWriter.writeProperties(document.getProperties());
-        for (Group g : document.getGroups()) {
-            export(xmlWriter, g);
+        for (FolderElement e : document.getElements()) {
+            if (e instanceof Group) {
+                export(xmlWriter, (Group) e);
+            } else if (e instanceof InputGraph) {
+                export(xmlWriter, (InputGraph)e, null, false);
+            }
         }
 
         xmlWriter.endTag();
@@ -71,14 +77,29 @@
         writer.startTag(Parser.GROUP_ELEMENT, attributes);
         writer.writeProperties(g.getProperties());
 
-        if (g.getMethod() != null) {
-            export(writer, g.getMethod());
+        boolean shouldExport = true;
+        if (in != null) {
+            char c = (char) in.read();
+            if (c != 'y') {
+                shouldExport = false;
+            }
         }
 
-        InputGraph previous = null;
-        for (InputGraph graph : g.getGraphs()) {
-            export(writer, graph, previous, true);
-            previous = graph;
+        if (shouldExport) {
+            if (g.getMethod() != null) {
+                export(writer, g.getMethod());
+            }
+
+            InputGraph previous = null;
+            for (FolderElement e : g.getElements()) {
+                if (e instanceof InputGraph) {
+                    InputGraph graph = (InputGraph) e;
+                    export(writer, graph, previous, true);
+                    previous = graph;
+                } else if (e instanceof Group) {
+                    export(writer, (Group) e);
+                }
+            }
         }
 
         writer.endTag();
@@ -90,8 +111,8 @@
         writer.writeProperties(graph.getProperties());
         writer.startTag(Parser.NODES_ELEMENT);
 
-        Set<InputNode> removed = new HashSet<InputNode>();
-        Set<InputNode> equal = new HashSet<InputNode>();
+        Set<InputNode> removed = new HashSet<>();
+        Set<InputNode> equal = new HashSet<>();
 
         if (previous != null) {
             for (InputNode n : previous.getNodes()) {
@@ -122,8 +143,8 @@
         writer.endTag();
 
         writer.startTag(Parser.EDGES_ELEMENT);
-        Set<InputEdge> removedEdges = new HashSet<InputEdge>();
-        Set<InputEdge> equalEdges = new HashSet<InputEdge>();
+        Set<InputEdge> removedEdges = new HashSet<>();
+        Set<InputEdge> equalEdges = new HashSet<>();
 
         if (previous != null) {
             for (InputEdge e : previous.getEdges()) {
@@ -153,23 +174,25 @@
 
         writer.startTag(Parser.CONTROL_FLOW_ELEMENT);
         for (InputBlock b : graph.getBlocks()) {
-
             writer.startTag(Parser.BLOCK_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, b.getName()));
 
-            writer.startTag(Parser.SUCCESSORS_ELEMENT);
-            for (InputBlock s : b.getSuccessors()) {
-                writer.simpleTag(Parser.SUCCESSOR_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, s.getName()));
+            if (b.getSuccessors().size() > 0) {
+                writer.startTag(Parser.SUCCESSORS_ELEMENT);
+                for (InputBlock s : b.getSuccessors()) {
+                    writer.simpleTag(Parser.SUCCESSOR_ELEMENT, new Properties(Parser.BLOCK_NAME_PROPERTY, s.getName()));
+                }
+                writer.endTag();
             }
-            writer.endTag();
 
+            if (b.getNodes().size() > 0) {
             writer.startTag(Parser.NODES_ELEMENT);
-            for (InputNode n : b.getNodes()) {
-                writer.simpleTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, n.getId() + ""));
+                for (InputNode n : b.getNodes()) {
+                    writer.simpleTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, n.getId() + ""));
+                }
+                writer.endTag();
             }
-            writer.endTag();
 
             writer.endTag();
-
         }
 
         writer.endTag();
@@ -199,8 +222,8 @@
             b.append(" ");
             b.append(code.getName());
             b.append("\n");
+        }
 
-        }
         b.append("]]>");
         w.write(b.toString());
         w.endTag();
@@ -209,9 +232,15 @@
 
     private Properties createProperties(InputEdge edge) {
         Properties p = new Properties();
-        p.setProperty(Parser.TO_INDEX_PROPERTY, Integer.toString(edge.getToIndex()));
+        if (edge.getToIndex() != 0) {
+            p.setProperty(Parser.TO_INDEX_PROPERTY, Integer.toString(edge.getToIndex()));
+        }
+        if (edge.getFromIndex() != 0) {
+            p.setProperty(Parser.FROM_INDEX_PROPERTY, Integer.toString(edge.getFromIndex()));
+        }
         p.setProperty(Parser.TO_PROPERTY, Integer.toString(edge.getTo()));
         p.setProperty(Parser.FROM_PROPERTY, Integer.toString(edge.getFrom()));
+        p.setProperty(Parser.TYPE_PROPERTY, edge.getType());
         return p;
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLParser.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLParser.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,6 @@
  */
 package com.sun.hotspot.igv.data.serialization;
 
-import com.sun.hotspot.igv.data.Property;
 import com.sun.hotspot.igv.data.Properties;
 import java.util.HashMap;
 import java.util.Stack;
@@ -38,13 +37,6 @@
  */
 public class XMLParser implements ContentHandler {
 
-    public static interface ParseMonitor {
-
-        public void setProgress(double d);
-
-        public void setState(String state);
-    }
-
     public static class MissingAttributeException extends SAXException {
 
         private String name;
@@ -85,24 +77,25 @@
     public static class ElementHandler<T, P> {
 
         private String name;
-        private T object;
+        private Stack<T> object = new Stack<>();
         private Attributes attr;
         private StringBuilder currentText;
         private ParseMonitor monitor;
         private HashMap<String, ElementHandler<?, ? super T>> hashtable;
         private boolean needsText;
-        private ElementHandler<P, ?> parentElement;
+        private Stack<ElementHandler<P, ?>> parentElement = new Stack<>();
+        private Stack<P> parentObject = new Stack<>();
 
         public ElementHandler(String name) {
             this(name, false);
         }
 
         public ElementHandler<P, ?> getParentElement() {
-            return parentElement;
+            return parentElement.peek();
         }
 
         public P getParentObject() {
-            return getParentElement().getObject();
+            return parentObject.peek();
         }
 
         protected boolean needsText() {
@@ -110,7 +103,7 @@
         }
 
         public ElementHandler(String name, boolean needsText) {
-            this.hashtable = new HashMap<String, ElementHandler<?, ? super T>>();
+            this.hashtable = new HashMap<>();
             this.name = name;
             this.needsText = needsText;
         }
@@ -133,7 +126,7 @@
         }
 
         public T getObject() {
-            return object;
+            return object.size() == 0 ? null : object.peek();
         }
 
         public String readAttribute(String name) {
@@ -151,8 +144,8 @@
         public void processAttributesAsProperties(Properties p) {
             int length = attr.getLength();
             for (int i = 0; i < length; i++) {
-                String val = attr.getValue(i).intern();
-                String localName = attr.getLocalName(i).intern();
+                String val = attr.getValue(i);
+                String localName = attr.getLocalName(i);
                 p.setProperty(val, localName);
             }
         }
@@ -161,8 +154,9 @@
             this.currentText = new StringBuilder();
             this.attr = attr;
             this.monitor = monitor;
-            this.parentElement = parentElement;
-            object = start();
+            this.parentElement.push(parentElement);
+            parentObject.push(parentElement.getObject());
+            object.push(start());
         }
 
         protected T start() throws SAXException {
@@ -175,6 +169,9 @@
 
         public void endElement() throws SAXException {
             end(currentText.toString());
+            object.pop();
+            parentElement.pop();
+            parentObject.pop();
         }
 
         protected void text(char[] c, int start, int length) {
@@ -186,32 +183,37 @@
     private ParseMonitor monitor;
 
     public XMLParser(TopElementHandler rootHandler, ParseMonitor monitor) {
-        this.stack = new Stack<ElementHandler>();
+        this.stack = new Stack<>();
         this.monitor = monitor;
         this.stack.push(rootHandler);
     }
 
+    @Override
     public void setDocumentLocator(Locator locator) {
-        if (monitor != null) {
-            monitor.setState("Starting parsing");
-        }
+
     }
 
+    @Override
     public void startDocument() throws SAXException {
     }
 
+    @Override
     public void endDocument() throws SAXException {
     }
 
+    @Override
     public void startPrefixMapping(String prefix, String uri) throws SAXException {
     }
 
+    @Override
     public void endPrefixMapping(String prefix) throws SAXException {
     }
 
+    @SuppressWarnings("unchecked")
+    @Override
     public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+        assert !stack.isEmpty();
 
-        assert !stack.isEmpty();
         ElementHandler parent = stack.peek();
         if (parent != null) {
             ElementHandler child = parent.getChild(qName);
@@ -225,6 +227,7 @@
         stack.push(null);
     }
 
+    @Override
     public void endElement(String uri, String localName, String qName) throws SAXException {
         ElementHandler handler = stack.pop();
         if (handler != null) {
@@ -232,6 +235,7 @@
         }
     }
 
+    @Override
     public void characters(char[] ch, int start, int length) throws SAXException {
 
         assert !stack.isEmpty();
@@ -243,12 +247,15 @@
         }
     }
 
+    @Override
     public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
     }
 
+    @Override
     public void processingInstruction(String target, String data) throws SAXException {
     }
 
+    @Override
     public void skippedEntity(String name) throws SAXException {
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,7 +41,7 @@
 
     public XMLWriter(Writer inner) {
         this.inner = inner;
-        elementStack = new Stack<String>();
+        elementStack = new Stack<>();
     }
 
     @Override
@@ -49,6 +49,7 @@
         write(arr, 0, arr.length);
     }
 
+    @Override
     public void write(char[] cbuf, int off, int len) throws IOException {
         for (int i = off; i < off + len; i++) {
             char c = cbuf[i];
@@ -64,10 +65,12 @@
         }
     }
 
+    @Override
     public void flush() throws IOException {
         inner.flush();
     }
 
+    @Override
     public void close() throws IOException {
         inner.close();
     }
@@ -111,7 +114,7 @@
     }
 
     public void writeProperties(Properties props) throws IOException {
-        if (props.getProperties().hasNext() == false) {
+        if (props.iterator().hasNext() == false) {
             return;
         }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/graphdocument.xsd	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
+    
+    <xsd:element name="graphDocument">
+        <xsd:complexType>
+            <xsd:sequence>
+                <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+                <xsd:element name="group" type="groupType" minOccurs="0" maxOccurs="unbounded" />
+            </xsd:sequence>
+        </xsd:complexType>
+    </xsd:element>
+
+    <xsd:complexType name="groupType">
+        <xsd:sequence>
+            <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="assembly" type="assemblyType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="method" type="methodType" minOccurs="0" maxOccurs="1" />
+            <xsd:choice minOccurs="0" maxOccurs="unbounded" >
+                <xsd:element name="graph" type="graphType" />
+                <xsd:element name="group" type="groupType" />
+            </xsd:choice>
+        </xsd:sequence>
+        <xsd:attribute name="difference" use="optional" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="propertiesType">
+        <xsd:sequence>
+            <xsd:element name="p" minOccurs="0" maxOccurs="unbounded">
+                <xsd:complexType>
+                    <xsd:simpleContent>
+                        <xsd:extension base="xsd:string">
+                            <xsd:attribute name="name" use="required" />
+                        </xsd:extension>
+                    </xsd:simpleContent>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:sequence>
+    </xsd:complexType>
+    
+    <xsd:simpleType name="assemblyType">
+        <xsd:restriction base="xsd:string" />
+    </xsd:simpleType>
+    
+    <xsd:complexType name="methodType">
+        <xsd:all>
+            <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="bytecodes" minOccurs="0" maxOccurs="1">
+                <xsd:simpleType>
+                    <xsd:restriction base="xsd:string" />
+                </xsd:simpleType>
+            </xsd:element>
+            <xsd:element name="inlined" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="method" type="methodType" minOccurs="0" maxOccurs="unbounded" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+        </xsd:all>
+        <xsd:attribute name="bci" type="xsd:int" use="required" />
+        <xsd:attribute name="shortName" type="xsd:string" use="required" />
+        <xsd:attribute name="name" type="xsd:string" use="required" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="graphType">
+        <xsd:sequence>
+            <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+            
+            <xsd:element name="nodes" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:choice minOccurs="0" maxOccurs="unbounded">
+                            <xsd:element name="node" type="nodeType" />
+                            <xsd:element name="removeNode" type="nodeRefType" />
+                        </xsd:choice>
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            
+            <xsd:element name="edges" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:choice minOccurs="0" maxOccurs="unbounded">
+                            <xsd:element name="edge" type="edgeType" />
+                            <xsd:element name="removeEdge" type="edgeType" />
+                        </xsd:choice>
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            
+            <xsd:element name="controlFlow" type="controlFlowType" minOccurs="0" maxOccurs="1" />
+        </xsd:sequence>
+        
+        <xsd:attribute name="name" use="optional" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="nodeType">
+        <xsd:sequence>
+            <xsd:element name="properties" type="propertiesType" minOccurs="0" maxOccurs="1" />
+        </xsd:sequence>
+        <xsd:attribute name="id" type="xsd:int" use="required" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="nodeRefType">
+        <xsd:attribute name="id" type="xsd:int" use="required" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="edgeType">
+        <xsd:attribute name="from" type="xsd:int" use="required" />
+        <xsd:attribute name="to" type="xsd:int" use="required" />
+        <xsd:attribute name="label" type="xsd:string" use="optional" />
+        <xsd:attribute name="type" type="xsd:string" use="optional" />
+        <xsd:attribute name="fromIndex" type="xsd:int" use="optional" />
+        
+        <!-- These are aliases and should be mutually exclusive -->
+        <xsd:attribute name="toIndex" type="xsd:int" use="optional" />
+        <xsd:attribute name="index" type="xsd:int" use="optional" />
+    </xsd:complexType>
+    
+    <xsd:complexType name="controlFlowType">
+        <xsd:sequence>
+            <xsd:element name="block" type="blockType" minOccurs="0" maxOccurs="unbounded" />
+        </xsd:sequence>
+    </xsd:complexType>
+    
+    <xsd:complexType name="blockType">
+        <xsd:all>
+            <xsd:element name="successors" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="successor" minOccurs="0" maxOccurs="unbounded">
+                            <xsd:complexType>
+                                <xsd:attribute name="name" type="xsd:string" use="required" />
+                            </xsd:complexType>
+                        </xsd:element>
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>
+            <xsd:element name="nodes" minOccurs="0" maxOccurs="1">
+                <xsd:complexType>
+                    <xsd:sequence>
+                        <xsd:element name="node" type="nodeRefType" minOccurs="0" maxOccurs="unbounded" />
+                    </xsd:sequence>
+                </xsd:complexType>
+            </xsd:element>    
+        </xsd:all>
+        
+        <xsd:attribute name="name" type="xsd:string" use="required" />
+    </xsd:complexType>
+</xsd:schema>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GraphViewer.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GraphViewer.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -31,5 +31,5 @@
  */
 public interface GraphViewer {
 
-    public void view(InputGraph graph);
+    public void view(InputGraph graph, boolean clone);
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupCallback.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupCallback.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupOrganizer.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.data.services;
-
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.Pair;
-import java.util.List;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public interface GroupOrganizer {
-
-    public String getName();
-
-    public List<Pair<String, List<Group>>> organize(List<String> subFolders, List<Group> groups);
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupReceiver.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,35 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.data.services;
-
-import java.awt.Component;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public interface GroupReceiver {
-
-    public Component init(GroupCallback callback);
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/InputGraphProvider.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/InputGraphProvider.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/Scheduler.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/Scheduler.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/ChangedEventTest.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+import static org.junit.Assert.assertEquals;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ChangedEventTest {
+
+    public ChangedEventTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of addListener method, of class Event.
+     */
+    @Test
+    public void testBase() {
+
+        ChangedEvent<Integer> e = new ChangedEvent<>(5);
+        final int[] fireCount = new int[1];
+
+        e.addListener(new ChangedListener<Integer>() {
+            @Override
+            public void changed(Integer s) {
+                assertEquals(s.intValue(), 5);
+                fireCount[0]++;
+            }
+        });
+
+        e.fire();
+        assertEquals(1, fireCount[0]);
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.beginAtomic();
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.fire();
+        assertEquals(2, fireCount[0]);
+
+        e.endAtomic();
+        assertEquals(3, fireCount[0]);
+
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/ControllableChangedListenerTest.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+import static org.junit.Assert.*;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ControllableChangedListenerTest {
+
+    public ControllableChangedListenerTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of isEnabled method, of class ControllableChangedListener.
+     */
+    @Test
+    public void testBase() {
+
+        final boolean[] hasFired = new boolean[1];
+        final boolean[] shouldFire = new boolean[1];
+        final Integer[] valueToFire = new Integer[1];
+        ControllableChangedListener<Integer> l = new ControllableChangedListener<Integer>() {
+
+            @Override
+            public void filteredChanged(Integer value) {
+                assertTrue(shouldFire[0]);
+                assertEquals(valueToFire[0], value);
+                hasFired[0] = true;
+            }
+        };
+
+        shouldFire[0] = true;
+        valueToFire[0] = 1;
+        hasFired[0] = false;
+        l.changed(1);
+        assertTrue(hasFired[0]);
+
+        shouldFire[0] = false;
+        hasFired[0] = false;
+        l.setEnabled(false);
+        l.changed(1);
+        assertFalse(hasFired[0]);
+
+        shouldFire[0] = true;
+        valueToFire[0] = 1;
+        hasFired[0] = false;
+        l.setEnabled(true);
+        l.changed(1);
+        assertTrue(hasFired[0]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/GroupTest.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import static org.junit.Assert.assertEquals;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class GroupTest {
+
+    public GroupTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getAllNodes method, of class Group.
+     */
+    @Test
+    public void testGetAllNodes() {
+        final Group g = new Group(null);
+        final InputGraph graph1 = new InputGraph("1");
+        final InputGraph graph2 = new InputGraph("2");
+        g.addElement(graph1);
+        g.addElement(graph2);
+        graph1.addNode(new InputNode(1));
+        graph1.addNode(new InputNode(2));
+        graph2.addNode(new InputNode(2));
+        graph2.addNode(new InputNode(3));
+        assertEquals(g.getAllNodes(), new HashSet(Arrays.asList(1, 2, 3)));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/InputGraphTest.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputGraphTest {
+
+    /**
+     *    1
+     *   / \
+     *  2   3
+     *   \  |  5
+     *    \ | /
+     *      4
+     */
+    private static InputGraph referenceGraph;
+
+    private static InputGraph emptyGraph;
+
+    private static final InputNode N1 = new InputNode(1);
+    private static final InputNode N2 = new InputNode(2);
+    private static final InputNode N3 = new InputNode(3);
+    private static final InputNode N4 = new InputNode(4);
+    private static final InputNode N5 = new InputNode(5);
+    private static final InputEdge E12 = new InputEdge((char)0, 1, 2);
+    private static final InputEdge E13 = new InputEdge((char)0, 1, 3);
+    private static final InputEdge E24 = new InputEdge((char)0, 2, 4);
+    private static final InputEdge E34 = new InputEdge((char)0, 3, 4);
+    private static final InputEdge E54 = new InputEdge((char)0, 5, 4);
+
+    public InputGraphTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+        Group group = new Group(null);
+
+        emptyGraph = new InputGraph("emptyGraph");
+        group.addElement(emptyGraph);
+
+        referenceGraph = new InputGraph("referenceGraph");
+        group.addElement(referenceGraph);
+        referenceGraph.addNode(N1);
+        referenceGraph.addNode(N2);
+        referenceGraph.addNode(N3);
+        referenceGraph.addNode(N4);
+        referenceGraph.addNode(N5);
+
+        referenceGraph.addEdge(E12);
+        referenceGraph.addEdge(E13);
+        referenceGraph.addEdge(E24);
+        referenceGraph.addEdge(E34);
+        referenceGraph.addEdge(E54);
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of equals method, of class InputGraph.
+     */
+    @Test
+    public void testEquals() {
+
+        Group parentA = new Group(null);
+        InputGraph a = new InputGraph("graph");
+        parentA.addElement(a);
+
+        Group parentB = new Group(null);
+        InputGraph b = new InputGraph("graph");
+        parentB.addElement(b);
+
+        InputGraph c = new InputGraph("graph");
+        parentB.addElement(b);
+
+        Util.assertGraphEquals(a, b);
+        Util.assertGraphEquals(b, c);
+
+        a.addNode(new InputNode(1));
+        Util.assertGraphNotEquals(a, b);
+
+        b.addNode(new InputNode(1));
+        Util.assertGraphEquals(a, b);
+    }
+
+    /**
+     * Test of findRootNodes method, of class InputGraph.
+     */
+    @Test
+    public void testFindRootNodes() {
+        assertTrue(emptyGraph.findRootNodes().isEmpty());
+
+        List<InputNode> result = referenceGraph.findRootNodes();
+        assertTrue(result.size() == 2);
+        assertTrue(result.contains(N1));
+        assertTrue(result.contains(N5));
+    }
+
+    /**
+     * Test of findAllOutgoingEdges method, of class InputGraph.
+     */
+    @Test
+    public void testFindAllOutgoingEdges() {
+        assertTrue(emptyGraph.findAllOutgoingEdges().isEmpty());
+
+        Map<InputNode, List<InputEdge>> result = referenceGraph.findAllOutgoingEdges();
+        assertTrue(result.size() == 5);
+        assertEquals(result.get(N1), Arrays.asList(E12, E13));
+        assertEquals(result.get(N2), Arrays.asList(E24));
+        assertEquals(result.get(N3), Arrays.asList(E34));
+        assertEquals(result.get(N4), Arrays.asList());
+        assertEquals(result.get(N5), Arrays.asList(E54));
+    }
+
+    /**
+     * Test of findAllIngoingEdges method, of class InputGraph.
+     */
+    @Test
+    public void testFindAllIngoingEdges() {
+        assertTrue(emptyGraph.findAllIngoingEdges().isEmpty());
+
+        Map<InputNode, List<InputEdge>> result = referenceGraph.findAllIngoingEdges();
+        assertTrue(result.size() == 5);
+        assertEquals(result.get(N1), Arrays.asList());
+        assertEquals(result.get(N2), Arrays.asList(E12));
+        assertEquals(result.get(N3), Arrays.asList(E13));
+        assertEquals(result.get(N4), Arrays.asList(E24, E34, E54));
+        assertEquals(result.get(N5), Arrays.asList());
+    }
+
+    /**
+     * Test of findOutgoingEdges method, of class InputGraph.
+     */
+    @Test
+    public void testFindOutgoingEdges() {
+        assertTrue(emptyGraph.findOutgoingEdges(new InputNode(1)).isEmpty());
+
+        assertEquals(referenceGraph.findOutgoingEdges(N1), Arrays.asList(E12, E13));
+        assertEquals(referenceGraph.findOutgoingEdges(N2), Arrays.asList(E24));
+        assertEquals(referenceGraph.findOutgoingEdges(N3), Arrays.asList(E34));
+        assertEquals(referenceGraph.findOutgoingEdges(N4), Arrays.asList());
+        assertEquals(referenceGraph.findOutgoingEdges(N5), Arrays.asList(E54));
+    }
+
+    /**
+     * Test of getNext method, of class InputGraph.
+     */
+    @Test
+    public void testGetNextPrev() {
+        final Group group = new Group(null);
+
+        final InputGraph a = new InputGraph("a");
+
+        final InputGraph b = new InputGraph("b");
+
+        final InputGraph c = new InputGraph("c");
+        group.addElement(a);
+        group.addElement(b);
+        group.addElement(c);
+
+        assertEquals(null, a.getPrev());
+        assertEquals(b, a.getNext());
+
+        assertEquals(a, b.getPrev());
+        assertEquals(c, b.getNext());
+
+        assertEquals(b, c.getPrev());
+        assertEquals(null, c.getNext());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/InputMethodTest.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertThat;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas
+ */
+public class InputMethodTest {
+
+    public InputMethodTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+
+    /**
+     * Test of getBytecodes method, of class InputMethod.
+     */
+    @Test
+    public void testGetSetBytecodes() {
+
+        final String input = "0 iload_0\n" +
+                             "1 iconst_1\n" +
+                             "2 if_icmpne 7\n" +
+                             "5 iconst_1\n" +
+                             "6 ireturn\n" +
+                             "7 iconst_0\n" +
+                             "8 ireturn";
+
+        final Group g = new Group(null);
+        InputMethod m = new InputMethod(g, "name", "shortName", -1);
+        m.setBytecodes(input);
+
+        assertThat(m.getBytecodes().size(), is(7));
+
+        assertThat(m.getBytecodes().get(0).getBci(), is(0));
+        assertThat(m.getBytecodes().get(1).getBci(), is(1));
+        assertThat(m.getBytecodes().get(2).getBci(), is(2));
+        assertThat(m.getBytecodes().get(3).getBci(), is(5));
+
+        assertThat(m.getBytecodes().get(0).getName(), is("iload_0"));
+        assertThat(m.getBytecodes().get(1).getName(), is("iconst_1"));
+        assertThat(m.getBytecodes().get(2).getName(), is("if_icmpne 7"));
+        assertThat(m.getBytecodes().get(6).getName(), is("ireturn"));
+
+        assertThat(m.getBytecodes().get(2).getInlined(), nullValue());
+        assertThat(m.getBytecodes().get(6).getInlined(), nullValue());
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/PairTest.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.hotspot.igv.data;
+
+import static org.junit.Assert.*;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PairTest {
+
+    public PairTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getLeft method, of class Pair.
+     */
+    @Test
+    public void testBase() {
+        Pair p = new Pair();
+        assertTrue(p.getLeft() == null);
+        assertTrue(p.getRight() == null);
+        assertEquals("[null/null]", p.toString());
+        assertFalse(p.equals(null));
+
+        Pair<Integer, Integer> p2 = new Pair(1, 2);
+        assertTrue(p2.getLeft().intValue() == 1);
+        assertTrue(p2.getRight().intValue() == 2);
+        assertFalse(p.equals(p2));
+        assertFalse(p2.equals(p));
+        assertFalse(p.hashCode() == p2.hashCode());
+        assertEquals("[1/2]", p2.toString());
+
+        Pair p3 = new Pair(1, 2);
+        assertTrue(p2.equals(p3));
+        assertTrue(p2.hashCode() == p3.hashCode());
+
+        p2.setLeft(2);
+        assertFalse(p2.equals(p3));
+        assertTrue(p2.getLeft().intValue() == 2);
+        assertTrue(p2.getRight().intValue() == 2);
+        assertFalse(p2.hashCode() == p3.hashCode());
+        assertEquals("[2/2]", p2.toString());
+
+        p2.setRight(1);
+        assertFalse(p2.equals(p3));
+        assertTrue(p2.getLeft().intValue() == 2);
+        assertTrue(p2.getRight().intValue() == 1);
+        assertFalse(p2.hashCode() == p3.hashCode());
+        assertEquals("[2/1]", p2.toString());
+
+        p3.setLeft(2);
+        p3.setRight(1);
+        assertTrue(p2.hashCode() == p3.hashCode());
+        assertTrue(p2.equals(p3));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/PropertiesTest.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,401 @@
+/*
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.hotspot.igv.data;
+
+import com.sun.hotspot.igv.data.Properties.InvertPropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.PropertySelector;
+import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
+import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import junit.framework.TestCase;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PropertiesTest extends TestCase {
+
+
+
+    public PropertiesTest(String testName) {
+        super(testName);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        super.setUp();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+    }
+
+    /**
+     * Test of equals method, of class Properties.
+     */
+    public void testEquals() {
+        Properties a = new Properties();
+        assertFalse(a.equals(null));
+        assertTrue(a.equals(a));
+
+        Properties b = new Properties();
+        assertTrue(a.equals(b));
+        assertTrue(a.hashCode() == b.hashCode());
+
+        a.setProperty("p1", "1");
+        assertFalse(a.equals(b));
+        assertFalse(b.equals(a));
+        assertFalse(a.hashCode() == b.hashCode());
+
+        b.setProperty("p1", "1");
+        assertTrue(a.equals(b));
+        assertTrue(a.hashCode() == b.hashCode());
+
+        Properties c = new Properties(a);
+        assertTrue(c.equals(a));
+        assertTrue(c.equals(b));
+
+        c.setProperty("p1", "2");
+        assertFalse(c.equals(b));
+        assertFalse(c.hashCode() == b.hashCode());
+        assertFalse(c.equals(a));
+        assertFalse(c.hashCode() == a.hashCode());
+
+        a.setProperty("p2", "2");
+        Properties d = new Properties();
+        d.setProperty("p2", "2");
+        d.setProperty("p1", "1");
+        assertTrue(d.equals(a));
+    }
+
+    /**
+     * Test of selectSingle method, of class Properties.
+     */
+    public void testSelectSingle() {
+
+        final boolean[] called = new boolean[1];
+        final String v = "2";
+        final String n = "p2";
+
+        PropertyMatcher matcher = new PropertyMatcher() {
+
+            @Override
+            public String getName() {
+                assertFalse(called[0]);
+                called[0] = true;
+                return n;
+            }
+
+            @Override
+            public boolean match(String value) {
+                assertTrue(v.equals(value));
+                return true;
+            }
+        };
+
+        Properties instance = new Properties();
+        instance.setProperty("p1", "1");
+        instance.setProperty(n, v);
+        instance.setProperty("p3", "3");
+        Property result = instance.selectSingle(matcher);
+        assertEquals(result, new Property(n, v));
+
+
+        called[0] = false;
+        PropertyMatcher matcher2 = new PropertyMatcher() {
+
+            @Override
+            public String getName() {
+                assertFalse(called[0]);
+                called[0] = true;
+                return n;
+            }
+
+            @Override
+            public boolean match(String value) {
+                return false;
+            }
+        };
+
+
+        Property result2 = instance.selectSingle(matcher2);
+        assertTrue(result2 == null);
+    }
+
+    /**
+     * Test of get method, of class Properties.
+     */
+    public void testGet() {
+        Properties instance = new Properties();
+        instance.setProperty("p1", "1");
+        assertEquals("1", instance.get("p1"));
+        assertEquals(null, instance.get("p2"));
+    }
+
+    /**
+     * Test of getProperties method, of class Properties.
+     */
+    public void testIterator() {
+        Properties instance = new Properties();
+        instance.setProperty("p1", "1");
+        instance.setProperty("p2", "2");
+        Iterator<Property> result = instance.iterator();
+        assertTrue(result.hasNext());
+        assertEquals(new Property("p1", "1"), result.next());
+        assertTrue(result.hasNext());
+        assertEquals(new Property("p2", "2"), result.next());
+        assertFalse(result.hasNext());
+        assertTrue(result.next() == null);
+
+        try {
+            result.remove();
+            fail();
+        } catch(UnsupportedOperationException e) {}
+    }
+
+    /**
+     * Test of add method, of class Properties.
+     */
+    public void testAdd() {
+        Properties a = new Properties();
+        a.setProperty("p1", "1");
+        a.setProperty("p2", "2");
+
+        Properties b = new Properties();
+        b.setProperty("p1", "1");
+
+        Properties c = new Properties();
+        c.setProperty("p2", "2");
+
+        assertFalse(a.equals(b));
+        b.add(c);
+
+        assertTrue(a.equals(b));
+
+        b.setProperty("p3", null);
+        assertTrue(a.equals(b));
+
+        Properties empty = new Properties();
+        b.add(empty);
+        assertTrue(a.equals(b));
+
+        empty.add(b);
+        assertTrue(a.equals(empty));
+    }
+
+
+    /**
+     * Test the multiple argument constructors.
+     */
+    public void testConstructors() {
+        Properties a = new Properties("p1", "1", "p2", "2", "p3", "3");
+        Properties b = new Properties("p1", "1", "p2", "2");
+        Properties c = new Properties("p1", "1");
+
+        assertTrue(a.get("p3").equals("3"));
+        assertTrue(b.get("p2").equals("2"));
+        assertTrue(b.get("p1").equals("1"));
+
+        b.setProperty("p3", "3");
+        c.setProperty("p2", "2");
+        c.setProperty("p3", "3");
+
+        assertTrue(a.equals(b));
+        assertTrue(a.equals(c));
+    }
+
+    /**
+     * Test Entity class
+     */
+    public void testEntity() {
+
+        Properties p = new Properties();
+
+        Properties.Entity entity = new Properties.Entity();
+        assertEquals(entity.getProperties(), p);
+
+        entity.getProperties().setProperty("p1", "1");
+        Properties.Entity entity2 = new Properties.Entity(entity);
+        assertEquals(entity.getProperties(), entity2.getProperties());
+    }
+
+    /**
+     * Test property selector
+     */
+    public void testPropertySelector() {
+        final Collection<Properties.Entity> c = new ArrayList<>();
+
+        final Properties.Entity e1 = new Properties.Entity();
+        e1.getProperties().setProperty("p1", "1");
+        e1.getProperties().setProperty("p2", "2");
+        c.add(e1);
+
+        final Properties.Entity e2 = new Properties.Entity();
+        e2.getProperties().setProperty("p2", "2");
+        e2.getProperties().setProperty("p1", "1");
+        e2.getProperties().setProperty("p3", "3");
+        c.add(e2);
+
+        final Properties.Entity e3 = new Properties.Entity();
+        e3.getProperties().setProperty("p3", "3");
+        e3.getProperties().setProperty("p4", "4");
+        c.add(e3);
+
+        final PropertySelector<Properties.Entity> sel = new PropertySelector<>(c);
+
+        final StringPropertyMatcher matcher1 = new StringPropertyMatcher("p2", "2");
+        assertTrue(sel.selectMultiple(matcher1).size() == 2);
+        assertTrue(sel.selectMultiple(matcher1).contains(e1));
+        assertTrue(sel.selectMultiple(matcher1).contains(e2));
+        assertTrue(sel.selectSingle(matcher1).equals(e1) || sel.selectSingle(matcher1).equals(e2));
+
+        final StringPropertyMatcher matcher2 = new StringPropertyMatcher("p3", "3");
+        assertTrue(sel.selectMultiple(matcher2).size() == 2);
+        assertTrue(sel.selectMultiple(matcher2).contains(e2));
+        assertTrue(sel.selectMultiple(matcher2).contains(e3));
+        assertTrue(sel.selectSingle(matcher2).equals(e2) || sel.selectSingle(matcher2).equals(e3));
+
+        final StringPropertyMatcher matcher3 = new StringPropertyMatcher("p4", "4");
+        assertTrue(sel.selectMultiple(matcher3).size() == 1);
+        assertTrue(sel.selectMultiple(matcher3).contains(e3));
+        assertTrue(sel.selectSingle(matcher3).equals(e3));
+
+        final StringPropertyMatcher matcher4 = new StringPropertyMatcher("p5", "5");
+        assertTrue(sel.selectMultiple(matcher4).size() == 0);
+        assertTrue(sel.selectSingle(matcher4) == null);
+    }
+
+    public void testRemoveProperty() {
+        final Properties p = new Properties();
+        p.setProperty("p1", "1");
+        p.setProperty("p2", "2");
+
+        assertTrue(p.get("p1").equals("1"));
+        assertTrue(p.get("p2").equals("2"));
+
+        p.setProperty("p1", null);
+        assertTrue(p.get("p1") == null);
+        assertTrue(p.get("p2").equals("2"));
+
+        p.setProperty("p2", null);
+        assertTrue(p.get("p1") == null);
+        assertTrue(p.get("p2") == null);
+
+        p.setProperty("p3", "3");
+        assertTrue(p.get("p1") == null);
+        assertTrue(p.get("p2") == null);
+        assertTrue(p.get("p3").equals("3"));
+    }
+
+    /**
+     * Test property matchers
+     */
+    public void testPropertyMatchers() {
+        final StringPropertyMatcher matcher = new StringPropertyMatcher("p1", "1");
+        assertTrue(matcher.getName().equals("p1"));
+        assertTrue(matcher.match("1"));
+        assertFalse(matcher.match("2"));
+        try {
+            matcher.match(null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new StringPropertyMatcher(null, "**");
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new StringPropertyMatcher("p1", null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        final RegexpPropertyMatcher matcher2 = new RegexpPropertyMatcher("p1", "C.*");
+        assertTrue(matcher2.getName().equals("p1"));
+        assertTrue(matcher2.match("C"));
+        assertTrue(matcher2.match("Casdf"));
+        assertFalse(matcher2.match(" C"));
+        assertFalse(matcher2.match("c"));
+        assertFalse(matcher2.match("asdfC"));
+
+        try {
+            matcher2.match(null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new RegexpPropertyMatcher("p1", "**");
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new RegexpPropertyMatcher(null, "1");
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        try {
+            new RegexpPropertyMatcher("p1", null);
+            fail();
+        } catch(IllegalArgumentException e) {}
+
+        final InvertPropertyMatcher matcher3 = new InvertPropertyMatcher(matcher);
+        assertTrue(matcher3.getName().equals("p1"));
+        assertFalse(matcher3.match("1"));
+        assertTrue(matcher3.match("2"));
+        assertFalse(matcher3.match(null));
+    }
+
+    public void testToString() {
+        Properties p = new Properties();
+        assertEquals(p.toString(), "[]");
+
+        p.setProperty("p1", "1");
+        assertEquals(p.toString(), "[p1=1]");
+
+        Properties p2 = new Properties();
+        p2.setProperty("p1", "1");
+        p2.setProperty("p2", "2");
+        assertEquals(p2.toString(), "[p1=1, p2=2]");
+
+        Properties p3 = new Properties();
+        p3.setProperty("p2", "2");
+        p3.setProperty("p1", "1");
+        assertEquals(p3.toString(), "[p1=1, p2=2]");
+
+        p3.setProperty("p0", "0");
+        assertEquals(p3.toString(), "[p0=0, p1=1, p2=2]");
+
+        p2.setProperty("p1", null);
+        assertEquals(p2.toString(), "[p2=2]");
+
+        p2.setProperty("p2", null);
+        assertEquals(p2.toString(), "[]");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/PropertyTest.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.hotspot.igv.data;
+
+import static org.junit.Assert.*;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PropertyTest {
+
+    public PropertyTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getName method, of class Property.
+     */
+    @Test
+    public void testGetNameAndValue() {
+        final Property p = new Property("name", "value");
+        assertEquals(p.getName(), "name");
+        assertEquals(p.getValue(), "value");
+
+        try {
+            new Property(null, "value");
+            fail();
+        } catch(IllegalArgumentException e) {
+        }
+
+
+        try {
+            new Property("name", null);
+            fail();
+        } catch(IllegalArgumentException e) {
+        }
+    }
+
+    /**
+     * Test of toString method, of class Property.
+     */
+    @Test
+    public void testToString() {
+        final Property p = new Property("name", "value");
+        assertEquals(p.toString(), "name=value");
+    }
+
+    /**
+     * Test of equals method, of class Property.
+     */
+    @Test
+    public void testEquals() {
+        final Property p = new Property("name", "value");
+        final Object o = new Object();
+        assertFalse(p.equals(o));
+        assertFalse(p.equals(null));
+        assertTrue(p.equals(p));
+
+        final Property p2 = new Property("name", "value1");
+        assertFalse(p.equals(p2));
+        assertTrue(p.hashCode() != p2.hashCode());
+
+        final Property p3 = new Property("name2", "value");
+        assertFalse(p.equals(p3));
+        assertTrue(p.hashCode() != p3.hashCode());
+        assertTrue(p2.hashCode() != p3.hashCode());
+
+        final Property p4 = new Property("name", "value");
+        assertEquals(p, p4);
+        assertEquals(p.hashCode(), p4.hashCode());
+
+        final Property p5 = new Property("value", "name");
+        assertFalse(p.equals(p5));
+        assertTrue(p.hashCode() != p5.hashCode());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/SourceTest.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.data;
+
+import java.util.Arrays;
+import java.util.LinkedHashSet;
+import static org.junit.Assert.assertEquals;
+import org.junit.*;
+
+/**
+ *
+ * @author Thomas
+ */
+public class SourceTest {
+
+    public SourceTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    /**
+     * Test of getSourceNodes method, of class Source.
+     */
+    @Test
+    public void testBase() {
+        final Source s = new Source();
+
+        final InputNode N1 = new InputNode(1);
+        final InputNode N2 = new InputNode(2);
+
+        s.addSourceNode(N1);
+        assertEquals(s.getSourceNodes(), Arrays.asList(N1));
+        assertEquals(s.getSourceNodesAsSet(), new LinkedHashSet<>(Arrays.asList(1)));
+
+        s.addSourceNode(N2);
+        assertEquals(s.getSourceNodes(), Arrays.asList(N1, N2));
+        assertEquals(s.getSourceNodesAsSet(), new LinkedHashSet<>(Arrays.asList(1, 2)));
+
+        s.addSourceNode(N1);
+        assertEquals(s.getSourceNodes(), Arrays.asList(N1, N2));
+        assertEquals(s.getSourceNodesAsSet(), new LinkedHashSet<>(Arrays.asList(1, 2)));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/Util.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.hotspot.igv.data;
+
+import static org.junit.Assert.*;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Util {
+
+    public static void assertGraphDocumentNotEquals(GraphDocument a, GraphDocument b) {
+        try {
+            assertGraphDocumentEquals(a, b);
+        } catch(AssertionError e) {
+            return;
+        }
+
+        fail("Graphs documents are equal!");
+    }
+
+    public static void assertGraphDocumentEquals(GraphDocument a, GraphDocument b) {
+
+        if (a.getElements().size() != b.getElements().size()) {
+            fail();
+        }
+
+        int z = 0;
+        for (FolderElement e : b.getElements()) {
+
+            if (e instanceof Group) {
+                Group g = (Group) e;
+                Group thisG = (Group) a.getElements().get(z);
+                assertGroupEquals(thisG, g);
+            z++;
+            }
+        }
+    }
+
+    public static void assertGroupNotEquals(Group a, Group b) {
+        try {
+            assertGroupEquals(a, b);
+        } catch(AssertionError e) {
+            return;
+        }
+
+        fail("Groups are equal!");
+    }
+
+    public static void assertGroupEquals(Group a, Group b) {
+
+        if (a.getGraphsCount() != b.getGraphsCount()) {
+            fail();
+        }
+
+        int z = 0;
+        for (InputGraph graph : a.getGraphs()) {
+            InputGraph otherGraph = b.getGraphs().get(z);
+            assertGraphEquals(graph, otherGraph);
+            z++;
+        }
+
+        if (a.getMethod() == null || b.getMethod() == null) {
+            if (a.getMethod() != b.getMethod()) {
+                fail();
+            }
+        } else {
+            if (!a.getMethod().equals(b.getMethod())) {
+                fail();
+            }
+        }
+    }
+
+    public static void assertGraphNotEquals(InputGraph a, InputGraph b) {
+        try {
+            assertGraphEquals(a, b);
+        } catch(AssertionError e) {
+            return;
+        }
+
+        fail("Graphs are equal!");
+    }
+
+    public static void assertGraphEquals(InputGraph a, InputGraph b) {
+
+        if(!a.getNodesAsSet().equals(b.getNodesAsSet())) {
+            fail();
+        }
+
+        if (!a.getEdges().equals(b.getEdges())) {
+            fail();
+        }
+
+        if (a.getBlocks().equals(b.getBlocks())) {
+            fail();
+        }
+
+        for (InputNode n : a.getNodes()) {
+            assertEquals(a.getBlock(n), b.getBlock(n));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/test/unit/src/com/sun/hotspot/igv/data/serialization/ParserTest.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,225 @@
+/*
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package com.sun.hotspot.igv.data.serialization;
+
+import com.sun.hotspot.igv.data.*;
+import java.io.*;
+import java.nio.channels.Channels;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import org.junit.*;
+import org.openide.util.Exceptions;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ParserTest {
+
+    public ParserTest() {
+    }
+
+    @BeforeClass
+    public static void setUpClass() throws Exception {
+    }
+
+    @AfterClass
+    public static void tearDownClass() throws Exception {
+    }
+
+    @Before
+    public void setUp() {
+    }
+
+    @After
+    public void tearDown() {
+    }
+
+    private void test(GraphDocument document) {
+        final Printer printer = new Printer();
+        final CharArrayWriter writer = new CharArrayWriter();
+        printer.export(writer, document);
+        test(document, writer.toString());
+    }
+
+    private void test(GraphDocument document, String xmlString) {
+        try {
+            InputStream in = new ByteArrayInputStream(xmlString.getBytes("UTF-8"));
+            try {
+                Parser parser = new Parser(Channels.newChannel(in));
+                final GraphDocument parsedDocument = parser.parse();
+                Util.assertGraphDocumentEquals(document, parsedDocument);
+            } catch (SAXException ex) {
+                fail(ex.toString());
+            }
+        } catch (UnsupportedEncodingException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+    }
+
+    private void testBoth(GraphDocument document, String xmlString) {
+        test(document);
+        test(document, xmlString);
+    }
+
+    /**
+     * Test of graph document serialization
+     */
+    @Test
+    public void testSerialization() {
+        final GraphDocument doc = new GraphDocument();
+
+        test(doc);
+
+        final Group group1 = new Group(doc);
+        doc.addElement(group1);
+        test(doc);
+
+        final Group group2 = new Group(doc);
+        doc.addElement(group2);
+        test(doc);
+
+        final InputGraph graph = new InputGraph("");
+        group1.addElement(graph);
+        test(doc);
+
+        graph.addNode(new InputNode(0));
+        test(doc);
+
+        graph.addNode(new InputNode(1));
+        test(doc);
+
+        graph.addNode(new InputNode(2));
+        test(doc);
+
+        graph.addNode(new InputNode(3));
+        test(doc);
+
+        graph.addEdge(new InputEdge((char)0, (char)0, 0, 1));
+        test(doc);
+
+        graph.addEdge(new InputEdge((char)1, (char)1, 0, 1));
+        test(doc);
+
+        graph.addEdge(new InputEdge((char)0, (char)0, 1, 2));
+        test(doc);
+
+        graph.addEdge(new InputEdge((char)0, (char)0, 2, 3));
+        test(doc);
+
+        group1.setMethod(new InputMethod(group1, "testMethod", "tM", 1));
+        test(doc);
+
+        final InputBlock b1 = graph.addBlock("1");
+        b1.addNode(0);
+        b1.addNode(1);
+
+        final InputBlock b2 = graph.addBlock("2");
+        b2.addNode(2);
+        b2.addNode(3);
+        test(doc);
+
+        final GraphDocument document2 = new GraphDocument();
+        doc.addGraphDocument(document2);
+        test(doc);
+        assertTrue(doc.getElements().size() == 2);
+
+        final Group group3 = new Group(document2);
+        document2.addElement(group3);
+        doc.addGraphDocument(document2);
+        assertTrue(doc.getElements().size() == 3);
+        assertTrue(document2.getElements().size() == 0);
+
+        doc.clear();
+        test(doc);
+        Util.assertGraphDocumentEquals(doc, new GraphDocument());
+    }
+
+    @Test
+    public void testSimpleExport() {
+        GraphDocument document = new GraphDocument();
+        Group g = new Group(document);
+        document.addElement(g);
+
+        InputGraph graph = new InputGraph("TestGraph");
+                g.addElement(graph);
+        graph.getProperties().setProperty("testName", "testValue");
+
+        InputNode n1 = new InputNode(0);
+        InputNode n2 = new InputNode(1);
+        InputEdge e1 = new InputEdge((char)0, 0, 1);
+        InputEdge e2 = new InputEdge((char)1, 0, 1);
+        graph.addNode(n1);
+        graph.addNode(n2);
+        graph.addEdge(e1);
+        graph.addEdge(e2);
+
+        test(document);
+    }
+
+    @Test
+    public void testComplexExport() {
+
+        GraphDocument document = new GraphDocument();
+        Group g = new Group(document);
+        document.addElement(g);
+
+        InputGraph graph = new InputGraph("TestGraph");
+                g.addElement(graph);
+        graph.getProperties().setProperty("testName", "testValue");
+
+        InputNode n1 = new InputNode(0);
+        InputNode n2 = new InputNode(1);
+        InputEdge e1 = new InputEdge((char)0, 0, 0);
+        InputEdge e2 = new InputEdge((char)1, 1, 1);
+        graph.addNode(n1);
+        graph.addNode(n2);
+        graph.addEdge(e1);
+        graph.addEdge(e2);
+
+        InputGraph graph2 = new InputGraph("TestGraph2");
+                g.addElement(graph2);
+        graph2.addNode(n1);
+        InputNode n3 = new InputNode(2);
+        graph2.addNode(n3);
+        InputEdge e3 = new InputEdge((char)0, 0, 2);
+        graph2.addEdge(e3);
+
+        test(document);
+    }
+
+
+    /**
+     * Test of parse method, of class Parser.
+     */
+    @Test
+    public void testParse() {
+        testBoth(new GraphDocument(), "<graphDocument></graphDocument>");
+    }
+
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -14,6 +14,14 @@
                         <specification-version>1.0</specification-version>
                     </run-dependency>
                 </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
+                    </run-dependency>
+                </dependency>
             </module-dependencies>
             <public-packages>
                 <package>com.sun.hotspot.igv.difference</package>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,16 +24,11 @@
  */
 package com.sun.hotspot.igv.difference;
 
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.InputEdge;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.InputNode;
-import com.sun.hotspot.igv.data.Property;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.*;
+import com.sun.hotspot.igv.data.services.Scheduler;
+import java.util.*;
+import org.openide.util.Lookup;
 
 /**
  *
@@ -46,7 +41,7 @@
     public static final String VALUE_CHANGED = "changed";
     public static final String VALUE_SAME = "same";
     public static final String VALUE_DELETED = "deleted";
-    public static final String OLD_PREFIX = "OLD_";
+    public static final String NEW_PREFIX = "NEW_";
     public static final String MAIN_PROPERTY = "name";
     public static final double LIMIT = 100.0;
     public static final String[] IGNORE_PROPERTIES = new String[]{"idx", "debug_idx"};
@@ -60,14 +55,14 @@
     }
 
     private static InputGraph createDiffSameGroup(InputGraph a, InputGraph b) {
-        Map<Integer, InputNode> keyMapB = new HashMap<Integer, InputNode>();
+        Map<Integer, InputNode> keyMapB = new HashMap<>(b.getNodes().size());
         for (InputNode n : b.getNodes()) {
             Integer key = n.getId();
             assert !keyMapB.containsKey(key);
             keyMapB.put(key, n);
         }
 
-        Set<Pair> pairs = new HashSet<Pair>();
+        Set<NodePair> pairs = new HashSet<>();
 
         for (InputNode n : a.getNodes()) {
             Integer key = n.getId();
@@ -75,30 +70,92 @@
 
             if (keyMapB.containsKey(key)) {
                 InputNode nB = keyMapB.get(key);
-                pairs.add(new Pair(n, nB));
+                pairs.add(new NodePair(n, nB));
             }
         }
 
         return createDiff(a, b, pairs);
     }
 
-    private static InputGraph createDiff(InputGraph a, InputGraph b, Set<Pair> pairs) {
-        Group g = new Group();
+    private static void ensureScheduled(InputGraph a) {
+        if (a.getBlocks().isEmpty()) {
+            Scheduler s = Lookup.getDefault().lookup(Scheduler.class);
+            a.clearBlocks();
+            s.schedule(a);
+            a.ensureNodesInBlocks();
+        }
+    }
+
+    private static InputGraph createDiff(InputGraph a, InputGraph b, Set<NodePair> pairs) {
+        ensureScheduled(a);
+        ensureScheduled(b);
+
+        Group g = new Group(null);
         g.setMethod(a.getGroup().getMethod());
-        g.setAssembly(a.getGroup().getAssembly());
+        if (a.getGroup() == b.getGroup()) {
+            g.getProperties().add(a.getGroup().getProperties());
+        } else {
+            // copy properties that have the same value in both groups
+            Properties bps = b.getGroup().getProperties();
+            for (Property p : a.getGroup().getProperties()) {
+                String value = p.getValue();
+                if (value != null && value.equals(bps.get(p.getName()))) {
+                    g.getProperties().setProperty(p.getName(), value);
+                }
+            }
+        }
         g.getProperties().setProperty("name", "Difference");
-        InputGraph graph = new InputGraph(g, null);
-        graph.setName(a.getName() + ", " + b.getName());
-        graph.setIsDifferenceGraph(true);
+        InputGraph graph = new InputGraph(a.getName() + ", " + b.getName());
+        g.addElement(graph);
 
-        Set<InputNode> nodesA = new HashSet<InputNode>(a.getNodes());
-        Set<InputNode> nodesB = new HashSet<InputNode>(b.getNodes());
+        Map<InputBlock, InputBlock> blocksMap = new HashMap<>();
+        for (InputBlock blk : a.getBlocks()) {
+            InputBlock diffblk = graph.addBlock(blk.getName());
+            blocksMap.put(blk, diffblk);
+        }
+        for (InputBlock blk : b.getBlocks()) {
+            InputBlock diffblk = graph.getBlock(blk.getName());
+            if (diffblk == null) {
+                diffblk = graph.addBlock(blk.getName());
+            }
+            blocksMap.put(blk, diffblk);
+        }
 
-        Map<InputNode, InputNode> inputNodeMap = new HashMap<InputNode, InputNode>();
-        for (Pair p : pairs) {
-            InputNode n = p.getN1();
+        // Difference between block edges
+        Set<Pair<String, String>> aEdges = new HashSet<>();
+        for (InputBlockEdge edge : a.getBlockEdges()) {
+            aEdges.add(new Pair<>(edge.getFrom().getName(), edge.getTo().getName()));
+        }
+        for (InputBlockEdge bEdge : b.getBlockEdges()) {
+            InputBlock from = bEdge.getFrom();
+            InputBlock to = bEdge.getTo();
+            Pair<String, String> pair = new Pair<>(from.getName(), to.getName());
+            if (aEdges.contains(pair)) {
+                // same
+                graph.addBlockEdge(blocksMap.get(from), blocksMap.get(to));
+                aEdges.remove(pair);
+            } else {
+                // added
+                InputBlockEdge edge = graph.addBlockEdge(blocksMap.get(from), blocksMap.get(to));
+                edge.setState(InputBlockEdge.State.NEW);
+            }
+        }
+        for (Pair<String, String> deleted : aEdges) {
+            // removed
+            InputBlock from = graph.getBlock(deleted.getLeft());
+            InputBlock to = graph.getBlock(deleted.getRight());
+            InputBlockEdge edge = graph.addBlockEdge(from, to);
+            edge.setState(InputBlockEdge.State.DELETED);
+        }
+
+        Set<InputNode> nodesA = new HashSet<>(a.getNodes());
+        Set<InputNode> nodesB = new HashSet<>(b.getNodes());
+
+        Map<InputNode, InputNode> inputNodeMap = new HashMap<>(pairs.size());
+        for (NodePair p : pairs) {
+            InputNode n = p.getLeft();
             assert nodesA.contains(n);
-            InputNode nB = p.getN2();
+            InputNode nB = p.getRight();
             assert nodesB.contains(nB);
 
             nodesA.remove(n);
@@ -107,41 +164,59 @@
             inputNodeMap.put(n, n2);
             inputNodeMap.put(nB, n2);
             graph.addNode(n2);
+            InputBlock block = blocksMap.get(a.getBlock(n));
+            block.addNode(n2.getId());
             markAsChanged(n2, n, nB);
         }
 
         for (InputNode n : nodesA) {
             InputNode n2 = new InputNode(n);
             graph.addNode(n2);
-            markAsNew(n2);
+            InputBlock block = blocksMap.get(a.getBlock(n));
+            block.addNode(n2.getId());
+            markAsDeleted(n2);
             inputNodeMap.put(n, n2);
         }
 
+        int curIndex = 0;
         for (InputNode n : nodesB) {
             InputNode n2 = new InputNode(n);
-            n2.setId(-n2.getId());
+
+            // Find new ID for node of b, does not change the id property
+            while (graph.getNode(curIndex) != null) {
+                curIndex++;
+            }
+
+            n2.setId(curIndex);
             graph.addNode(n2);
-            markAsDeleted(n2);
+            InputBlock block = blocksMap.get(b.getBlock(n));
+            block.addNode(n2.getId());
+            markAsNew(n2);
             inputNodeMap.put(n, n2);
         }
 
         Collection<InputEdge> edgesA = a.getEdges();
         Collection<InputEdge> edgesB = b.getEdges();
 
-        Set<InputEdge> newEdges = new HashSet<InputEdge>();
+        Set<InputEdge> newEdges = new HashSet<>();
 
         for (InputEdge e : edgesA) {
             int from = e.getFrom();
             int to = e.getTo();
             InputNode nodeFrom = inputNodeMap.get(a.getNode(from));
             InputNode nodeTo = inputNodeMap.get(a.getNode(to));
-            char index = e.getToIndex();
+            char fromIndex = e.getFromIndex();
+            char toIndex = e.getToIndex();
 
-            InputEdge newEdge = new InputEdge(index, nodeFrom.getId(), nodeTo.getId());
-            if (!newEdges.contains(newEdge)) {
-                markAsNew(newEdge);
-                newEdges.add(newEdge);
-                graph.addEdge(newEdge);
+            if (nodeFrom == null || nodeTo == null) {
+                System.out.println("Unexpected edge : " + from + " -> " + to);
+            } else {
+                InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId(), e.getLabel(), e.getType());
+                if (!newEdges.contains(newEdge)) {
+                    markAsDeleted(newEdge);
+                    newEdges.add(newEdge);
+                    graph.addEdge(newEdge);
+                }
             }
         }
 
@@ -150,40 +225,41 @@
             int to = e.getTo();
             InputNode nodeFrom = inputNodeMap.get(b.getNode(from));
             InputNode nodeTo = inputNodeMap.get(b.getNode(to));
-            char index = e.getToIndex();
+            char fromIndex = e.getFromIndex();
+            char toIndex = e.getToIndex();
 
-            InputEdge newEdge = new InputEdge(index, nodeFrom.getId(), nodeTo.getId());
-            if (!newEdges.contains(newEdge)) {
-                markAsDeleted(newEdge);
-                newEdges.add(newEdge);
-                graph.addEdge(newEdge);
+            if (nodeFrom == null || nodeTo == null) {
+                System.out.println("Unexpected edge : " + from + " -> " + to);
             } else {
-                newEdges.remove(newEdge);
-                graph.removeEdge(newEdge);
-                markAsSame(newEdge);
-                newEdges.add(newEdge);
-                graph.addEdge(newEdge);
+                InputEdge newEdge = new InputEdge(fromIndex, toIndex, nodeFrom.getId(), nodeTo.getId(), e.getLabel(), e.getType());
+                if (!newEdges.contains(newEdge)) {
+                    markAsNew(newEdge);
+                    newEdges.add(newEdge);
+                    graph.addEdge(newEdge);
+                } else {
+                    newEdges.remove(newEdge);
+                    graph.removeEdge(newEdge);
+                    markAsSame(newEdge);
+                    newEdges.add(newEdge);
+                    graph.addEdge(newEdge);
+                }
             }
         }
 
-        g.addGraph(graph);
         return graph;
     }
 
-    private static class Pair {
+    private static class NodePair extends Pair<InputNode, InputNode> {
+
 
-        private InputNode n1;
-        private InputNode n2;
-
-        public Pair(InputNode n1, InputNode n2) {
-            this.n1 = n1;
-            this.n2 = n2;
+        public NodePair(InputNode n1, InputNode n2) {
+            super(n1, n2);
         }
 
         public double getValue() {
 
             double result = 0.0;
-            for (Property p : n1.getProperties()) {
+            for (Property p : getLeft().getProperties()) {
                 double faktor = 1.0;
                 for (String forbidden : IGNORE_PROPERTIES) {
                     if (p.getName().equals(forbidden)) {
@@ -191,7 +267,7 @@
                         break;
                     }
                 }
-                String p2 = n2.getProperties().get(p.getName());
+                String p2 = getRight().getProperties().get(p.getName());
                 result += evaluate(p.getValue(), p2) * faktor;
             }
 
@@ -208,21 +284,13 @@
                 return (double) (Math.abs(p.length() - p2.length())) / p.length() + 0.5;
             }
         }
-
-        public InputNode getN1() {
-            return n1;
-        }
-
-        public InputNode getN2() {
-            return n2;
-        }
     }
 
     private static InputGraph createDiff(InputGraph a, InputGraph b) {
 
-        Set<InputNode> matched = new HashSet<InputNode>();
+        Set<InputNode> matched = new HashSet<>();
 
-        Set<Pair> pairs = new HashSet<Pair>();
+        Set<NodePair> pairs = new HashSet<>();
         for (InputNode n : a.getNodes()) {
             String s = n.getProperties().get(MAIN_PROPERTY);
             if (s == null) {
@@ -235,18 +303,18 @@
                 }
 
                 if (s.equals(s2)) {
-                    Pair p = new Pair(n, n2);
+                    NodePair p = new NodePair(n, n2);
                     pairs.add(p);
                 }
             }
         }
 
-        Set<Pair> selectedPairs = new HashSet<Pair>();
+        Set<NodePair> selectedPairs = new HashSet<>();
         while (pairs.size() > 0) {
 
             double min = Double.MAX_VALUE;
-            Pair minPair = null;
-            for (Pair p : pairs) {
+            NodePair minPair = null;
+            for (NodePair p : pairs) {
                 double cur = p.getValue();
                 if (cur < min) {
                     minPair = p;
@@ -259,9 +327,9 @@
             } else {
                 selectedPairs.add(minPair);
 
-                Set<Pair> toRemove = new HashSet<Pair>();
-                for (Pair p : pairs) {
-                    if (p.getN1() == minPair.getN1() || p.getN2() == minPair.getN2()) {
+                Set<NodePair> toRemove = new HashSet<>();
+                for (NodePair p : pairs) {
+                    if (p.getLeft() == minPair.getLeft() || p.getRight() == minPair.getRight()) {
                         toRemove.add(p);
                     }
                 }
@@ -292,7 +360,7 @@
             String s = firstNode.getProperties().get(p.getName());
             if (!p.getValue().equals(s)) {
                 difference = true;
-                n.getProperties().setProperty(OLD_PREFIX + p.getName(), p.getValue());
+                n.getProperties().setProperty(NEW_PREFIX + p.getName(), p.getValue());
             }
         }
 
@@ -300,7 +368,7 @@
             String s = otherNode.getProperties().get(p.getName());
             if (s == null && p.getValue().length() > 0) {
                 difference = true;
-                n.getProperties().setProperty(OLD_PREFIX + p.getName(), "");
+                n.getProperties().setProperty(NEW_PREFIX + p.getName(), "");
             }
         }
 
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -23,12 +23,28 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>com.sun.hotspot.igv.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>org.jdesktop.layout</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
                         <release-version>1</release-version>
-                        <specification-version>1.4.1</specification-version>
+                        <specification-version>1.16.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.30.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -36,7 +52,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.5.1</specification-version>
+                        <specification-version>7.18.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -44,7 +60,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.3</specification-version>
+                        <specification-version>7.46.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -52,7 +68,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.2.0.1</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -60,7 +76,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -68,7 +92,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.16</specification-version>
+                        <specification-version>6.39.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.sun.hotspot.igv.filter.JavaSE6ScriptEngine
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/AbstractFilter.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/AbstractFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,14 +42,17 @@
         properties = new Properties();
     }
 
+    @Override
     public Properties getProperties() {
         return properties;
     }
 
+    @Override
     public OpenCookie getEditor() {
         return null;
     }
 
+    @Override
     public ChangedEvent<Filter> getChangedEvent() {
         return changedEvent;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ColorFilter.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ColorFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,13 +23,9 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Connection;
+import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.graph.Connection.ConnectionStyle;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Selector;
-import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.graph.*;
 import java.awt.Color;
 import java.util.ArrayList;
 import java.util.List;
@@ -45,16 +41,18 @@
 
     public ColorFilter(String name) {
         this.name = name;
-        colorRules = new ArrayList<ColorRule>();
+        colorRules = new ArrayList<>();
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void apply(Diagram diagram) {
 
-        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(diagram.getFigures());
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(diagram.getFigures());
         for (ColorRule rule : colorRules) {
             if (rule.getSelector() != null) {
                 List<Figure> figures = rule.getSelector().selected(diagram);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CombineFilter.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CombineFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,13 +23,9 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
-import com.sun.hotspot.igv.graph.OutputSlot;
 import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import com.sun.hotspot.igv.graph.*;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -46,23 +42,25 @@
 
     public CombineFilter(String name) {
         this.name = name;
-        rules = new ArrayList<CombineRule>();
+        rules = new ArrayList<>();
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void apply(Diagram diagram) {
 
-        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(diagram.getFigures());
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(diagram.getFigures());
         for (CombineRule r : rules) {
 
             List<Figure> list = selector.selectMultiple(r.getFirstMatcher());
-            Set<Figure> figuresToRemove = new HashSet<Figure>();
+            Set<Figure> figuresToRemove = new HashSet<>();
             for (Figure f : list) {
 
-                List<Figure> successors = new ArrayList<Figure>(f.getSuccessors());
+                List<Figure> successors = new ArrayList<>(f.getSuccessors());
                 if (r.isReversed()) {
                     if (successors.size() == 1) {
                         Figure succ = successors.get(0);
@@ -76,21 +74,30 @@
                             }
                         }
 
-                        assert slot != null;
-                        slot.setName(f.getProperties().get("dump_spec"));
-                        if (f.getProperties().get("short_name") != null) {
-                            slot.setShortName(f.getProperties().get("short_name"));
+                        slot.getSource().addSourceNodes(f.getSource());
+                        if (r.getShortProperty() != null) {
+                            String s = f.getProperties().get(r.getShortProperty());
+                            if (s != null && s.length() > 0) {
+                                slot.setShortName(s);
+                                slot.setText(s);
+                                slot.setColor(f.getColor());
+                            }
                         } else {
-                            String s = f.getProperties().get("dump_spec");
-                            if (s != null && s.length() <= 5) {
-                                slot.setShortName(s);
+                            assert slot != null;
+                            slot.setText(f.getProperties().get("dump_spec"));
+                            if (f.getProperties().get("short_name") != null) {
+                                slot.setShortName(f.getProperties().get("short_name"));
+                            } else {
+                                String s = f.getProperties().get("dump_spec");
+                                if (s != null && s.length() <= 5) {
+                                    slot.setShortName(s);
+                                }
                             }
-
                         }
 
                         for (InputSlot s : f.getInputSlots()) {
                             for (Connection c : s.getConnections()) {
-                                Connection newConn = diagram.createConnection(slot, c.getOutputSlot());
+                                Connection newConn = diagram.createConnection(slot, c.getOutputSlot(), c.getLabel(), c.getType());
                                 newConn.setColor(c.getColor());
                                 newConn.setStyle(c.getStyle());
                             }
@@ -101,7 +108,7 @@
                 } else {
 
                     for (Figure succ : successors) {
-                        if (succ.getPredecessors().size() == 1) {
+                        if (succ.getPredecessors().size() == 1 && succ.getInputSlots().size() == 1) {
                             if (succ.getProperties().selectSingle(r.getSecondMatcher()) != null && succ.getOutputSlots().size() == 1) {
 
 
@@ -122,22 +129,32 @@
                                     pos = Integer.parseInt(succ.getProperties().get("con"));
                                 }
                                 OutputSlot slot = f.createOutputSlot(pos);
-                                slot.setName(succ.getProperties().get("dump_spec"));
-                                if (succ.getProperties().get("short_name") != null) {
-                                    slot.setShortName(succ.getProperties().get("short_name"));
+                                slot.getSource().addSourceNodes(succ.getSource());
+                                if (r.getShortProperty() != null) {
+                                    String s = succ.getProperties().get(r.getShortProperty());
+                                    if (s != null && s.length() > 0) {
+                                        slot.setShortName(s);
+                                        slot.setText(s);
+                                        slot.setColor(succ.getColor());
+                                    }
                                 } else {
-                                    String s = succ.getProperties().get("dump_spec");
-                                    if (s != null && s.length() <= 2) {
-                                        slot.setShortName(s);
+                                    slot.setText(succ.getProperties().get("dump_spec"));
+                                    if (succ.getProperties().get("short_name") != null) {
+                                        slot.setShortName(succ.getProperties().get("short_name"));
                                     } else {
-                                        String tmpName = succ.getProperties().get("name");
-                                        if (tmpName != null && tmpName.length() > 0) {
-                                            slot.setShortName(tmpName.substring(0, 1));
+                                        String s = succ.getProperties().get("dump_spec");
+                                        if (s != null && s.length() <= 2) {
+                                            slot.setShortName(s);
+                                        } else {
+                                            String tmpName = succ.getProperties().get("name");
+                                            if (tmpName != null && tmpName.length() > 0) {
+                                                slot.setShortName(tmpName.substring(0, 1));
+                                            }
                                         }
                                     }
                                 }
                                 for (Connection c : nextSlot.getConnections()) {
-                                    Connection newConn = diagram.createConnection(c.getInputSlot(), slot);
+                                    Connection newConn = diagram.createConnection(c.getInputSlot(), slot, c.getLabel(), c.getType());
                                     newConn.setColor(c.getColor());
                                     newConn.setStyle(c.getStyle());
                                 }
@@ -167,6 +184,7 @@
         private PropertyMatcher first;
         private PropertyMatcher second;
         private boolean reversed;
+        private String shortProperty;
 
         public CombineRule(PropertyMatcher first, PropertyMatcher second) {
             this(first, second, false);
@@ -174,9 +192,14 @@
         }
 
         public CombineRule(PropertyMatcher first, PropertyMatcher second, boolean reversed) {
+            this(first, second, reversed, null);
+        }
+
+        public CombineRule(PropertyMatcher first, PropertyMatcher second, boolean reversed, String shortProperty) {
             this.first = first;
             this.second = second;
             this.reversed = reversed;
+            this.shortProperty = shortProperty;
         }
 
         public boolean isReversed() {
@@ -190,5 +213,9 @@
         public PropertyMatcher getSecondMatcher() {
             return second;
         }
+
+        public String getShortProperty() {
+            return shortProperty;
+        }
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ConnectionFilter.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ConnectionFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,12 +23,8 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Selector;
 import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.graph.*;
 import java.awt.Color;
 import java.util.ArrayList;
 import java.util.List;
@@ -44,16 +40,18 @@
 
     public ConnectionFilter(String name) {
         this.name = name;
-        connectionStyleRules = new ArrayList<ConnectionStyleRule>();
+        connectionStyleRules = new ArrayList<>();
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void apply(Diagram diagram) {
 
-        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(diagram.getFigures());
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(diagram.getFigures());
         for (ConnectionStyleRule rule : connectionStyleRules) {
             List<Figure> figures = null;
             if (rule.getSelector() != null) {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,17 +29,13 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
-import java.util.Collection;
 import java.util.logging.Level;
 import java.util.logging.Logger;
-import org.openide.DialogDisplayer;
-import org.openide.NotifyDescriptor;
+import javax.script.*;
 import org.openide.cookies.OpenCookie;
-import org.openide.filesystems.Repository;
-import org.openide.filesystems.FileSystem;
 import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
 import org.openide.util.Exceptions;
-import org.openide.util.Lookup;
 
 /**
  *
@@ -48,7 +44,6 @@
 public class CustomFilter extends AbstractFilter {
 
     public static final String JAVASCRIPT_HELPER_ID = "JavaScriptHelper";
-    private static ScriptEngineAbstraction engine;
     private String code;
     private String name;
 
@@ -58,6 +53,7 @@
         getProperties().setProperty("name", name);
     }
 
+    @Override
     public String getName() {
         return name;
     }
@@ -80,6 +76,7 @@
     public OpenCookie getEditor() {
         return new OpenCookie() {
 
+            @Override
             public void open() {
                 openInEditor();
             }
@@ -89,7 +86,9 @@
     public boolean openInEditor() {
         EditFilterDialog dialog = new EditFilterDialog(CustomFilter.this);
         dialog.setVisible(true);
-        return dialog.wasAccepted();
+        boolean result = dialog.wasAccepted();
+        this.getChangedEvent().fire();
+        return result;
     }
 
     @Override
@@ -97,41 +96,16 @@
         return getName();
     }
 
-    public static ScriptEngineAbstraction getEngine() {
-        if (engine == null) {
-
-            ScriptEngineAbstraction chosen = null;
-            try {
-                Collection<? extends ScriptEngineAbstraction> list = Lookup.getDefault().lookupAll(ScriptEngineAbstraction.class);
-                for (ScriptEngineAbstraction s : list) {
-                    if (s.initialize(getJsHelperText())) {
-                        if (chosen == null || !(chosen instanceof JavaSE6ScriptEngine)) {
-                            chosen = s;
-                        }
-                    }
-                }
-            } catch (NoClassDefFoundError ncdfe) {
-                Logger.getLogger("global").log(Level.SEVERE, null, ncdfe);
-            }
-
-            if (chosen == null) {
-                NotifyDescriptor message = new NotifyDescriptor.Message("Could not find a scripting engine. Please make sure that the Rhino scripting engine is available. Otherwise filter cannot be used.", NotifyDescriptor.ERROR_MESSAGE);
-                DialogDisplayer.getDefault().notifyLater(message);
-                chosen = new NullScriptEngine();
-            }
-
-            engine = chosen;
-        }
-
-        return engine;
-    }
-
     private static String getJsHelperText() {
         InputStream is = null;
-        StringBuilder sb = new StringBuilder("importPackage(Packages.com.sun.hotspot.igv.filter);importPackage(Packages.com.sun.hotspot.igv.graph);importPackage(Packages.com.sun.hotspot.igv.data);importPackage(Packages.com.sun.hotspot.igv.util);importPackage(java.awt);");
+        StringBuilder sb = new StringBuilder("if (typeof importPackage === 'undefined') { try { load('nashorn:mozilla_compat.js'); } catch (e) {} }"
+                + "importPackage(Packages.com.sun.hotspot.igv.filter);"
+                + "importPackage(Packages.com.sun.hotspot.igv.graph);"
+                + "importPackage(Packages.com.sun.hotspot.igv.data);"
+                + "importPackage(Packages.com.sun.hotspot.igv.util);"
+                + "importPackage(java.awt);");
         try {
-            FileSystem fs = Repository.getDefault().getDefaultFileSystem();
-            FileObject fo = fs.getRoot().getFileObject(JAVASCRIPT_HELPER_ID);
+            FileObject fo = FileUtil.getConfigRoot().getFileObject(JAVASCRIPT_HELPER_ID);
             is = fo.getInputStream();
             BufferedReader r = new BufferedReader(new InputStreamReader(is));
             String s;
@@ -152,7 +126,18 @@
         return sb.toString();
     }
 
+    @Override
     public void apply(Diagram d) {
-        getEngine().execute(d, code);
+        try {
+            ScriptEngineManager sem = new ScriptEngineManager();
+            ScriptEngine e = sem.getEngineByName("ECMAScript");
+            e.eval(getJsHelperText());
+            Bindings b = e.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
+            b.put("graph", d);
+            b.put("IO", System.out);
+            e.eval(code, b);
+        } catch (ScriptException ex) {
+            Exceptions.printStackTrace(ex);
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/EdgeColorIndexFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.*;
+import java.awt.Color;
+import java.util.List;
+
+public class EdgeColorIndexFilter extends AbstractFilter {
+
+    public static final String INPUTS = "INPUTS";
+    public static final String OUTPUTS = "OUTPUTS";
+    private final String applyTo;
+    private final Color[] colors;
+
+    public EdgeColorIndexFilter(String applyTo, Color... color) {
+        if (!applyTo.equals(INPUTS) && !applyTo.equals(OUTPUTS)) {
+            throw new IllegalArgumentException("applyTo");
+        }
+
+        this.applyTo = applyTo;
+        this.colors = color;
+    }
+
+    @Override
+    public String getName() {
+        return "Edge Color Index Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            Slot[] slots;
+            if (applyTo.equals(INPUTS)) {
+                List<InputSlot> inputSlots = f.getInputSlots();
+                slots = inputSlots.toArray(new Slot[inputSlots.size()]);
+            } else {
+                List<OutputSlot> outputSlots = f.getOutputSlots();
+                slots = outputSlots.toArray(new Slot[outputSlots.size()]);
+            }
+            int index = 0;
+            for (Slot slot : slots) {
+                if (index < colors.length && colors[index] != null) {
+                    slot.setColor(colors[index]);
+                    for (Connection c : slot.getConnections()) {
+
+                        c.setColor(colors[index]);
+                    }
+                }
+                index++;
+            }
+
+        }
+    }
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/EditFilterDialog.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/EditFilterDialog.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -137,14 +137,14 @@
     }// </editor-fold>//GEN-END:initComponents
 
 private void okButtonClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_okButtonClicked
-        this.customFilter.setName(this.nameTextField.getText());
-        this.customFilter.setCode(this.sourceTextArea.getText());
-        accepted = true;
-        setVisible(false);
+    this.customFilter.setName(this.nameTextField.getText());
+    this.customFilter.setCode(this.sourceTextArea.getText());
+    accepted = true;
+    setVisible(false);
 }//GEN-LAST:event_okButtonClicked
 
 private void cancelButtonClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonClicked
-        setVisible(false);
+    setVisible(false);
 }//GEN-LAST:event_cancelButtonClicked
 
 
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/Filter.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/Filter.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -41,5 +41,6 @@
 
     OpenCookie getEditor();
 
+    @Override
     ChangedEvent<Filter> getChangedEvent();
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChain.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChain.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,9 +23,10 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Diagram;
 import com.sun.hotspot.igv.data.ChangedEvent;
 import com.sun.hotspot.igv.data.ChangedEventProvider;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.graph.Diagram;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
@@ -38,20 +39,25 @@
 
     private List<Filter> filters;
     private transient ChangedEvent<FilterChain> changedEvent;
-    private boolean fireEvents;
+
+    private ChangedListener<Filter> changedListener = new ChangedListener<Filter>() {
+        @Override
+        public void changed(Filter source) {
+            changedEvent.fire();
+        }
+    };
 
     public FilterChain() {
-        filters = new ArrayList<Filter>();
-        changedEvent = new ChangedEvent<FilterChain>(this);
-        this.fireEvents = true;
+        filters = new ArrayList<>();
+        changedEvent = new ChangedEvent<>(this);
     }
 
     public FilterChain(FilterChain f) {
-        this.filters = new ArrayList<Filter>(f.filters);
-        changedEvent = new ChangedEvent<FilterChain>(this);
-        this.fireEvents = true;
+        this.filters = new ArrayList<>(f.filters);
+        changedEvent = new ChangedEvent<>(this);
     }
 
+    @Override
     public ChangedEvent<FilterChain> getChangedEvent() {
         return changedEvent;
     }
@@ -68,7 +74,7 @@
     }
 
     public void apply(Diagram d, FilterChain sequence) {
-        List<Filter> applied = new ArrayList<Filter>();
+        List<Filter> applied = new ArrayList<>();
         for (Filter f : sequence.getFilters()) {
             if (filters.contains(f)) {
                 f.apply(d);
@@ -84,29 +90,12 @@
         }
     }
 
-    public void beginAtomic() {
-        this.fireEvents = false;
-    }
-
-    public void endAtomic() {
-        this.fireEvents = true;
-        changedEvent.fire();
-    }
 
     public void addFilter(Filter filter) {
         assert filter != null;
         filters.add(filter);
-        if (fireEvents) {
-            changedEvent.fire();
-        }
-    }
-
-    public void addFilterSameSequence(Filter filter) {
-        assert filter != null;
-        filters.add(filter);
-        if (fireEvents) {
-            changedEvent.fire();
-        }
+        filter.getChangedEvent().addListener(changedListener);
+        changedEvent.fire();
     }
 
     public boolean containsFilter(Filter filter) {
@@ -116,9 +105,8 @@
     public void removeFilter(Filter filter) {
         assert filters.contains(filter);
         filters.remove(filter);
-        if (fireEvents) {
-            changedEvent.fire();
-        }
+        filter.getChangedEvent().removeListener(changedListener);
+        changedEvent.fire();
     }
 
     public void moveFilterUp(Filter filter) {
@@ -128,9 +116,7 @@
             filters.remove(index);
             filters.add(index - 1, filter);
         }
-        if (fireEvents) {
-            changedEvent.fire();
-        }
+        changedEvent.fire();
     }
 
     public void moveFilterDown(Filter filter) {
@@ -140,16 +126,10 @@
             filters.remove(index);
             filters.add(index + 1, filter);
         }
-        if (fireEvents) {
-            changedEvent.fire();
-        }
+        changedEvent.fire();
     }
 
     public List<Filter> getFilters() {
         return Collections.unmodifiableList(filters);
     }
-
-    public void clear() {
-        filters.clear();
-    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChainProvider.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChainProvider.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterSetting.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterSetting.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -42,7 +42,7 @@
 
     public FilterSetting(String name) {
         this.name = name;
-        filters = new HashSet<Filter>();
+        filters = new HashSet<>();
     }
 
     public Set<Filter> getFilters() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/GradientColorFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import java.awt.image.Raster;
+import java.util.List;
+
+/**
+ * Filter that colors nodes using a customizable color gradient, based on how
+ * a numeric property is located in a specified interval.
+ *
+ * @author Peter Hofer
+ */
+public class GradientColorFilter extends AbstractFilter {
+
+    public static final String LINEAR = "LINEAR";
+    public static final String LOGARITHMIC = "LOGARITHMIC";
+
+    private String propertyName = "probability";
+    private float minValue = 0;
+    private float maxValue = 500;
+    private float[] fractions = {0, 0.5f, 1};
+    private Color[] colors = {Color.BLUE, Color.YELLOW, Color.RED};
+    private int shadeCount = 8;
+    private String mode = LINEAR;
+
+    @Override
+    public String getName() {
+        return "Gradient Color Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        boolean logarithmic = mode.equalsIgnoreCase(LOGARITHMIC);
+        if (!logarithmic && !mode.equalsIgnoreCase(LINEAR)) {
+            throw new RuntimeException("Unknown mode: " + mode);
+        }
+
+        Rectangle bounds = new Rectangle(shadeCount, 1);
+        LinearGradientPaint lgp = new LinearGradientPaint(bounds.x, bounds.y, bounds.width, bounds.y, fractions, colors);
+        PaintContext context = lgp.createContext(null, bounds, bounds.getBounds2D(), AffineTransform.getTranslateInstance(0, 0), new RenderingHints(null));
+        Raster raster = context.getRaster(bounds.x, bounds.y, bounds.width, bounds.height);
+        int[] rgb = raster.getPixels(bounds.x, bounds.y, bounds.width, bounds.height, (int[]) null);
+        Color[] shades = new Color[rgb.length / 3];
+        for (int i = 0; i < shades.length; ++i) {
+            shades[i] = new Color(rgb[i * 3], rgb[i * 3 + 1], rgb[i * 3 + 2]);
+        }
+
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            String property = f.getProperties().get(propertyName);
+            if (property != null) {
+                try {
+                    float value = Float.parseFloat(property);
+
+                    Color nodeColor;
+                    if (value <= minValue) {
+                        nodeColor = colors[0];
+                    } else if (value >= maxValue) {
+                        nodeColor = colors[colors.length - 1];
+                    } else {
+                        double normalized = value - minValue;
+                        double interval = maxValue - minValue;
+                        int index;
+                        // Use Math.ceil() to make values above zero distinguishable from zero
+                        if (logarithmic) {
+                            index = (int) Math.ceil(shades.length * Math.log(1 + normalized) / Math.log(1 + interval));
+                        } else {
+                            index = (int) Math.ceil(shades.length * normalized / interval);
+                        }
+                        nodeColor = shades[index];
+                    }
+                    f.setColor(nodeColor);
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+        }
+    }
+
+    public String getPropertyName() {
+        return propertyName;
+    }
+
+    public void setPropertyName(String propertyName) {
+        this.propertyName = propertyName;
+    }
+
+    public float getMinValue() {
+        return minValue;
+    }
+
+    public void setMinValue(float minValue) {
+        this.minValue = minValue;
+    }
+
+    public float getMaxValue() {
+        return maxValue;
+    }
+
+    public void setMaxValue(float maxValue) {
+        this.maxValue = maxValue;
+    }
+
+    public float[] getFractions() {
+        return fractions;
+    }
+
+    public void setFractions(float[] fractions) {
+        this.fractions = fractions;
+    }
+
+    public Color[] getColors() {
+        return colors;
+    }
+
+    public void setColors(Color[] colors) {
+        this.colors = colors;
+    }
+
+    public int getShadeCount() {
+        return shadeCount;
+    }
+
+    public void setShadeCount(int shadeCount) {
+        this.shadeCount = shadeCount;
+    }
+
+    public String getMode() {
+        return mode;
+    }
+
+    public void setMode(String mode) {
+        this.mode = mode;
+    }
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/JavaSE6ScriptEngine.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.hotspot.igv.filter;
-
-import com.sun.hotspot.igv.graph.Diagram;
-import javax.script.Bindings;
-import javax.script.ScriptContext;
-import javax.script.ScriptEngine;
-import javax.script.ScriptEngineManager;
-import javax.script.ScriptException;
-import org.openide.util.Exceptions;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class JavaSE6ScriptEngine implements ScriptEngineAbstraction {
-
-    private ScriptEngine engine;
-    private Bindings bindings;
-
-    public boolean initialize(String jsHelperText) {
-        try {
-            ScriptEngineManager sem = new ScriptEngineManager();
-            ScriptEngine e = sem.getEngineByName("ECMAScript");
-            engine = e;
-            e.eval(jsHelperText);
-            Bindings b = e.getContext().getBindings(ScriptContext.ENGINE_SCOPE);
-            b.put("IO", System.out);
-            bindings = b;
-            return true;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    public void execute(Diagram d, String code) {
-        try {
-            Bindings b = bindings;
-            b.put("graph", d);
-            engine.eval(code, b);
-        } catch (ScriptException ex) {
-            Exceptions.printStackTrace(ex);
-        }
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/NullScriptEngine.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.filter;
-
-import com.sun.hotspot.igv.graph.Diagram;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class NullScriptEngine implements ScriptEngineAbstraction {
-
-    public boolean initialize(String jsHelperText) {
-        return true;
-    }
-
-    public void execute(Diagram d, String code) {
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveFilter.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,7 @@
 
 import com.sun.hotspot.igv.graph.Diagram;
 import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
 import com.sun.hotspot.igv.graph.Selector;
-import com.sun.hotspot.igv.data.Properties;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
@@ -44,56 +42,36 @@
 
     public RemoveFilter(String name) {
         this.name = name;
-        rules = new ArrayList<RemoveRule>();
+        rules = new ArrayList<>();
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void apply(Diagram diagram) {
-
         for (RemoveRule r : rules) {
+            List<Figure> selected = r.getSelector().selected(diagram);
+            Set<Figure> toRemove = new HashSet<>(selected);
 
-            List<Figure> list = r.getSelector().selected(diagram);
-            Set<Figure> figuresToRemove = new HashSet<Figure>();
-
-            List<Figure> protectedFigures = null;
-            if (r.getRemoveAllWithoutPredecessor()) {
-                protectedFigures = diagram.getRootFigures();
+            if (r.getRemoveOrphans()) {
+                boolean changed;
+                do {
+                    changed = false;
+                    for (Figure f : diagram.getFigures()) {
+                        if (!toRemove.contains(f)) {
+                            if (toRemove.containsAll(f.getPredecessors()) && toRemove.containsAll(f.getSuccessors())) {
+                                toRemove.add(f);
+                                changed = true;
+                            }
+                        }
+                    }
+                } while (changed);
             }
 
-            for (Figure f : list) {
-                if (r.getRemoveOnlyInputs()) {
-                    List<InputSlot> inputSlots = new ArrayList<InputSlot>();
-                    for (InputSlot is : f.getInputSlots()) {
-                        inputSlots.add(is);
-                    }
-                    for (InputSlot is : inputSlots) {
-                        f.removeSlot(is);
-                    }
-
-                    f.createInputSlot();
-                } else {
-                    figuresToRemove.add(f);
-                }
-            }
-
-            if (r.getRemoveAllWithoutPredecessor()) {
-                boolean progress = true;
-                while (progress) {
-                    List<Figure> rootFigures = diagram.getRootFigures();
-                    progress = false;
-                    for (Figure f : rootFigures) {
-                        if (!protectedFigures.contains(f)) {
-                            figuresToRemove.add(f);
-                            progress = true;
-                        }
-                    }
-                }
-            }
-
-            diagram.removeAllFigures(figuresToRemove);
+            diagram.removeAllFigures(toRemove);
         }
     }
 
@@ -104,29 +82,23 @@
     public static class RemoveRule {
 
         private Selector selector;
-        private boolean removeAllWithoutPredecessor;
-        private boolean removeOnlyInputs;
+        private boolean removeOrphans;
 
-        public RemoveRule(Selector selector, boolean b) {
-            this(selector, b, false);
+        public RemoveRule(Selector selector) {
+            this(selector, false);
         }
 
-        public RemoveRule(Selector selector, boolean removeAllWithoutPredecessor, boolean removeOnlyInputs) {
+        public RemoveRule(Selector selector, boolean removeOrphans) {
             this.selector = selector;
-            this.removeOnlyInputs = removeOnlyInputs;
-            this.removeAllWithoutPredecessor = removeAllWithoutPredecessor;
+            this.removeOrphans = removeOrphans;
         }
 
         public Selector getSelector() {
             return selector;
         }
 
-        public boolean getRemoveOnlyInputs() {
-            return removeOnlyInputs;
-        }
-
-        public boolean getRemoveAllWithoutPredecessor() {
-            return removeAllWithoutPredecessor;
+        public boolean getRemoveOrphans() {
+            return removeOrphans;
         }
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveInputsFilter.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveInputsFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,12 +23,7 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
-import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Selector;
+import com.sun.hotspot.igv.graph.*;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -43,13 +38,15 @@
 
     public RemoveInputsFilter(String name) {
         this.name = name;
-        rules = new ArrayList<RemoveInputsRule>();
+        rules = new ArrayList<>();
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void apply(Diagram diagram) {
 
         for (RemoveInputsRule r : rules) {
@@ -57,7 +54,7 @@
             List<Figure> list = r.getSelector().selected(diagram);
             for (Figure f : list) {
                 int z = 0;
-                List<InputSlot> last = new ArrayList<InputSlot>();
+                List<InputSlot> last = new ArrayList<>();
                 for (InputSlot is : f.getInputSlots()) {
                     if (z >= r.getStartingIndex() && z <= r.getEndIndex() && is.getConnections().size() > 0) {
                         StringBuilder sb = new StringBuilder();
@@ -73,7 +70,7 @@
                         }
                         is.removeAllConnections();
                         is.setShortName("X");
-                        is.setName(sb.toString());
+                        is.setText(sb.toString());
                         last.add(is);
                     } else {
                         last.clear();
@@ -91,10 +88,10 @@
                         if (i != 0) {
                             sb.append("<BR>");
                         }
-                        sb.append(is2.getName());
+                        sb.append(is2.getText());
                     }
 
-                    first.setName(sb.toString());
+                    first.setText(sb.toString());
 
                     for (int i = 1; i < last.size(); i++) {
                         f.removeSlot(last.get(i));
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveSelfLoopsFilter.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveSelfLoopsFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,11 +23,7 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
-import com.sun.hotspot.igv.graph.OutputSlot;
+import com.sun.hotspot.igv.graph.*;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -44,17 +40,19 @@
         this.name = name;
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void apply(Diagram d) {
 
         for (Figure f : d.getFigures()) {
 
             for (InputSlot is : f.getInputSlots()) {
 
-                List<Connection> toRemove = new ArrayList<Connection>();
+                List<Connection> toRemove = new ArrayList<>();
                 for (Connection c : is.getConnections()) {
 
                     if (c.getOutputSlot().getFigure() == f) {
@@ -72,7 +70,7 @@
                     }
 
                     c.getInputSlot().setShortName("O");
-                    c.getInputSlot().setName("Self Loop");
+                    c.getInputSlot().setText("Self Loop");
                 }
             }
         }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ScriptEngineAbstraction.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.hotspot.igv.filter;
-
-import com.sun.hotspot.igv.graph.Diagram;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public interface ScriptEngineAbstraction {
-
-    public boolean initialize(String jsHelperText);
-
-    public void execute(Diagram d, String code);
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,12 +23,7 @@
  */
 package com.sun.hotspot.igv.filter;
 
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
-import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Selector;
+import com.sun.hotspot.igv.graph.*;
 import java.util.List;
 
 /**
@@ -39,25 +34,52 @@
 
     private String name;
     private Selector selector;
+    private String propertyName;
 
-    public SplitFilter(String name, Selector selector) {
+    public SplitFilter(String name, Selector selector, String propertyName) {
         this.name = name;
         this.selector = selector;
+        this.propertyName = propertyName;
     }
 
+    @Override
     public String getName() {
         return name;
     }
 
+    @Override
     public void apply(Diagram d) {
         List<Figure> list = selector.selected(d);
 
         for (Figure f : list) {
+
+            for (InputSlot is : f.getInputSlots()) {
+                for (Connection c : is.getConnections()) {
+                    OutputSlot os = c.getOutputSlot();
+                    if (f.getSource().getSourceNodes().size() > 0) {
+                        os.getSource().addSourceNodes(f.getSource());
+                        os.setAssociatedNode(f.getSource().getSourceNodes().get(0));
+                        os.setColor(f.getColor());
+                    }
+
+
+                    String s = Figure.resolveString(propertyName, f.getProperties());
+                    if (s != null) {
+                        os.setShortName(s);
+                    }
+
+                }
+            }
             for (OutputSlot os : f.getOutputSlots()) {
                 for (Connection c : os.getConnections()) {
                     InputSlot is = c.getInputSlot();
-                    is.setName(f.getProperties().get("dump_spec"));
-                    String s = f.getProperties().get("short_name");
+                    if (f.getSource().getSourceNodes().size() > 0) {
+                        is.getSource().addSourceNodes(f.getSource());
+                        is.setAssociatedNode(f.getSource().getSourceNodes().get(0));
+                        is.setColor(f.getColor());
+                    }
+
+                    String s = Figure.resolveString(propertyName, f.getProperties());
                     if (s != null) {
                         is.setShortName(s);
                     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/UnconnectedSlotFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.graph.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Filter that hides slots with no connections.
+ */
+public class UnconnectedSlotFilter extends AbstractFilter {
+
+    private final boolean removeInputs;
+    private final boolean removeOutputs;
+
+    public UnconnectedSlotFilter(boolean inputs, boolean outputs) {
+        this.removeInputs = inputs;
+        this.removeOutputs = outputs;
+    }
+
+    @Override
+    public String getName() {
+        return "Unconnected Slot Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        if (!removeInputs && !removeOutputs) {
+            return;
+        }
+
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            List<Slot> remove = new ArrayList<>();
+            if (removeInputs) {
+                for (InputSlot is : f.getInputSlots()) {
+                    if (is.getConnections().isEmpty()) {
+                        remove.add(is);
+                    }
+                }
+            }
+            if (removeOutputs) {
+                for (OutputSlot os : f.getOutputSlots()) {
+                    if (os.getConnections().isEmpty()) {
+                        remove.add(os);
+                    }
+                }
+            }
+            for (Slot s : remove) {
+                f.removeSlot(s);
+            }
+        }
+    }
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/helper.js	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/helper.js	Tue May 05 19:27:08 2015 +0200
@@ -21,26 +21,35 @@
  * questions.
  *
  */
-
+ 
  /**
  *
  * @author Thomas Wuerthinger
  */
-
+ 
 function colorize(property, regexp, color) {
     var f = new ColorFilter("");
     f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), color));
-    f.apply(graph);
+    f.apply(graph); 
 }
 
 function remove(property, regexp) {
     var f = new RemoveFilter("");
-    f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), false, false));
+    f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp))));
     f.apply(graph);
 }
 
-function split(property, regexp) {
-    var f = new SplitFilter("", new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)));
+function removeIncludingOrphans(property, regexp) {
+    var f = new RemoveFilter("");
+    f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), true));
+    f.apply(graph);
+}
+
+function split(property, regexp, propertyName) {
+    if (propertyName == undefined) {
+        propertyName = graph.getNodeText();
+    }
+    var f = new SplitFilter("", new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), propertyName);
     f.apply(graph);
 }
 
@@ -56,6 +65,40 @@
     f.apply(graph);
 }
 
+function removeUnconnectedSlots(inputs, outputs) {
+    var f = new UnconnectedSlotFilter(inputs, outputs);
+    f.apply(graph);
+}
+
+function colorizeGradient(property, min, max) {
+    var f = new GradientColorFilter();
+    f.setPropertyName(property);
+    f.setMinValue(min);
+    f.setMaxValue(max);
+    f.apply(graph);
+}
+
+function colorizeGradientWithMode(property, min, max, mode) {
+    var f = new GradientColorFilter();
+    f.setPropertyName(property);
+    f.setMinValue(min);
+    f.setMaxValue(max);
+    f.setMode(mode);
+    f.apply(graph);
+}
+
+function colorizeGradientCustom(property, min, max, mode, colors, fractions, nshades) {
+    var f = new GradientColorFilter();
+    f.setPropertyName(property);
+    f.setMinValue(min);
+    f.setMaxValue(max);
+    f.setMode(mode);
+    f.setColors(colors);
+    f.setFractions(fractions);
+    f.setShadeCount(nshades);
+    f.apply(graph);
+}
+
 var black = Color.black;
 var blue = Color.blue;
 var cyan = Color.cyan;
@@ -68,4 +111,4 @@
 var pink = Color.pink
 var red = Color.red;
 var yellow = Color.yellow;
-var white = Color.white;
+var white = Color.white;
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/build-impl.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/build-impl.xml	Tue May 05 19:27:08 2015 +0200
@@ -4,6 +4,13 @@
 ***         EDIT ../build.xml INSTEAD         ***
 -->
 <project name="com.sun.hotspot.igv.filterwindow-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
     <property file="nbproject/private/suite-private.properties"/>
     <property file="nbproject/suite.properties"/>
     <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
@@ -16,13 +23,21 @@
             <property name="@{name}" value="${@{value}}"/>
         </sequential>
     </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
     <property file="${user.properties.file}"/>
     <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
         <condition>
             <not>
-                <available file="${harness.dir}" type="dir"/>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
             </not>
         </condition>
     </fail>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/genfiles.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/genfiles.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,8 +1,5 @@
-build.xml.data.CRC32=401b2654
-build.xml.script.CRC32=9c158403
-build.xml.stylesheet.CRC32=79c3b980
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=401b2654
-nbproject/build-impl.xml.script.CRC32=19fb08e0
-nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
+nbproject/build-impl.xml.data.CRC32=5b8e8a60
+nbproject/build-impl.xml.script.CRC32=e4293f0e
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.67.1
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -43,7 +43,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.6.1.1</specification-version>
+                        <specification-version>6.21.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.39.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -51,7 +59,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.5.1</specification-version>
+                        <specification-version>7.18.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -59,7 +67,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.12.1</specification-version>
+                        <specification-version>6.34.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -67,7 +75,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.3.1</specification-version>
+                        <specification-version>7.46.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -75,7 +83,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.7.1</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -83,7 +91,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.2.1.1</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -91,7 +99,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.10.1.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -99,7 +115,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.18.1</specification-version>
+                        <specification-version>6.39.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/Bundle.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/Bundle.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,3 +1,3 @@
 OpenIDE-Module-Name=FilterWindow
-CTL_FilterTopComponent=Filter Window
-HINT_FilterTopComponent=This is a Filter window
+CTL_FilterTopComponent=Filters
+HINT_FilterTopComponent=Allows to choose active filters and modify them.
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckListView.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckListView.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,8 +44,8 @@
     }
 
     @Override
-    protected JList createList() {
-        JList tmpList = super.createList();
+    protected JList<Object> createList() {
+        JList<Object> tmpList = super.createList();
         tmpList.setCellRenderer(new CheckRenderer(tmpList));
         return tmpList;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNode.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNode.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,7 +40,7 @@
 
     public CheckNode(Children c, Lookup lookup) {
         super(c, lookup);
-        selectionChangedEvent = new ChangedEvent<CheckNode>(this);
+        selectionChangedEvent = new ChangedEvent<>(this);
         selected = false;
         enabled = true;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNodeListModel.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNodeListModel.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,7 +24,7 @@
 package com.sun.hotspot.igv.filterwindow;
 
 import org.openide.explorer.view.NodeListModel;
-import org.openide.nodes.Node;
+import org.openide.explorer.view.Visualizer;
 
 /**
  *
@@ -32,15 +32,11 @@
  */
 public class CheckNodeListModel extends NodeListModel {
 
-    private Node rootNode;
-
-    @Override
-    public void setNode(Node rootNode) {
-        this.rootNode = rootNode;
-        super.setNode(rootNode);
-    }
-
     public CheckNode getCheckNodeAt(int index) {
-        return (CheckNode) rootNode.getChildren().getNodes()[index];
+        Object item = getElementAt(index);
+        if (item != null) {
+            return (CheckNode) Visualizer.findNode(item);
+        }
+        return null;
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckRenderer.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckRenderer.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,11 +23,7 @@
  */
 package com.sun.hotspot.igv.filterwindow;
 
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.Rectangle;
+import java.awt.*;
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
 import javax.swing.JCheckBox;
@@ -37,12 +33,12 @@
 /**
  * @author Thomas Wuerthinger
  */
-public class CheckRenderer extends JCheckBox implements ListCellRenderer {
+public class CheckRenderer extends JCheckBox implements ListCellRenderer<Object> {
 
-    private JList list;
+    private JList<Object> list;
     private Color startBackground;
 
-    public CheckRenderer(final JList list) {
+    public CheckRenderer(final JList<Object> list) {
         this.list = list;
         list.addMouseListener(
                 new MouseAdapter() {
@@ -65,7 +61,8 @@
         startBackground = this.getBackground();
     }
 
-    public Component getListCellRendererComponent(final JList list, Object value, final int index, boolean isSelected, boolean cellHasFocus) {
+    @Override
+    public Component getListCellRendererComponent(final JList<? extends Object> list, Object value, final int index, boolean isSelected, boolean cellHasFocus) {
         setText(value.toString());
         CheckNode node = ((CheckNodeListModel) list.getModel()).getCheckNodeAt(index);
         this.setSelected(node.isSelected());
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterChainProviderImplementation.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterChainProviderImplementation.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,10 +32,12 @@
  */
 public class FilterChainProviderImplementation implements FilterChainProvider {
 
+    @Override
     public FilterChain getFilterChain() {
         return FilterTopComponent.findInstance().getFilterChain();
     }
 
+    @Override
     public FilterChain getSequence() {
         return FilterTopComponent.findInstance().getSequence();
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterNode.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterNode.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,12 +23,12 @@
  */
 package com.sun.hotspot.igv.filterwindow;
 
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.filter.Filter;
+import com.sun.hotspot.igv.filter.FilterChain;
 import com.sun.hotspot.igv.filterwindow.actions.MoveFilterDownAction;
 import com.sun.hotspot.igv.filterwindow.actions.MoveFilterUpAction;
 import com.sun.hotspot.igv.filterwindow.actions.RemoveFilterAction;
-import com.sun.hotspot.igv.filter.Filter;
-import com.sun.hotspot.igv.filter.FilterChain;
-import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.util.PropertiesSheet;
 import javax.swing.Action;
 import org.openide.actions.OpenAction;
@@ -48,7 +48,7 @@
 public class FilterNode extends CheckNode implements LookupListener, ChangedListener<FilterTopComponent> {
 
     private Filter filter;
-    private Lookup.Result result;
+    private Lookup.Result<FilterChain> result;
 
     public FilterNode(Filter filter) {
         this(filter, new InstanceContent());
@@ -62,6 +62,7 @@
         this.filter = filter;
         filter.getChangedEvent().addListener(new ChangedListener<Filter>() {
 
+            @Override
             public void changed(Filter source) {
                 update();
             }
@@ -69,12 +70,14 @@
 
         update();
 
-        Lookup.Template<FilterChain> tpl = new Lookup.Template<FilterChain>(FilterChain.class);
+        Lookup.Template<FilterChain> tpl = new Lookup.Template<>(FilterChain.class);
         result = Utilities.actionsGlobalContext().lookup(tpl);
         result.addLookupListener(this);
 
         FilterTopComponent.findInstance().getFilterSettingsChangedEvent().addListener(this);
         resultChanged(null);
+
+        setShortDescription("Double-click to open filter");
     }
 
     private void update() {
@@ -102,10 +105,12 @@
         return OpenAction.get(OpenAction.class).createContextAwareInstance(Utilities.actionsGlobalContext());
     }
 
+    @Override
     public void resultChanged(LookupEvent lookupEvent) {
         changed(FilterTopComponent.findInstance());
     }
 
+    @Override
     public void changed(FilterTopComponent source) {
         setSelected(source.getFilterChain().containsFilter(filter));
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.form	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.form	Tue May 05 19:27:08 2015 +0200
@@ -3,6 +3,8 @@
 <Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,65 +23,38 @@
  */
 package com.sun.hotspot.igv.filterwindow;
 
-import com.sun.hotspot.igv.filterwindow.actions.MoveFilterDownAction;
-import com.sun.hotspot.igv.filterwindow.actions.MoveFilterUpAction;
-import com.sun.hotspot.igv.filterwindow.actions.NewFilterAction;
-import com.sun.hotspot.igv.filterwindow.actions.RemoveFilterAction;
-import com.sun.hotspot.igv.filterwindow.actions.RemoveFilterSettingsAction;
-import com.sun.hotspot.igv.filterwindow.actions.SaveFilterSettingsAction;
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.filter.CustomFilter;
 import com.sun.hotspot.igv.filter.Filter;
 import com.sun.hotspot.igv.filter.FilterChain;
 import com.sun.hotspot.igv.filter.FilterSetting;
-import com.sun.hotspot.igv.data.ChangedEvent;
-import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.filterwindow.actions.*;
 import java.awt.BorderLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.io.BufferedReader;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.Serializable;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
+import java.io.*;
+import java.util.*;
 import javax.swing.JComboBox;
 import javax.swing.UIManager;
 import javax.swing.border.Border;
 import org.openide.DialogDisplayer;
 import org.openide.ErrorManager;
 import org.openide.NotifyDescriptor;
+import org.openide.awt.Toolbar;
 import org.openide.awt.ToolbarPool;
 import org.openide.explorer.ExplorerManager;
 import org.openide.explorer.ExplorerUtils;
+import org.openide.filesystems.FileLock;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileUtil;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
-import org.openide.util.Exceptions;
-import org.openide.util.Lookup;
-import org.openide.util.LookupEvent;
-import org.openide.util.LookupListener;
-import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
-import org.openide.awt.Toolbar;
-import org.openide.filesystems.FileLock;
+import org.openide.util.*;
 import org.openide.util.actions.SystemAction;
 import org.openide.windows.TopComponent;
 import org.openide.windows.WindowManager;
-import org.openide.filesystems.Repository;
-import org.openide.filesystems.FileSystem;
-import org.openide.filesystems.FileObject;
 
 /**
  *
@@ -98,13 +71,14 @@
     private ExplorerManager manager;
     private FilterChain filterChain;
     private FilterChain sequence;
-    private Lookup.Result result;
+    private Lookup.Result<FilterChain> result;
     private JComboBox comboBox;
     private List<FilterSetting> filterSettings;
     private FilterSetting customFilterSetting = new FilterSetting("-- Custom --");
     private ChangedEvent<FilterTopComponent> filterSettingsChangedEvent;
     private ActionListener comboBoxActionListener = new ActionListener() {
 
+        @Override
         public void actionPerformed(ActionEvent e) {
             comboBoxSelectionChanged();
         }
@@ -139,8 +113,8 @@
 
         if (s != customFilterSetting) {
             FilterChain chain = getFilterChain();
-            chain.beginAtomic();
-            List<Filter> toRemove = new ArrayList<Filter>();
+            chain.getChangedEvent().beginAtomic();
+            List<Filter> toRemove = new ArrayList<>();
             for (Filter f : chain.getFilters()) {
                 if (!s.containsFilter(f)) {
                     toRemove.add(f);
@@ -156,7 +130,7 @@
                 }
             }
 
-            chain.endAtomic();
+            chain.getChangedEvent().endAtomic();
             filterSettingsChangedEvent.fire();
         } else {
             this.updateComboBoxSelection();
@@ -177,14 +151,14 @@
     }
 
     public void addFilterSetting() {
-        NotifyDescriptor.InputLine l = new NotifyDescriptor.InputLine("Enter a name:", "Filter");
+        NotifyDescriptor.InputLine l = new NotifyDescriptor.InputLine("Name of the new profile:", "Filter Profile");
         if (DialogDisplayer.getDefault().notify(l) == NotifyDescriptor.OK_OPTION) {
             String name = l.getInputText();
 
             FilterSetting toRemove = null;
             for (FilterSetting s : filterSettings) {
                 if (s.getName().equals(name)) {
-                    NotifyDescriptor.Confirmation conf = new NotifyDescriptor.Confirmation("Filter \"" + name + "\" already exists, to you want to overwrite?", "Filter");
+                    NotifyDescriptor.Confirmation conf = new NotifyDescriptor.Confirmation("Filter profile \"" + name + "\" already exists, do you want to replace it?", "Filter");
                     if (DialogDisplayer.getDefault().notify(conf) == NotifyDescriptor.YES_OPTION) {
                         toRemove = s;
                         break;
@@ -203,6 +177,7 @@
             // Sort alphabetically
             Collections.sort(filterSettings, new Comparator<FilterSetting>() {
 
+                @Override
                 public int compare(FilterSetting o1, FilterSetting o2) {
                     return o1.getName().compareTo(o2.getName());
                 }
@@ -223,7 +198,7 @@
             FilterSetting f = (FilterSetting) o;
             assert f != customFilterSetting;
             assert filterSettings.contains(f);
-            NotifyDescriptor.Confirmation l = new NotifyDescriptor.Confirmation("Do you really want to remove filter \"" + f + "\"?", "Filter");
+            NotifyDescriptor.Confirmation l = new NotifyDescriptor.Confirmation("Do you really want to remove filter profile \"" + f + "\"?", "Filter Profile");
             if (DialogDisplayer.getDefault().notify(l) == NotifyDescriptor.YES_OPTION) {
                 filterSettings.remove(f);
                 updateComboBox();
@@ -267,28 +242,26 @@
         }
     }
 
-    private class FilterChildren extends Children.Keys implements ChangedListener<CheckNode> {
+    private class FilterChildren extends Children.Keys<Filter> implements ChangedListener<CheckNode> {
+
+        private HashMap<Filter, Node> nodeHash = new HashMap<>();
 
-        //private Node[] oldSelection;
-        //private ArrayList<Node> newSelection;
-        private HashMap<Object, Node> nodeHash = new HashMap<Object, Node>();
-
-        protected Node[] createNodes(Object object) {
-            if (nodeHash.containsKey(object)) {
-                return new Node[]{nodeHash.get(object)};
+        @Override
+        protected Node[] createNodes(Filter filter) {
+            if (nodeHash.containsKey(filter)) {
+                return new Node[]{nodeHash.get(filter)};
             }
 
-            assert object instanceof Filter;
-            Filter filter = (Filter) object;
-            com.sun.hotspot.igv.filterwindow.FilterNode node = new com.sun.hotspot.igv.filterwindow.FilterNode(filter);
+            FilterNode node = new FilterNode(filter);
             node.getSelectionChangedEvent().addListener(this);
-            nodeHash.put(object, node);
+            nodeHash.put(filter, node);
             return new Node[]{node};
         }
 
         public FilterChildren() {
             sequence.getChangedEvent().addListener(new ChangedListener<FilterChain>() {
 
+                @Override
                 public void changed(FilterChain source) {
                     addNotify();
                 }
@@ -297,11 +270,13 @@
             setBefore(false);
         }
 
+        @Override
         protected void addNotify() {
             setKeys(sequence.getFilters());
             updateSelection();
         }
 
+        @Override
         public void changed(CheckNode source) {
             FilterNode node = (FilterNode) source;
             Filter f = node.getFilter();
@@ -322,16 +297,11 @@
     }
 
     public FilterChain getFilterChain() {
-        return filterChain;/*
-    EditorTopComponent tc = EditorTopComponent.getActive();
-    if (tc == null) {
-    return filterChain;
-    }
-    return tc.getFilterChain();*/
+        return filterChain;
     }
 
     private FilterTopComponent() {
-        filterSettingsChangedEvent = new ChangedEvent<FilterTopComponent>(this);
+        filterSettingsChangedEvent = new ChangedEvent<>(this);
         initComponents();
         setName(NbBundle.getMessage(FilterTopComponent.class, "CTL_FilterTopComponent"));
         setToolTipText(NbBundle.getMessage(FilterTopComponent.class, "HINT_FilterTopComponent"));
@@ -355,13 +325,13 @@
         toolBar.add(SaveFilterSettingsAction.get(SaveFilterSettingsAction.class));
         toolBar.add(RemoveFilterSettingsAction.get(RemoveFilterSettingsAction.class));
         toolBar.addSeparator();
+        toolBar.add(NewFilterAction.get(NewFilterAction.class));
+        toolBar.add(RemoveFilterAction.get(RemoveFilterAction.class).createContextAwareInstance(this.getLookup()));
         toolBar.add(MoveFilterUpAction.get(MoveFilterUpAction.class).createContextAwareInstance(this.getLookup()));
         toolBar.add(MoveFilterDownAction.get(MoveFilterDownAction.class).createContextAwareInstance(this.getLookup()));
-        toolBar.add(RemoveFilterAction.get(RemoveFilterAction.class).createContextAwareInstance(this.getLookup()));
-        toolBar.add(NewFilterAction.get(NewFilterAction.class));
         this.add(view, BorderLayout.CENTER);
 
-        filterSettings = new ArrayList<FilterSetting>();
+        filterSettings = new ArrayList<>();
         updateComboBox();
 
         comboBox.addActionListener(comboBoxActionListener);
@@ -401,6 +371,7 @@
             filter = cf;
         }
 
+        @Override
         public void changed(Filter source) {
             try {
                 if (!fileObject.getName().equals(filter.getName())) {
@@ -409,15 +380,14 @@
                     lock.releaseLock();
                     FileObject newFileObject = fileObject.getParent().getFileObject(filter.getName());
                     fileObject = newFileObject;
-
                 }
 
                 FileLock lock = fileObject.lock();
                 OutputStream os = fileObject.getOutputStream(lock);
-                Writer w = new OutputStreamWriter(os);
-                String s = filter.getCode();
-                w.write(s);
-                w.close();
+                try (Writer w = new OutputStreamWriter(os)) {
+                    String s = filter.getCode();
+                    w.write(s);
+                }
                 lock.releaseLock();
 
             } catch (IOException ex) {
@@ -427,15 +397,13 @@
     }
 
     public void initFilters() {
-
-        FileSystem fs = Repository.getDefault().getDefaultFileSystem();
-        FileObject folder = fs.getRoot().getFileObject(FOLDER_ID);
+        FileObject folder = FileUtil.getConfigRoot().getFileObject(FOLDER_ID);
         FileObject[] children = folder.getChildren();
 
-        List<CustomFilter> customFilters = new ArrayList<CustomFilter>();
-        HashMap<CustomFilter, String> afterMap = new HashMap<CustomFilter, String>();
-        Set<CustomFilter> enabledSet = new HashSet<CustomFilter>();
-        HashMap<String, CustomFilter> map = new HashMap<String, CustomFilter>();
+        List<CustomFilter> customFilters = new ArrayList<>();
+        HashMap<CustomFilter, String> afterMap = new HashMap<>();
+        Set<CustomFilter> enabledSet = new HashSet<>();
+        HashMap<String, CustomFilter> map = new HashMap<>();
 
         for (final FileObject fo : children) {
             InputStream is = null;
@@ -447,13 +415,12 @@
                 is = fo.getInputStream();
                 BufferedReader r = new BufferedReader(new InputStreamReader(is));
                 String s;
-                StringBuffer sb = new StringBuffer();
+                StringBuilder sb = new StringBuilder();
                 while ((s = r.readLine()) != null) {
                     sb.append(s);
                     sb.append("\n");
                 }
                 code = sb.toString();
-
             } catch (FileNotFoundException ex) {
                 Exceptions.printStackTrace(ex);
             } catch (IOException ex) {
@@ -488,7 +455,7 @@
 
         for (int j = 0; j < customFilters.size(); j++) {
             for (int i = 0; i < customFilters.size(); i++) {
-                List<CustomFilter> copiedList = new ArrayList<CustomFilter>(customFilters);
+                List<CustomFilter> copiedList = new ArrayList<>(customFilters);
                 for (CustomFilter cf : copiedList) {
 
                     String after = afterMap.get(cf);
@@ -573,7 +540,7 @@
 
     @Override
     public void componentOpened() {
-        Lookup.Template<FilterChain> tpl = new Lookup.Template<FilterChain>(FilterChain.class);
+        Lookup.Template<FilterChain> tpl = new Lookup.Template<>(FilterChain.class);
         result = Utilities.actionsGlobalContext().lookup(tpl);
         result.addLookupListener(this);
     }
@@ -584,13 +551,9 @@
         result = null;
     }
 
+    @Override
     public void resultChanged(LookupEvent lookupEvent) {
         setChain(Utilities.actionsGlobalContext().lookup(FilterChain.class));
-    /*
-    EditorTopComponent tc = EditorTopComponent.getActive();
-    if (tc != null) {
-    setChain(tc.getFilterChain());
-    }*/
     }
 
     public void setChain(FilterChain chain) {
@@ -598,10 +561,10 @@
     }
 
     private FileObject getFileObject(CustomFilter cf) {
-        FileObject fo = Repository.getDefault().getDefaultFileSystem().getRoot().getFileObject(FOLDER_ID + "/" + cf.getName());
+        FileObject fo = FileUtil.getConfigRoot().getFileObject(FOLDER_ID + "/" + cf.getName());
         if (fo == null) {
             try {
-                fo = org.openide.filesystems.Repository.getDefault().getDefaultFileSystem().getRoot().getFileObject(FOLDER_ID).createData(cf.getName());
+                fo = FileUtil.getConfigRoot().getFileObject(FOLDER_ID).createData(cf.getName());
             } catch (IOException ex) {
                 Exceptions.printStackTrace(ex);
             }
@@ -610,6 +573,24 @@
     }
 
     @Override
+    public boolean requestFocus(boolean temporary) {
+        view.requestFocus();
+        return super.requestFocus(temporary);
+    }
+
+    @Override
+    protected boolean requestFocusInWindow(boolean temporary) {
+        view.requestFocus();
+        return super.requestFocusInWindow(temporary);
+    }
+
+    @Override
+    public void requestActive() {
+        super.requestActive();
+        view.requestFocus();
+    }
+
+    @Override
     public void writeExternal(ObjectOutput out) throws IOException {
         super.writeExternal(out);
 
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/Bundle.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/Bundle.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,10 +1,7 @@
-# To change this template, choose Tools | Templates
-# and open the template in the editor.
-
-CTL_FilterAction=Open Filter Window
+CTL_FilterAction=Filters
+CTL_MoveFilterUpAction=Move upwards
 CTL_MoveFilterDownAction=Move downwards
-CTL_MoveFilterUpAction=Move upwards
-CTL_NewFilterAction=New filter...
 CTL_RemoveFilterAction=Remove
 CTL_RemoveFilterSettingsAction=Remove filter setting
-CTL_SaveFilterSettingsAction=Save filter settings...
+CTL_SaveFilterSettingsAction=Create filter profile...
+CTL_NewFilterAction=New filter...
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/FilterAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/FilterAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
  */
 package com.sun.hotspot.igv.filterwindow.actions;
 
-import com.sun.hotspot.igv.filterwindow.*;
+import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
 import java.awt.event.ActionEvent;
 import javax.swing.AbstractAction;
 import org.openide.util.NbBundle;
@@ -39,6 +39,7 @@
         super(NbBundle.getMessage(FilterAction.class, "CTL_FilterAction"));
     }
 
+    @Override
     public void actionPerformed(ActionEvent evt) {
         TopComponent win = FilterTopComponent.findInstance();
         win.open();
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterDownAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterDownAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,8 @@
  */
 package com.sun.hotspot.igv.filterwindow.actions;
 
+import com.sun.hotspot.igv.filter.Filter;
 import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
-import com.sun.hotspot.igv.filter.Filter;
 import javax.swing.Action;
 import org.openide.nodes.Node;
 import org.openide.util.HelpCtx;
@@ -37,6 +37,7 @@
  */
 public final class MoveFilterDownAction extends CookieAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         for (Node n : activatedNodes) {
             Filter c = n.getLookup().lookup(Filter.class);
@@ -44,19 +45,22 @@
         }
     }
 
+    @Override
     protected int mode() {
         return CookieAction.MODE_EXACTLY_ONE;
     }
 
     public MoveFilterDownAction() {
 
-        putValue(Action.SHORT_DESCRIPTION, "Move filter downwards");
+        putValue(Action.SHORT_DESCRIPTION, "Move selected filter downwards");
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(MoveFilterUpAction.class, "CTL_MoveFilterDownAction");
     }
 
+    @Override
     protected Class[] cookieClasses() {
         return new Class[]{
             Filter.class
@@ -65,7 +69,7 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/filterwindow/images/down.gif";
+        return "com/sun/hotspot/igv/filterwindow/images/down.png";
     }
 
     @Override
@@ -74,6 +78,7 @@
         putValue("noIconInMenu", Boolean.TRUE);
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterUpAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterUpAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,8 @@
  */
 package com.sun.hotspot.igv.filterwindow.actions;
 
+import com.sun.hotspot.igv.filter.Filter;
 import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
-import com.sun.hotspot.igv.filter.Filter;
 import javax.swing.Action;
 import org.openide.nodes.Node;
 import org.openide.util.HelpCtx;
@@ -37,6 +37,7 @@
  */
 public final class MoveFilterUpAction extends CookieAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         for (Node n : activatedNodes) {
             Filter c = n.getLookup().lookup(Filter.class);
@@ -44,18 +45,21 @@
         }
     }
 
+    @Override
     protected int mode() {
         return CookieAction.MODE_EXACTLY_ONE;
     }
 
     public MoveFilterUpAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Move filter upwards");
+        putValue(Action.SHORT_DESCRIPTION, "Move selected filter upwards");
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(MoveFilterUpAction.class, "CTL_MoveFilterUpAction");
     }
 
+    @Override
     protected Class[] cookieClasses() {
         return new Class[]{
             Filter.class
@@ -64,7 +68,7 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/filterwindow/images/up.gif";
+        return "com/sun/hotspot/igv/filterwindow/images/up.png";
     }
 
     @Override
@@ -73,6 +77,7 @@
         putValue("noIconInMenu", Boolean.TRUE);
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/NewFilterAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/NewFilterAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,10 +39,12 @@
         putValue(Action.SHORT_DESCRIPTION, "Create new filter");
     }
 
+    @Override
     public void performAction() {
         FilterTopComponent.findInstance().newFilter();
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(SaveFilterSettingsAction.class, "CTL_NewFilterAction");
     }
@@ -52,6 +54,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -63,6 +66,6 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/filterwindow/images/plus.gif";
+        return "com/sun/hotspot/igv/filterwindow/images/plus.png";
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,8 +23,8 @@
  */
 package com.sun.hotspot.igv.filterwindow.actions;
 
+import com.sun.hotspot.igv.filter.Filter;
 import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
-import com.sun.hotspot.igv.filter.Filter;
 import javax.swing.Action;
 import javax.swing.JOptionPane;
 import org.openide.nodes.Node;
@@ -39,13 +39,14 @@
  */
 public final class RemoveFilterAction extends CookieAction {
 
+    @Override
     protected void performAction(Node[] activatedNodes) {
         Object[] options = {"Yes",
             "No",
             "Cancel"
         };
         int n = JOptionPane.showOptionDialog(WindowManager.getDefault().getMainWindow(),
-                "Do you really want to delete " + activatedNodes.length + " filter/s?", "Delete?",
+                "Do you really want to delete " + activatedNodes.length + " filter(s)?", "Delete Filters",
                 JOptionPane.YES_NO_CANCEL_OPTION,
                 JOptionPane.QUESTION_MESSAGE,
                 null,
@@ -59,18 +60,21 @@
         }
     }
 
+    @Override
     protected int mode() {
         return CookieAction.MODE_ALL;
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(RemoveFilterAction.class, "CTL_RemoveFilterAction");
     }
 
     public RemoveFilterAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Remove filter");
+        putValue(Action.SHORT_DESCRIPTION, "Remove selected filter");
     }
 
+    @Override
     protected Class[] cookieClasses() {
         return new Class[]{
             Filter.class
@@ -85,9 +89,10 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/filterwindow/images/minus.gif";
+        return "com/sun/hotspot/igv/filterwindow/images/minus.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterSettingsAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterSettingsAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,16 +35,18 @@
  */
 public final class RemoveFilterSettingsAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         FilterTopComponent.findInstance().removeFilterSetting();
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(RemoveFilterSettingsAction.class, "CTL_RemoveFilterSettingsAction");
     }
 
     public RemoveFilterSettingsAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Remove filter profile");
+        putValue(Action.SHORT_DESCRIPTION, "Delete current filter profile");
     }
 
     @Override
@@ -52,6 +54,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -63,6 +66,6 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/filterwindow/images/delete.gif";
+        return "com/sun/hotspot/igv/filterwindow/images/delete.png";
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/SaveFilterSettingsAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/SaveFilterSettingsAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,10 +35,12 @@
  */
 public final class SaveFilterSettingsAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         FilterTopComponent.findInstance().addFilterSetting();
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(SaveFilterSettingsAction.class, "CTL_SaveFilterSettingsAction");
     }
@@ -49,9 +51,10 @@
     }
 
     public SaveFilterSettingsAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Create new filter profile");
+        putValue(Action.SHORT_DESCRIPTION, "Save filter configuration as profile...");
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -63,6 +66,6 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/filterwindow/images/add.gif";
+        return "com/sun/hotspot/igv/filterwindow/images/add.png";
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/customRightTopWsmode.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/customRightTopWsmode.xml	Tue May 05 19:27:08 2015 +0200
@@ -4,8 +4,8 @@
     <kind type="view" />
     <state type="joined" />
     <constraints>
-        <path orientation="horizontal" number="45" weight="0.21761006289308177"/>
-        <path orientation="vertical" number="0" weight="0.2510122989593188"/>
+        <path orientation="horizontal" number="90" weight="0.2"/>
+        <path orientation="vertical" number="0" weight="0.75"/>
     </constraints>
     <bounds x="0" y="0" width="0" height="0" />
     <frame state="0"/>
Binary file hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/add.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/add.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/delete.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/delete.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/down.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/down.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/minus.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/minus.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/plus.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/plus.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/up.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/up.png has changed
--- a/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/layer.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/layer.xml	Tue May 05 19:27:08 2015 +0200
@@ -18,8 +18,11 @@
             <attr name="position" intvalue="900"/>
         </file>
     </folder>
-    <folder name="Window">
-        <file name="com-sun-hotspot-igv-coordinator-actions-FilterAction.instance"/>
+    
+    <folder name="Actions">
+        <folder name="Window">
+            <file name="com-sun-hotspot-igv-filterwindow-actions-FilterAction.instance"/>
+        </folder>
     </folder>
     <folder name="Menu">
         <folder name="Window">
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/build.xml	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.graal" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.graal.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/manifest.mf	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.graal
+OpenIDE-Module-Layer: com/sun/hotspot/igv/graal/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/graal/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/nbproject/build-impl.xml	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.graal-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/nbproject/genfiles.properties	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=92ea213f
+build.xml.script.CRC32=3534d355
+build.xml.stylesheet.CRC32=a56c6a5b@2.67.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=92ea213f
+nbproject/build-impl.xml.script.CRC32=2867f2d5
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.67.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.graal</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.filter</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/nbproject/suite.properties	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/Bundle.properties	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Graal Compiler Support
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalCFGFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.graal.filters;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.filter.AbstractFilter;
+import com.sun.hotspot.igv.graph.Connection;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graph.InputSlot;
+import com.sun.hotspot.igv.graph.OutputSlot;
+import java.util.HashSet;
+import java.util.Set;
+
+public class GraalCFGFilter extends AbstractFilter {
+
+    @Override
+    public String getName() {
+        return "Graal CFG Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        Set<Connection> connectionsToRemove = new HashSet<>();
+
+        for (Figure f : d.getFigures()) {
+            Properties p = f.getProperties();
+            int predCount;
+            String predCountString = p.get("predecessorCount");
+            if (predCountString != null) {
+                predCount = Integer.parseInt(predCountString);
+            } else if (Boolean.parseBoolean(p.get("hasPredecessor"))) {
+                predCount = 1;
+            } else {
+                predCount = 0;
+            }
+            for (InputSlot is : f.getInputSlots()) {
+                if (is.getPosition() >= predCount && !"EndNode".equals(is.getProperties().get("class"))) {
+                    for (Connection c : is.getConnections()) {
+                        if (!"EndNode".equals(c.getOutputSlot().getFigure().getProperties().get("class"))) {
+                            connectionsToRemove.add(c);
+                        }
+                    }
+                }
+            }
+        }
+
+        for (Connection c : connectionsToRemove) {
+            c.remove();
+        }
+
+        Set<Figure> figuresToRemove = new HashSet<>();
+        next: for (Figure f : d.getFigures()) {
+            for (InputSlot is : f.getInputSlots()) {
+                if (!is.getConnections().isEmpty()) {
+                    continue next;
+                }
+            }
+            for (OutputSlot os : f.getOutputSlots()) {
+                if (!os.getConnections().isEmpty()) {
+                    continue next;
+                }
+            }
+            figuresToRemove.add(f);
+        }
+        d.removeAllFigures(figuresToRemove);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalColoringFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.graal.filters;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.filter.AbstractFilter;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import java.awt.Color;
+import java.util.List;
+
+public class GraalColoringFilter extends AbstractFilter {
+
+    private String colorName;
+
+    public GraalColoringFilter(String colorName) {
+        this.colorName = colorName;
+    }
+
+    @Override
+    public String getName() {
+        return "Graal Coloring Filter (" + colorName + ")";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        List<Figure> figures = d.getFigures();
+        int colors = 0;
+        for (Figure f : figures) {
+            Properties p = f.getProperties();
+            final String prop = p.get(colorName + "Color");
+            if (prop == null) {
+                continue;
+            }
+            try {
+                int color = Integer.parseInt(prop);
+                if (color > colors) {
+                    colors = color;
+                }
+            } catch (NumberFormatException nfe) {
+                // nothing to do
+            }
+        }
+        colors++;
+        for (Figure f : figures) {
+            Properties p = f.getProperties();
+            final String prop = p.get(colorName + "Color");
+            if (prop == null) {
+                continue;
+            }
+            try {
+                int color = Integer.parseInt(prop);
+                Color c = Color.getHSBColor((float) color / colors, 1.0f, 0.7f);
+                f.setColor(c);
+            } catch (NumberFormatException nfe) {
+                // nothing to do
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/GraalEdgeColorFilter.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.graal.filters;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.filter.AbstractFilter;
+import com.sun.hotspot.igv.graph.Connection;
+import com.sun.hotspot.igv.graph.Connection.ConnectionStyle;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.graph.InputSlot;
+import java.awt.Color;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * Filter that colors usage and successor edges differently.
+ *
+ * @author Peter Hofer
+ */
+public class GraalEdgeColorFilter extends AbstractFilter {
+
+    private final HashMap<String,Color> usageColor = new HashMap<>();
+    private Color otherUsageColor = Color.BLACK;
+
+    public GraalEdgeColorFilter() {
+    }
+
+    @Override
+    public String getName() {
+        return "Graal Edge Color Filter";
+    }
+
+    @Override
+    public void apply(Diagram d) {
+        List<Figure> figures = d.getFigures();
+        for (Figure f : figures) {
+            for (InputSlot is : f.getInputSlots()) {
+                for (Connection c : is.getConnections()) {
+                    String type = c.getType();
+                    if (type == "Association" && "EndNode".equals(c.getOutputSlot().getFigure().getProperties().get("class"))) {
+                        type = "Successor";
+                    }
+
+                    if (type != null) {
+                        Color typeColor = usageColor.get(type);
+                        if (typeColor == null) {
+                            c.setColor(otherUsageColor);
+                        } else {
+                            c.setColor(typeColor);
+                        }
+                        if (c.getStyle() != ConnectionStyle.DASHED && type == "Successor") {
+                            c.setStyle(ConnectionStyle.BOLD);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public Color getUsageColor(String type) {
+        return usageColor.get(type);
+    }
+
+    public void setUsageColor(String type, Color usageColor) {
+        this.usageColor.put(type, usageColor);
+    }
+
+    public Color getOtherUsageColor() {
+        return otherUsageColor;
+    }
+
+    public void setOtherUsageColor(Color otherUsageColor) {
+        this.otherUsageColor = otherUsageColor;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/callgraph.filter	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,4 @@
+colorize("name", "<init>.*", yellow);
+colorize("name", "<clinit>.*", pink);
+colorize("leaf", "1", lightGray);
+colorize("cutoff", "1", red);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/color.filter	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,31 @@
+var red =  new java.awt.Color(240, 59, 32);
+var orange = new java.awt.Color(254, 178, 76);
+var yellow = new java.awt.Color(255, 237, 160);
+var middleBlue = new java.awt.Color(100, 147, 224);
+var lightGreen = new java.awt.Color(173, 221, 142);
+var lightBlue = new java.awt.Color(200, 200, 250);
+var gray = new java.awt.Color(220, 220, 220);
+var violet = new java.awt.Color(201, 148, 199);
+var black = new java.awt.Color(0, 0, 0);
+
+colorize("category", "controlSink", red);
+colorize("category", "controlSplit", red);
+colorize("category", "merge", red);
+colorize("category", "begin", orange);
+colorize("category", "end", orange);
+colorize("category", "fixed", yellow);
+colorize("category", "state", lightGreen);
+colorize("category", "phi", middleBlue);
+colorize("category", "proxy", middleBlue);
+colorize("category", "floating", lightBlue);
+colorize("class", "ConstantLocationNode", gray);
+colorize("class", "ParameterNode", gray);
+colorize("class", "ConstantNode", gray);
+colorize("class", "GuardNode", violet);
+colorize("class", "BlackholeNode", black);
+
+var f = new com.sun.hotspot.igv.graal.filters.GraalEdgeColorFilter();
+f.setUsageColor("Successor", red);
+f.setUsageColor("Value", blue);
+f.setUsageColor("Memory", new Color(0.0, 0.5, 0.0));
+f.apply(graph);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/probability.filter	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,3 @@
+colorizeGradientWithMode("probability", 0, 500, "logarithmic");
+
+// more parameters: colorizeGradientCustom("probability", 0, 500, "logarithmic", [blue, yellow, red], [0, 0.5, 1], 16);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/reduceEdges.filter	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,3 @@
+split("class", "ConstantLocationNode");
+split("class", "ParameterNode");
+split("class", "ConstantNode");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/removeFloating.filter	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,4 @@
+remove("category", "floating");
+remove("category", "state");
+remove("category", "phi");
+remove("category", "proxy");
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/removeState.filter	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,1 @@
+remove("category", "state");
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/filters/stampColor.filter	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,16 @@
+var red =  new java.awt.Color(240, 59, 32);
+var orange = new java.awt.Color(254, 178, 76);
+var yellow = new java.awt.Color(255, 237, 160);
+var middleBlue = new java.awt.Color(100, 147, 224);
+var lightGreen = new java.awt.Color(173, 221, 142);
+var lightBlue = new java.awt.Color(200, 200, 250);
+var gray = new java.awt.Color(220, 220, 220);
+var violet = new java.awt.Color(201, 148, 199);
+
+colorize("stamp", ".*", white);
+colorize("stamp", "void", gray);
+colorize("stamp", "a.*", yellow);
+colorize("stamp", "a#.*", orange);
+colorize("stamp", "a!.*", red);
+colorize("stamp", "i.*", middleBlue);
+colorize("stamp", "f.*", lightGreen);
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graal/src/com/sun/hotspot/igv/graal/layer.xml	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
+<filesystem>
+    <folder name="Filters">
+        <file name="Coloring" url="filters/color.filter">
+            <attr name="enabled" boolvalue="true"/>
+        </file>
+        
+        
+        <file name="Stamp Coloring" url="filters/stampColor.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+      
+        <file name="Probability Coloring" url="filters/probability.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Call Graph Coloring" url="filters/callgraph.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Reduce Edges" url="filters/reduceEdges.filter">
+            <attr name="enabled" boolvalue="true"/>
+        </file>
+        
+        <file name="Remove State" url="filters/removeState.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+        
+        <file name="Remove Floating" url="filters/removeFloating.filter">
+            <attr name="enabled" boolvalue="false"/>
+        </file>
+    </folder>
+</filesystem>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -25,6 +25,7 @@
             </module-dependencies>
             <public-packages>
                 <package>com.sun.hotspot.igv.graph</package>
+                <package>com.sun.hotspot.igv.graph.services</package>
             </public-packages>
         </data>
     </configuration>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/AndSelector.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/AndSelector.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,10 +40,11 @@
         this.selector2 = s2;
     }
 
+    @Override
     public List<Figure> selected(Diagram d) {
         List<Figure> l1 = selector1.selected(d);
         List<Figure> l2 = selector2.selected(d);
-        List<Figure> result = new ArrayList<Figure>();
+        List<Figure> result = new ArrayList<>();
         for (Figure f : l2) {
             if (l1.contains(f)) {
                 result.add(f);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Block.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Block.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,14 +60,6 @@
         return succs;
     }
 
-    public Set<? extends Cluster> getPredecessors() {
-        Set<Block> succs = new HashSet<Block>();
-        for (InputBlock b : inputBlock.getPredecessors()) {
-            succs.add(diagram.getBlock(b));
-        }
-        return succs;
-    }
-
     public void setBounds(Rectangle r) {
         this.bounds = r;
     }
@@ -79,4 +71,10 @@
     public int compareTo(Cluster o) {
         return toString().compareTo(o.toString());
     }
+
+    @Override
+    public String toString() {
+        return inputBlock.getName();
+    }
 }
+
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Connection.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Connection.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
  */
 package com.sun.hotspot.igv.graph;
 
+import com.sun.hotspot.igv.data.Source;
 import com.sun.hotspot.igv.layout.Link;
 import com.sun.hotspot.igv.layout.Port;
 import java.awt.Color;
@@ -36,6 +37,11 @@
  */
 public class Connection implements Source.Provider, Link {
 
+    @Override
+    public boolean isVIP() {
+        return style == ConnectionStyle.BOLD;
+    }
+
     public enum ConnectionStyle {
 
         NORMAL,
@@ -48,13 +54,17 @@
     private Color color;
     private ConnectionStyle style;
     private List<Point> controlPoints;
+    private String label;
+    private String type;
 
-    protected Connection(InputSlot inputSlot, OutputSlot outputSlot) {
+    protected Connection(InputSlot inputSlot, OutputSlot outputSlot, String label, String type) {
         this.inputSlot = inputSlot;
         this.outputSlot = outputSlot;
+        this.label = label;
+        this.type = type;
         this.inputSlot.connections.add(this);
         this.outputSlot.connections.add(this);
-        controlPoints = new ArrayList<Point>();
+        controlPoints = new ArrayList<>();
         Figure sourceFigure = this.outputSlot.getFigure();
         Figure destFigure = this.inputSlot.getFigure();
         sourceFigure.addSuccessor(destFigure);
@@ -89,10 +99,19 @@
         style = s;
     }
 
+    @Override
     public Source getSource() {
         return source;
     }
 
+    public String getLabel() {
+        return label;
+    }
+
+    public String getType() {
+        return type;
+    }
+
     public void remove() {
         inputSlot.getFigure().removePredecessor(outputSlot.getFigure());
         inputSlot.connections.remove(this);
@@ -100,24 +119,44 @@
         outputSlot.connections.remove(this);
     }
 
+    public String getToolTipText() {
+        StringBuilder builder = new StringBuilder();
+        if (label != null) {
+            builder.append(label).append(": ");
+        }
+        if (type != null) {
+            builder.append(type).append(" ");
+        }
+        builder.append("from ");
+        builder.append(getOutputSlot().getFigure().getSource().getSourceNodes().get(0).getId());
+        builder.append(" to ");
+        builder.append(getInputSlot().getFigure().getSource().getSourceNodes().get(0).getId());
+        return builder.toString();
+    }
+
     @Override
     public String toString() {
-        return "Connection(" + getFrom().getVertex() + " to " + getTo().getVertex() + ")";
+        return "Connection('" + label + "', " + getFrom().getVertex() + " to " + getTo().getVertex() + ")";
     }
 
+    @Override
     public Port getFrom() {
         return outputSlot;
     }
 
+    @Override
     public Port getTo() {
         return inputSlot;
     }
 
+    @Override
     public List<Point> getControlPoints() {
         return controlPoints;
     }
 
+    @Override
     public void setControlPoints(List<Point> list) {
         controlPoints = list;
     }
 }
+
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,17 +28,9 @@
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.InputNode;
 import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.StringPropertyMatcher;
 import java.awt.Font;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
 
 /**
  *
@@ -51,20 +43,33 @@
     private InputGraph graph;
     private int curId;
     private String nodeText;
-    private Font font;
+    private final Font font;
+    private final Font slotFont;
+    private final Font boldFont;
 
     public Font getFont() {
         return font;
     }
 
+    public Font getSlotFont() {
+        return slotFont;
+    }
+
+    public Font getBoldFont() {
+        return boldFont;
+    }
+
     private Diagram() {
-        figures = new ArrayList<Figure>();
-        blocks = new HashMap<InputBlock, Block>();
+        figures = new ArrayList<>();
+        blocks = new LinkedHashMap<>(8);
         this.nodeText = "";
-        this.font = new Font("Serif", Font.PLAIN, 14);
+        this.font = new Font("Arial", Font.PLAIN, 12);
+        this.slotFont = new Font("Arial", Font.PLAIN, 10);
+        this.boldFont = this.font.deriveFont(Font.BOLD);
     }
 
     public Block getBlock(InputBlock b) {
+        assert blocks.containsKey(b);
         return blocks.get(b);
     }
 
@@ -72,12 +77,7 @@
         return nodeText;
     }
 
-    public void schedule(Collection<InputBlock> newBlocks) {
-        graph.schedule(newBlocks);
-        updateBlocks();
-    }
-
-    private void updateBlocks() {
+    public void updateBlocks() {
         blocks.clear();
         for (InputBlock b : graph.getBlocks()) {
             Block curBlock = new Block(b, this);
@@ -108,10 +108,26 @@
         return f;
     }
 
-    public Connection createConnection(InputSlot inputSlot, OutputSlot outputSlot) {
+    public Connection createConnection(InputSlot inputSlot, OutputSlot outputSlot, String label, String type) {
         assert inputSlot.getFigure().getDiagram() == this;
         assert outputSlot.getFigure().getDiagram() == this;
-        return new Connection(inputSlot, outputSlot);
+        return new Connection(inputSlot, outputSlot, label, type);
+    }
+
+    public Map<InputNode, Set<Figure>> calcSourceToFigureRelation() {
+        Map<InputNode, Set<Figure>> map = new HashMap<>();
+
+        for(InputNode node : this.getGraph().getNodes()) {
+            map.put(node, new HashSet<Figure>());
+        }
+
+        for(Figure f : this.getFigures()) {
+            for(InputNode node : f.getSource().getSourceNodes()) {
+                map.get(node).add(f);
+            }
+        }
+
+        return map;
     }
 
     public static Diagram createDiagram(InputGraph graph, String nodeText) {
@@ -126,11 +142,12 @@
         d.updateBlocks();
 
         Collection<InputNode> nodes = graph.getNodes();
-        HashMap<Integer, Figure> figureHash = new HashMap<Integer, Figure>();
+        Hashtable<Integer, Figure> figureHash = new Hashtable<>();
         for (InputNode n : nodes) {
             Figure f = d.createFigure();
             f.getSource().addSourceNode(n);
             f.getProperties().add(n.getProperties());
+            f.setSubgraphs(n.getSubgraphs());
             figureHash.put(n.getId(), f);
         }
 
@@ -140,23 +157,23 @@
             int to = e.getTo();
             Figure fromFigure = figureHash.get(from);
             Figure toFigure = figureHash.get(to);
+
+            if(fromFigure == null || toFigure == null) continue;
             assert fromFigure != null && toFigure != null;
 
+            int fromIndex = e.getFromIndex();
+            while (fromFigure.getOutputSlots().size() <= fromIndex) {
+                fromFigure.createOutputSlot();
+            }
+            OutputSlot outputSlot = fromFigure.getOutputSlots().get(fromIndex);
+
             int toIndex = e.getToIndex();
-
-            while (fromFigure.getOutputSlots().size() <= 0) {
-                fromFigure.createOutputSlot();
-            }
-
-            OutputSlot outputSlot = fromFigure.getOutputSlots().get(0);
-
             while (toFigure.getInputSlots().size() <= toIndex) {
                 toFigure.createInputSlot();
             }
-
             InputSlot inputSlot = toFigure.getInputSlots().get(toIndex);
 
-            Connection c = d.createConnection(inputSlot, outputSlot);
+            Connection c = d.createConnection(inputSlot, outputSlot, e.getLabel(), e.getType());
 
             if (e.getState() == InputEdge.State.NEW) {
                 c.setStyle(Connection.ConnectionStyle.BOLD);
@@ -174,7 +191,7 @@
             freeFigure(f);
         }
 
-        ArrayList<Figure> newFigures = new ArrayList<Figure>();
+        ArrayList<Figure> newFigures = new ArrayList<>();
         for (Figure f : this.figures) {
             if (!figuresToRemove.contains(f)) {
                 newFigures.add(f);
@@ -185,12 +202,12 @@
 
     private void freeFigure(Figure succ) {
 
-        List<InputSlot> inputSlots = new ArrayList<InputSlot>(succ.getInputSlots());
+        List<InputSlot> inputSlots = new ArrayList<>(succ.getInputSlots());
         for (InputSlot s : inputSlots) {
             succ.removeInputSlot(s);
         }
 
-        List<OutputSlot> outputSlots = new ArrayList<OutputSlot>(succ.getOutputSlots());
+        List<OutputSlot> outputSlots = new ArrayList<>(succ.getOutputSlots());
         for (OutputSlot s : outputSlots) {
             succ.removeOutputSlot(s);
         }
@@ -219,7 +236,7 @@
 
     public Set<Connection> getConnections() {
 
-        Set<Connection> connections = new HashSet<Connection>();
+        Set<Connection> connections = new HashSet<>();
         for (Figure f : figures) {
 
             for (InputSlot s : f.getInputSlots()) {
@@ -231,10 +248,10 @@
     }
 
     public Figure getRootFigure() {
-        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(figures);
-        Figure root = selector.selectSingle("name", "Root");
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(figures);
+        Figure root = selector.selectSingle(new StringPropertyMatcher("name", "Root"));
         if (root == null) {
-            root = selector.selectSingle("name", "Start");
+            root = selector.selectSingle(new StringPropertyMatcher("name", "Start"));
         }
         if (root == null) {
             List<Figure> rootFigures = getRootFigures();
@@ -258,9 +275,10 @@
         System.out.println("Number of figures: " + tmpFigures.size());
         System.out.println("Number of connections: " + connections.size());
 
-        List<Figure> figuresSorted = new ArrayList<Figure>(tmpFigures);
+        List<Figure> figuresSorted = new ArrayList<>(tmpFigures);
         Collections.sort(figuresSorted, new Comparator<Figure>() {
 
+            @Override
             public int compare(Figure a, Figure b) {
                 return b.getPredecessors().size() + b.getSuccessors().size() - a.getPredecessors().size() - a.getSuccessors().size();
             }
@@ -283,7 +301,7 @@
     }
 
     public List<Figure> getRootFigures() {
-        ArrayList<Figure> rootFigures = new ArrayList<Figure>();
+        ArrayList<Figure> rootFigures = new ArrayList<>();
         for (Figure f : figures) {
             if (f.getPredecessors().size() == 0) {
                 rootFigures.add(f);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,30 +23,25 @@
  */
 package com.sun.hotspot.igv.graph;
 
+import com.sun.hotspot.igv.data.InputBlock;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Source;
 import com.sun.hotspot.igv.layout.Cluster;
 import com.sun.hotspot.igv.layout.Vertex;
-import com.sun.hotspot.igv.data.Properties;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Point;
+import java.awt.*;
 import java.awt.image.BufferedImage;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
+import java.util.*;
 
-/**
- *
- * @author Thomas Wuerthinger
- */
 public class Figure extends Properties.Entity implements Source.Provider, Vertex {
 
-    public static final int INSET = 6;
-    public static final int SLOT_WIDTH = 10;
-    public static final int SLOT_START = 3;
+    public static final int INSET = 8;
+    public static int SLOT_WIDTH = 10;
+    public static final int OVERLAPPING = 6;
+    public static final int SLOT_START = 4;
+    public static final int SLOT_OFFSET = 8;
     public static final boolean VERTICAL_LAYOUT = true;
     protected List<InputSlot> inputSlots;
     protected List<OutputSlot> outputSlots;
@@ -55,6 +50,7 @@
     private Point position;
     private List<Figure> predecessors;
     private List<Figure> successors;
+    private List<InputGraph> subgraphs;
     private Color color;
     private int id;
     private String idString;
@@ -66,7 +62,7 @@
         if (heightCash == -1) {
             BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
             Graphics g = image.getGraphics();
-            g.setFont(diagram.getFont());
+            g.setFont(diagram.getFont().deriveFont(Font.BOLD));
             FontMetrics metrics = g.getFontMetrics();
             String nodeText = diagram.getNodeText();
             heightCash = nodeText.split("\n").length * metrics.getHeight() + INSET;
@@ -74,20 +70,41 @@
         return heightCash;
     }
 
+    public static <T> List<T> getAllBefore(List<T> inputList, T tIn) {
+        List<T> result = new ArrayList<>();
+        for(T t : inputList) {
+            if(t.equals(tIn)) {
+                break;
+            }
+            result.add(t);
+        }
+        return result;
+    }
+
+    public static int getSlotsWidth(Collection<? extends Slot> slots) {
+        int result = Figure.SLOT_OFFSET;
+        for(Slot s : slots) {
+            result += s.getWidth() + Figure.SLOT_OFFSET;
+        }
+        return result;
+    }
+
     public int getWidth() {
         if (widthCash == -1) {
             int max = 0;
             BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
             Graphics g = image.getGraphics();
-            g.setFont(diagram.getFont());
+            g.setFont(diagram.getFont().deriveFont(Font.BOLD));
             FontMetrics metrics = g.getFontMetrics();
-            for (String s : lines) {
+            for (String s : getLines()) {
                 int cur = metrics.stringWidth(s);
                 if (cur > max) {
                     max = cur;
                 }
             }
             widthCash = max + INSET;
+            widthCash = Math.max(widthCash, Figure.getSlotsWidth(inputSlots));
+            widthCash = Math.max(widthCash, Figure.getSlotsWidth(outputSlots));
         }
         return widthCash;
     }
@@ -95,10 +112,10 @@
     protected Figure(Diagram diagram, int id) {
         this.diagram = diagram;
         this.source = new Source();
-        inputSlots = new ArrayList<InputSlot>(5);
-        outputSlots = new ArrayList<OutputSlot>(1);
-        predecessors = new ArrayList<Figure>(6);
-        successors = new ArrayList<Figure>(6);
+        inputSlots = new ArrayList<>(5);
+        outputSlots = new ArrayList<>(1);
+        predecessors = new ArrayList<>(6);
+        successors = new ArrayList<>(6);
         this.id = id;
         idString = Integer.toString(id);
 
@@ -123,7 +140,7 @@
     }
 
     public Set<Figure> getPredecessorSet() {
-        Set<Figure> result = new HashSet<Figure>();
+        Set<Figure> result = new HashSet<>();
         for (Figure f : getPredecessors()) {
             result.add(f);
         }
@@ -131,7 +148,7 @@
     }
 
     public Set<Figure> getSuccessorSet() {
-        Set<Figure> result = new HashSet<Figure>();
+        Set<Figure> result = new HashSet<>();
         for (Figure f : getSuccessors()) {
             result.add(f);
         }
@@ -160,10 +177,20 @@
         successors.remove(f);
     }
 
+    public List<InputGraph> getSubgraphs() {
+        return subgraphs;
+    }
+
+    public void setSubgraphs(List<InputGraph> subgraphs) {
+        this.subgraphs = subgraphs;
+    }
+
+    @Override
     public void setPosition(Point p) {
         this.position = p;
     }
 
+    @Override
     public Point getPosition() {
         return position;
     }
@@ -172,6 +199,7 @@
         return diagram;
     }
 
+    @Override
     public Source getSource() {
         return source;
     }
@@ -193,7 +221,7 @@
 
         assert inputSlots.contains(s) || outputSlots.contains(s);
 
-        List<Connection> connections = new ArrayList<Connection>(s.getConnections());
+        List<Connection> connections = new ArrayList<>(s.getConnections());
         for (Connection c : connections) {
             c.remove();
         }
@@ -222,6 +250,13 @@
         return Collections.unmodifiableList(inputSlots);
     }
 
+    public Set<Slot> getSlots() {
+        Set<Slot> result = new HashSet<>();
+        result.addAll(getInputSlots());
+        result.addAll(getOutputSlots());
+        return result;
+    }
+
     public List<OutputSlot> getOutputSlots() {
         return Collections.unmodifiableList(outputSlots);
     }
@@ -248,13 +283,13 @@
         String[] result = new String[strings.length];
 
         for (int i = 0; i < strings.length; i++) {
-            result[i] = resolveString(strings[i]);
+            result[i] = resolveString(strings[i], getProperties());
         }
 
         lines = result;
     }
 
-    private String resolveString(String string) {
+    public static final String resolveString(String string, Properties properties) {
 
         StringBuilder sb = new StringBuilder();
         boolean inBrackets = false;
@@ -264,7 +299,7 @@
             char c = string.charAt(i);
             if (inBrackets) {
                 if (c == ']') {
-                    String value = getProperties().get(curIdent.toString());
+                    String value = properties.get(curIdent.toString());
                     if (value == null) {
                         value = "";
                     }
@@ -286,13 +321,16 @@
         return sb.toString();
     }
 
+    @Override
     public Dimension getSize() {
         if (VERTICAL_LAYOUT) {
             int width = Math.max(getWidth(), Figure.SLOT_WIDTH * (Math.max(inputSlots.size(), outputSlots.size()) + 1));
-            int height = getHeight() + 2 * Figure.SLOT_WIDTH;
+            int height = getHeight() + 2 * Figure.SLOT_WIDTH - 2 * Figure.OVERLAPPING;
+
+
             return new Dimension(width, height);
         } else {
-            int width = getWidth() + 2 * Figure.SLOT_WIDTH;
+            int width = getWidth() + 2 * Figure.SLOT_WIDTH - 2*Figure.OVERLAPPING;
             int height = Figure.SLOT_WIDTH * (Math.max(inputSlots.size(), outputSlots.size()) + 1);
             return new Dimension(width, height);
         }
@@ -308,21 +346,31 @@
             assert false : "Should never reach here, every figure must have at least one source node!";
             return null;
         } else {
-            Cluster result = diagram.getBlock(diagram.getGraph().getBlock(getSource().getSourceNodes().get(0)));
+            final InputBlock inputBlock = diagram.getGraph().getBlock(getSource().getSourceNodes().get(0));
+            assert inputBlock != null;
+            Cluster result = diagram.getBlock(inputBlock);
             assert result != null;
             return result;
         }
     }
 
+    @Override
     public boolean isRoot() {
-        if (source.getSourceNodes().size() > 0 && source.getSourceNodes().get(0).getProperties().get("name").equals("Root")) {
-            return true;
+
+        List<InputNode> sourceNodes = source.getSourceNodes();
+        if (sourceNodes.size() > 0 && sourceNodes.get(0).getProperties().get("name") != null) {
+            return source.getSourceNodes().get(0).getProperties().get("name").equals("Root");
         } else {
             return false;
         }
     }
 
+    @Override
     public int compareTo(Vertex f) {
         return toString().compareTo(f.toString());
     }
+
+    public Rectangle getBounds() {
+        return new Rectangle(this.getPosition(), new Dimension(this.getWidth(), this.getHeight()));
+    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InputSlot.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InputSlot.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,18 +36,24 @@
         super(figure, wantedIndex);
     }
 
+    @Override
     public int getPosition() {
         return getFigure().getInputSlots().indexOf(this);
     }
 
+    @Override
     public void setPosition(int position) {
         List<InputSlot> inputSlots = getFigure().inputSlots;
         InputSlot s = inputSlots.remove(position);
         inputSlots.add(position, s);
     }
-
+    @Override
     public Point getRelativePosition() {
-        return new Point(getFigure().getWidth() * (getPosition() + 1) / (getFigure().getInputSlots().size() + 1), Figure.SLOT_WIDTH - Figure.SLOT_START);
+        int gap = getFigure().getWidth() - Figure.getSlotsWidth(getFigure().getInputSlots());
+        double gapRatio = (double)gap / (double)(getFigure().getInputSlots().size() + 1);
+        int gapAmount = (int)((getPosition() + 1)*gapRatio);
+        return new Point(gapAmount + Figure.getSlotsWidth(Figure.getAllBefore(getFigure().getInputSlots(), this)) + getWidth()/2, -Figure.SLOT_START);
+        //return new Point((getFigure().getWidth() / (getFigure().getInputSlots().size() * 2)) * (getPosition() * 2 + 1), -Figure.SLOT_START);
     }
 
     @Override
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InvertSelector.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InvertSelector.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,9 +38,10 @@
         this.selector = selector;
     }
 
+    @Override
     public List<Figure> selected(Diagram d) {
 
-        List<Figure> result = new ArrayList<Figure>();
+        List<Figure> result = new ArrayList<>();
         List<Figure> otherResult = selector.selected(d);
         for (Figure f : d.getFigures()) {
             if (!otherResult.contains(f)) {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/MatcherSelector.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/MatcherSelector.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -39,8 +39,9 @@
         this.matcher = matcher;
     }
 
+    @Override
     public List<Figure> selected(Diagram d) {
-        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(d.getFigures());
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(d.getFigures());
         List<Figure> list = selector.selectMultiple(matcher);
         return list;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OrSelector.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OrSelector.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,6 +40,7 @@
         this.selector2 = s2;
     }
 
+    @Override
     public List<Figure> selected(Diagram d) {
 
         List<Figure> l1 = selector1.selected(d);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OutputSlot.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OutputSlot.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,17 +35,26 @@
         super(figure, wantedIndex);
     }
 
+    @Override
     public int getPosition() {
         return getFigure().getOutputSlots().indexOf(this);
     }
 
+    @Override
     public void setPosition(int position) {
         OutputSlot s = getFigure().outputSlots.remove(position);
         getFigure().outputSlots.add(position, s);
     }
 
+    @Override
     public Point getRelativePosition() {
-        return new Point(getFigure().getWidth() * (getPosition() + 1) / (getFigure().getOutputSlots().size() + 1), getFigure().getSize().height - Figure.SLOT_WIDTH + Figure.SLOT_START);
+        int gap = getFigure().getWidth() - Figure.getSlotsWidth(getFigure().getOutputSlots());
+        if(gap < 0) {
+            gap = 0;
+        }
+        double gapRatio = (double)gap / (double)(getFigure().getOutputSlots().size() + 1);
+        int gapAmount = (int)((getPosition() + 1)*gapRatio);
+        return new Point(gapAmount + Figure.getSlotsWidth(Figure.getAllBefore(getFigure().getOutputSlots(), this)) + getWidth()/2, Figure.SLOT_START);
     }
 
     @Override
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/PredecessorSelector.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/PredecessorSelector.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,9 +38,10 @@
         this.innerSelector = innerSelector;
     }
 
+    @Override
     public List<Figure> selected(Diagram d) {
         List<Figure> inner = innerSelector.selected(d);
-        List<Figure> result = new ArrayList<Figure>();
+        List<Figure> result = new ArrayList<>();
         for (Figure f : d.getFigures()) {
             boolean saved = false;
             for (Figure f2 : f.getSuccessors()) {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Selector.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Selector.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,63 +23,111 @@
  */
 package com.sun.hotspot.igv.graph;
 
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Source;
 import com.sun.hotspot.igv.layout.Port;
 import com.sun.hotspot.igv.layout.Vertex;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.image.BufferedImage;
 import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.List;
-import java.util.Comparator;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public abstract class Slot implements Port, Source.Provider {
+public abstract class Slot implements Port, Source.Provider, Properties.Provider {
 
     private int wantedIndex;
-    private String name;
-    private String shortName; // 1 - 2 characters
     private Source source;
     protected List<Connection> connections;
+    private InputNode associatedNode;
+    private Color color;
+    private String text;
+    private String shortName;
     private Figure figure;
 
     protected Slot(Figure figure, int wantedIndex) {
         this.figure = figure;
-        connections = new ArrayList<Connection>(2);
+        connections = new ArrayList<>(2);
         source = new Source();
         this.wantedIndex = wantedIndex;
-        name = "";
+        text = "";
         shortName = "";
         assert figure != null;
     }
+
+    @Override
+    public Properties getProperties() {
+        Properties p = new Properties();
+        if (source.getSourceNodes().size() > 0) {
+            for (InputNode n : source.getSourceNodes()) {
+                p.add(n.getProperties());
+            }
+        } else {
+            p.setProperty("name", "Slot");
+            p.setProperty("figure", figure.getProperties().get("name"));
+            p.setProperty("connectionCount", Integer.toString(connections.size()));
+        }
+        return p;
+    }
     public static final Comparator<Slot> slotIndexComparator = new Comparator<Slot>() {
 
+        @Override
         public int compare(Slot o1, Slot o2) {
             return o1.wantedIndex - o2.wantedIndex;
         }
     };
     public static final Comparator<Slot> slotFigureComparator = new Comparator<Slot>() {
 
+        @Override
         public int compare(Slot o1, Slot o2) {
             return o1.figure.getId() - o2.figure.getId();
         }
     };
 
+    public InputNode getAssociatedNode() {
+        return associatedNode;
+    }
+
+    public void setAssociatedNode(InputNode node) {
+        associatedNode = node;
+    }
+
+    public int getWidth() {
+        if (shortName == null || shortName.length() <= 1) {
+            return Figure.SLOT_WIDTH;
+        } else {
+            BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
+            Graphics g = image.getGraphics();
+            g.setFont(figure.getDiagram().getSlotFont().deriveFont(Font.BOLD));
+            FontMetrics metrics = g.getFontMetrics();
+            return Math.max(Figure.SLOT_WIDTH, metrics.stringWidth(shortName) + 6);
+        }
+    }
+
     public int getWantedIndex() {
         return wantedIndex;
     }
 
+    @Override
     public Source getSource() {
         return source;
     }
 
-    public String getName() {
-        return name;
+    public String getText() {
+        return text;
     }
 
     public void setShortName(String s) {
         assert s != null;
-        assert s.length() <= 2;
+//        assert s.length() <= 2;
         this.shortName = s;
 
     }
@@ -88,15 +136,27 @@
         return shortName;
     }
 
-    public boolean getShowName() {
+    public String getToolTipText() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(text);
+
+        for (InputNode n : getSource().getSourceNodes()) {
+            sb.append("Node (ID=" + n.getId() + "): " + n.getProperties().get("name"));
+            sb.append("<br>");
+        }
+
+        return sb.toString();
+    }
+
+    public boolean shouldShowName() {
         return getShortName() != null && getShortName().length() > 0;
     }
 
-    public void setName(String s) {
+    public void setText(String s) {
         if (s == null) {
             s = "";
         }
-        this.name = s;
+        this.text = s;
     }
 
     public Figure getFigure() {
@@ -104,17 +164,26 @@
         return figure;
     }
 
+    public Color getColor() {
+        return this.color;
+    }
+
+    public void setColor(Color c) {
+        color = c;
+    }
+
     public List<Connection> getConnections() {
         return Collections.unmodifiableList(connections);
     }
 
     public void removeAllConnections() {
-        List<Connection> connectionsCopy = new ArrayList<Connection>(this.connections);
+        List<Connection> connectionsCopy = new ArrayList<>(this.connections);
         for (Connection c : connectionsCopy) {
             c.remove();
         }
     }
 
+    @Override
     public Vertex getVertex() {
         return figure;
     }
@@ -123,3 +192,4 @@
 
     public abstract void setPosition(int position);
 }
+
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Source.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,100 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.graph;
-
-import com.sun.hotspot.igv.data.InputBlock;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.InputNode;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class Source {
-
-    private List<InputNode> sourceNodes;
-    private Set<Integer> set;
-
-    public Source() {
-        sourceNodes = new ArrayList<InputNode>(1);
-    }
-
-    public List<InputNode> getSourceNodes() {
-        return Collections.unmodifiableList(sourceNodes);
-    }
-
-    public Set<Integer> getSourceNodesAsSet() {
-        if (set == null) {
-            set = new HashSet<Integer>();
-            for (InputNode n : sourceNodes) {
-                int id = n.getId();
-                //if(id < 0) id = -id;
-                set.add(id);
-            }
-        }
-        return set;
-    }
-
-    public void addSourceNode(InputNode n) {
-        sourceNodes.add(n);
-        set = null;
-    }
-
-    public void removeSourceNode(InputNode n) {
-        sourceNodes.remove(n);
-        set = null;
-    }
-
-    public interface Provider {
-
-        public Source getSource();
-    }
-
-    public void setSourceNodes(List<InputNode> sourceNodes) {
-        this.sourceNodes = sourceNodes;
-        set = null;
-    }
-
-    public void addSourceNodes(Source s) {
-        for (InputNode n : s.getSourceNodes()) {
-            sourceNodes.add(n);
-        }
-        set = null;
-    }
-
-    public boolean isInBlock(InputGraph g, InputBlock blockNode) {
-
-        for (InputNode n : this.getSourceNodes()) {
-            if (g.getBlock(n) == blockNode) {
-                return true;
-            }
-        }
-        return false;
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/SuccessorSelector.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/SuccessorSelector.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -38,9 +38,10 @@
         this.innerSelector = innerSelector;
     }
 
+    @Override
     public List<Figure> selected(Diagram d) {
         List<Figure> inner = innerSelector.selected(d);
-        List<Figure> result = new ArrayList<Figure>();
+        List<Figure> result = new ArrayList<>();
         for (Figure f : d.getFigures()) {
             boolean saved = false;
             for (Figure f2 : f.getPredecessors()) {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/services/DiagramProvider.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.graph.services;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.graph.Diagram;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface DiagramProvider {
+    Diagram getDiagram();
+    ChangedEvent<DiagramProvider> getChangedEvent();
+
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterEdge.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterEdge.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -60,4 +60,8 @@
     public List<Point> getControlPoints() {
         return points;
     }
+
+    public boolean isVIP() {
+        return false;
+    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterIngoingConnection.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterIngoingConnection.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -73,4 +73,8 @@
     public List<Point> getControlPoints() {
         return controlPoints;
     }
+
+    public boolean isVIP() {
+        return false;
+    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterInputSlotNode.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterInputSlotNode.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -93,7 +93,7 @@
         outputSlot = new Port() {
 
             public Point getRelativePosition() {
-                return new Point(size.width / 2, size.height);
+                return new Point(size.width / 2, 0);//size.height);
             }
 
             public Vertex getVertex() {
@@ -183,7 +183,7 @@
 
         for (Link e : subEdges) {
             List<Point> arr = e.getControlPoints();
-            ArrayList<Point> newArr = new ArrayList<Point>();
+            ArrayList<Point> newArr = new ArrayList<Point>(arr.size());
             for (Point p : arr) {
                 if (p != null) {
                     Point p2 = new Point(p);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterOutgoingConnection.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterOutgoingConnection.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -65,4 +65,8 @@
     public List<Point> getControlPoints() {
         return intermediatePoints;
     }
+
+    public boolean isVIP() {
+        return false;
+    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterOutputSlotNode.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterOutputSlotNode.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -88,7 +88,7 @@
             public Point getRelativePosition() {
                 Point p = new Point(thisNode.getPosition());
                 p.x += ClusterNode.BORDER;
-                p.y = thisBlockNode.getSize().height;
+                p.y = 0;//thisBlockNode.getSize().height;
                 return p;
             }
 
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Edge.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Edge.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -83,6 +83,7 @@
         dest.addInEdge(this);
     }
 
+    @Override
     public String toString() {
         return "Edge (" + source + " -- " + dest + "): " + data;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Graph.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Graph.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,13 +23,7 @@
  */
 package com.sun.hotspot.igv.hierarchicallayout;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
+import java.util.*;
 
 /**
  *
@@ -42,13 +36,13 @@
     private List<Node<N, E>> nodeList;
 
     public Graph() {
-        nodes = new HashMap<Object, Node<N, E>>();
-        edges = new HashMap<Object, Edge<N, E>>();
-        nodeList = new ArrayList<Node<N, E>>();
+        nodes = new HashMap<>();
+        edges = new HashMap<>();
+        nodeList = new ArrayList<>();
     }
 
     public Node<N, E> createNode(N data, Object key) {
-        Node<N, E> n = new Node<N, E>(this, data);
+        Node<N, E> n = new Node<>(this, data);
         assert key == null || !nodes.containsKey(key);
         if (key != null) {
             nodes.put(key, n);
@@ -58,7 +52,7 @@
     }
 
     public Edge<N, E> createEdge(Node<N, E> source, Node<N, E> dest, E data, Object key) {
-        Edge<N, E> e = new Edge<N, E>(this, source, dest, data);
+        Edge<N, E> e = new Edge<>(this, source, dest, data);
         source.addOutEdge(e);
         dest.addInEdge(e);
         if (key != null) {
@@ -114,7 +108,7 @@
 
     public List<Node<N, E>> getNodesWithInDegree(int x, boolean countSelfLoops) {
 
-        List<Node<N, E>> result = new ArrayList<Node<N, E>>();
+        List<Node<N, E>> result = new ArrayList<>();
         for (Node<N, E> n : getNodes()) {
             if (n.getInDegree(countSelfLoops) == x) {
                 result.add(n);
@@ -126,7 +120,7 @@
     }
 
     private void markReachable(Node<N, E> startingNode) {
-        ArrayList<Node<N, E>> arr = new ArrayList<Node<N, E>>();
+        ArrayList<Node<N, E>> arr = new ArrayList<>();
         arr.add(startingNode);
         for (Node<N, E> n : getNodes()) {
             n.setReachable(false);
@@ -151,7 +145,7 @@
             n.setActive(false);
         }
 
-        Queue<Node<N, E>> queue = new LinkedList<Node<N, E>>();
+        Queue<Node<N, E>> queue = new LinkedList<>();
         queue.add(startingNode);
         startingNode.setVisited(true);
         int layer = 0;
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,12 +44,12 @@
  */
 public class HierarchicalClusterLayoutManager implements LayoutManager {
 
-    private OldHierarchicalLayoutManager.Combine combine;
-    private LayoutManager subManager = new OldHierarchicalLayoutManager(combine);
-    private LayoutManager manager = new OldHierarchicalLayoutManager(combine, 150);
+    private HierarchicalLayoutManager.Combine combine;
+    private LayoutManager subManager = new HierarchicalLayoutManager(combine);
+    private LayoutManager manager = new HierarchicalLayoutManager(combine);
     private static final boolean TRACE = false;
 
-    public HierarchicalClusterLayoutManager(OldHierarchicalLayoutManager.Combine combine) {
+    public HierarchicalClusterLayoutManager(HierarchicalLayoutManager.Combine combine) {
         this.combine = combine;
     }
 
@@ -57,6 +57,10 @@
         doLayout(graph, new HashSet<Vertex>(), new HashSet<Vertex>(), new HashSet<Link>());
     }
 
+    public void doLayout(LayoutGraph graph, Set<? extends Link> importantLinks) {
+        doLayout(graph);
+    }
+
     public void setSubManager(LayoutManager manager) {
         this.subManager = manager;
     }
@@ -116,7 +120,7 @@
 
         for (Vertex v : graph.getVertices()) {
             Cluster c = v.getCluster();
-            assert c != null;
+            assert c != null : "Cluster of vertex " + v + " is null!";
             clusterNodes.get(c).addSubNode(v);
         }
 
@@ -130,9 +134,9 @@
             Cluster toCluster = toVertex.getCluster();
 
             Port samePort = null;
-            if (combine == OldHierarchicalLayoutManager.Combine.SAME_INPUTS) {
+            if (combine == HierarchicalLayoutManager.Combine.SAME_INPUTS) {
                 samePort = toPort;
-            } else if (combine == OldHierarchicalLayoutManager.Combine.SAME_OUTPUTS) {
+            } else if (combine == HierarchicalLayoutManager.Combine.SAME_OUTPUTS) {
                 samePort = fromPort;
             }
 
@@ -196,7 +200,7 @@
 
         for (Cluster c : cluster) {
             ClusterNode n = clusterNodes.get(c);
-            subManager.doLayout(new LayoutGraph(n.getSubEdges(), n.getSubNodes()), clusterInputSlotSet.get(c), clusterOutputSlotSet.get(c), new HashSet<Link>());
+            subManager.doLayout(new LayoutGraph(n.getSubEdges(), n.getSubNodes()), new HashSet<Link>());
             n.updateSize();
         }
 
@@ -206,7 +210,7 @@
             ((ClusterNode) v).setRoot(true);
         }
 
-        manager.doLayout(new LayoutGraph(clusterEdges, clusterNodeSet), new HashSet<Vertex>(), new HashSet<Vertex>(), interClusterEdges);
+        manager.doLayout(new LayoutGraph(clusterEdges, clusterNodeSet), interClusterEdges);
 
         for (Cluster c : cluster) {
             ClusterNode n = clusterNodes.get(c);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,18 +29,7 @@
 import com.sun.hotspot.igv.layout.Vertex;
 import java.awt.Dimension;
 import java.awt.Point;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Queue;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.Stack;
-import java.util.TreeSet;
+import java.util.*;
 
 /**
  *
@@ -54,10 +43,11 @@
     public static final int CROSSING_ITERATIONS = 2;
     public static final int DUMMY_HEIGHT = 1;
     public static final int DUMMY_WIDTH = 1;
-    public static final int X_OFFSET = 9;
-    public static final int LAYER_OFFSET = 30;
+    public static final int X_OFFSET = 8;
+    public static final int LAYER_OFFSET = 8;
     public static final int MAX_LAYER_LENGTH = -1;
     public static final int MIN_LAYER_DIFFERENCE = 1;
+    public static final int VIP_BONUS = 10;
 
     public enum Combine {
 
@@ -85,8 +75,6 @@
     private LayoutGraph graph;
     private List<LayoutNode>[] layers;
     private int layerCount;
-    private Set<? extends Vertex> firstLayerHint;
-    private Set<? extends Vertex> lastLayerHint;
     private Set<? extends Link> importantLinks;
     private Set<Link> linksToFollow;
 
@@ -101,11 +89,13 @@
         public int yOffset;
         public int bottomYOffset;
         public Vertex vertex; // Only used for non-dummy nodes, otherwise null
-        public List<LayoutEdge> preds = new ArrayList<LayoutEdge>();
-        public List<LayoutEdge> succs = new ArrayList<LayoutEdge>();
-        public HashMap<Integer, Integer> outOffsets = new HashMap<Integer, Integer>();
-        public HashMap<Integer, Integer> inOffsets = new HashMap<Integer, Integer>();
+
+        public List<LayoutEdge> preds = new ArrayList<>();
+        public List<LayoutEdge> succs = new ArrayList<>();
+        public HashMap<Integer, Integer> outOffsets = new HashMap<>();
+        public HashMap<Integer, Integer> inOffsets = new HashMap<>();
         public int pos = -1; // Position within layer
+
         public int crossingNumber;
 
         @Override
@@ -121,6 +111,7 @@
         public int relativeFrom;
         public int relativeTo;
         public Link link;
+        public boolean vip;
     }
 
     private abstract class AlgorithmPart {
@@ -171,7 +162,7 @@
         this.layerOffset = LAYER_OFFSET;
         this.maxLayerLength = MAX_LAYER_LENGTH;
         this.minLayerDifference = MIN_LAYER_DIFFERENCE;
-        this.linksToFollow = new HashSet<Link>();
+        this.linksToFollow = new HashSet<>();
     }
 
     public int getMaxLayerLength() {
@@ -186,26 +177,26 @@
         minLayerDifference = v;
     }
 
+    @Override
     public void doLayout(LayoutGraph graph) {
-        doLayout(graph, new HashSet<Vertex>(), new HashSet<Vertex>(), new HashSet<Link>());
+        doLayout(graph, new HashSet<Link>());
 
     }
 
-    public void doLayout(LayoutGraph graph, Set<? extends Vertex> firstLayerHint, Set<? extends Vertex> lastLayerHint, Set<? extends Link> importantLinks) {
+    @Override
+    public void doLayout(LayoutGraph graph, Set<? extends Link> importantLinks) {
 
         this.importantLinks = importantLinks;
         this.graph = graph;
-        this.firstLayerHint = firstLayerHint;
-        this.lastLayerHint = lastLayerHint;
 
-        vertexToLayoutNode = new HashMap<Vertex, LayoutNode>();
-        reversedLinks = new HashSet<Link>();
-        reversedLinkStartPoints = new HashMap<Link, List<Point>>();
-        reversedLinkEndPoints = new HashMap<Link, List<Point>>();
-        bottomEdgeHash = new HashMap<LayoutEdge, LayoutEdge>();
-        nodes = new ArrayList<LayoutNode>();
-        splitStartPoints = new HashMap<Link, List<Point>>();
-        splitEndPoints = new HashMap<Link, List<Point>>();
+        vertexToLayoutNode = new HashMap<>();
+        reversedLinks = new HashSet<>();
+        reversedLinkStartPoints = new HashMap<>();
+        reversedLinkEndPoints = new HashMap<>();
+        bottomEdgeHash = new HashMap<>();
+        nodes = new ArrayList<>();
+        splitStartPoints = new HashMap<>();
+        splitEndPoints = new HashMap<>();
 
         // #############################################################
         // Step 1: Build up data structure
@@ -216,7 +207,7 @@
         new ReverseEdges().start();
 
         for (LayoutNode n : nodes) {
-            ArrayList<LayoutEdge> tmpArr = new ArrayList<LayoutEdge>();
+            ArrayList<LayoutEdge> tmpArr = new ArrayList<>();
             for (LayoutEdge e : n.succs) {
                 if (importantLinks.contains(e.link)) {
                     tmpArr.add(e);
@@ -224,7 +215,6 @@
             }
 
             for (LayoutEdge e : tmpArr) {
-                //System.out.println("Removed " + e);
                 e.from.succs.remove(e);
                 e.to.preds.remove(e);
             }
@@ -244,8 +234,7 @@
 
         // #############################################################
         // STEP 7: Assign X coordinates
-        //new AssignXCoordinates().start();
-        new AssignXCoordinates2().start();
+        new AssignXCoordinates().start();
 
         // #############################################################
         // STEP 6: Assign Y coordinates
@@ -260,10 +249,11 @@
 
         private int pointCount;
 
+        @Override
         protected void run() {
 
-            HashMap<Vertex, Point> vertexPositions = new HashMap<Vertex, Point>();
-            HashMap<Link, List<Point>> linkPositions = new HashMap<Link, List<Point>>();
+            HashMap<Vertex, Point> vertexPositions = new HashMap<>();
+            HashMap<Link, List<Point>> linkPositions = new HashMap<>();
             for (Vertex v : graph.getVertices()) {
                 LayoutNode n = vertexToLayoutNode.get(v);
                 assert !vertexPositions.containsKey(v);
@@ -274,12 +264,12 @@
 
                 for (LayoutEdge e : n.preds) {
                     if (e.link != null) {
-                        ArrayList<Point> points = new ArrayList<Point>();
+                        ArrayList<Point> points = new ArrayList<>();
 
-                        Point p = new Point(e.to.x + e.relativeTo, e.to.y + e.to.yOffset);
+                        Point p = new Point(e.to.x + e.relativeTo, e.to.y + e.to.yOffset + e.link.getTo().getRelativePosition().y);
                         points.add(p);
                         if (e.to.inOffsets.containsKey(e.relativeTo)) {
-                            points.add(new Point(p.x, p.y + e.to.inOffsets.get(e.relativeTo)));
+                            points.add(new Point(p.x, p.y + e.to.inOffsets.get(e.relativeTo) + e.link.getTo().getRelativePosition().y));
                         }
 
                         LayoutNode cur = e.from;
@@ -299,16 +289,14 @@
                             cur = curEdge.from;
                         }
 
-                        p = new Point(cur.x + curEdge.relativeFrom, cur.y + cur.height - cur.bottomYOffset);
+                        p = new Point(cur.x + curEdge.relativeFrom, cur.y + cur.height - cur.bottomYOffset + (curEdge.link == null ? 0 : curEdge.link.getFrom().getRelativePosition().y));
                         if (curEdge.from.outOffsets.containsKey(curEdge.relativeFrom)) {
-                            points.add(new Point(p.x, p.y + curEdge.from.outOffsets.get(curEdge.relativeFrom)));
+                            points.add(new Point(p.x, p.y + curEdge.from.outOffsets.get(curEdge.relativeFrom) + (curEdge.link == null ? 0 : curEdge.link.getFrom().getRelativePosition().y)));
                         }
                         points.add(p);
 
                         Collections.reverse(points);
 
-
-
                         if (cur.vertex == null && cur.preds.size() == 0) {
 
                             if (reversedLinkEndPoints.containsKey(e.link)) {
@@ -359,17 +347,17 @@
 
                 for (LayoutEdge e : n.succs) {
                     if (e.link != null) {
-                        ArrayList<Point> points = new ArrayList<Point>();
-                        Point p = new Point(e.from.x + e.relativeFrom, e.from.y + e.from.height - e.from.bottomYOffset);
+                        ArrayList<Point> points = new ArrayList<>();
+                        Point p = new Point(e.from.x + e.relativeFrom, e.from.y + e.from.height - e.from.bottomYOffset + e.link.getFrom().getRelativePosition().y);
                         points.add(p);
                         if (e.from.outOffsets.containsKey(e.relativeFrom)) {
-                            points.add(new Point(p.x, p.y + e.from.outOffsets.get(e.relativeFrom)));
+                            points.add(new Point(p.x, p.y + e.from.outOffsets.get(e.relativeFrom) + e.link.getFrom().getRelativePosition().y));
                         }
 
                         LayoutNode cur = e.to;
                         LayoutNode other = e.from;
                         LayoutEdge curEdge = e;
-                        while (cur.vertex == null && cur.succs.size() != 0) {
+                        while (cur.vertex == null && !cur.succs.isEmpty()) {
                             if (points.size() > 1 && points.get(points.size() - 1).x == cur.x + cur.width / 2 && points.get(points.size() - 2).x == cur.x + cur.width / 2) {
                                 points.remove(points.size() - 1);
                             }
@@ -378,7 +366,7 @@
                                 points.remove(points.size() - 1);
                             }
                             points.add(new Point(cur.x + cur.width / 2, cur.y + cur.height));
-                            if (cur.succs.size() == 0) {
+                            if (cur.succs.isEmpty()) {
                                 break;
                             }
                             assert cur.succs.size() == 1;
@@ -386,15 +374,13 @@
                             cur = curEdge.to;
                         }
 
-
-                        p = new Point(cur.x + curEdge.relativeTo, cur.y + cur.yOffset);
+                        p = new Point(cur.x + curEdge.relativeTo, cur.y + cur.yOffset + ((curEdge.link == null) ? 0 : curEdge.link.getTo().getRelativePosition().y));
                         points.add(p);
                         if (curEdge.to.inOffsets.containsKey(curEdge.relativeTo)) {
-                            points.add(new Point(p.x, p.y + curEdge.to.inOffsets.get(curEdge.relativeTo)));
+                            points.add(new Point(p.x, p.y + curEdge.to.inOffsets.get(curEdge.relativeTo) + ((curEdge.link == null) ? 0 : curEdge.link.getTo().getRelativePosition().y)));
                         }
 
-
-                        if (cur.succs.size() == 0 && cur.vertex == null) {
+                        if (cur.succs.isEmpty() && cur.vertex == null) {
                             if (reversedLinkStartPoints.containsKey(e.link)) {
                                 for (Point p1 : reversedLinkStartPoints.get(e.link)) {
                                     points.add(0, new Point(p1.x + other.x, p1.y + other.y));
@@ -495,13 +481,14 @@
 
         public float d;
         public int orderNumber = -1;
-        public ArrayList<LayoutNode> nodes = new ArrayList<LayoutNode>();
-        public HashSet<Segment> succs = new HashSet<Segment>();
-        public HashSet<Segment> preds = new HashSet<Segment>();
+        public ArrayList<LayoutNode> nodes = new ArrayList<>();
+        public HashSet<Segment> succs = new HashSet<>();
+        public HashSet<Segment> preds = new HashSet<>();
         public Region region;
     }
     private static final Comparator<Segment> segmentComparator = new Comparator<Segment>() {
 
+        @Override
         public int compare(Segment s1, Segment s2) {
             return s1.orderNumber - s2.orderNumber;
         }
@@ -511,26 +498,46 @@
 
         public float d;
         public int minOrderNumber;
-        public SortedSet<Segment> segments = new TreeSet<Segment>(segmentComparator);
-        public HashSet<Region> succs = new HashSet<Region>(4);
-        public HashSet<Region> preds = new HashSet<Region>(4);
+        public SortedSet<Segment> segments = new TreeSet<>(segmentComparator);
+        public HashSet<Region> succs = new HashSet<>(4);
+        public HashSet<Region> preds = new HashSet<>(4);
     }
     private static final Comparator<Region> regionComparator = new Comparator<Region>() {
 
+        @Override
         public int compare(Region r1, Region r2) {
             return r1.minOrderNumber - r2.minOrderNumber;
         }
     };
     private static final Comparator<LayoutNode> nodePositionComparator = new Comparator<LayoutNode>() {
 
+        @Override
         public int compare(LayoutNode n1, LayoutNode n2) {
             return n1.pos - n2.pos;
         }
     };
     private static final Comparator<LayoutNode> nodeProcessingDownComparator = new Comparator<LayoutNode>() {
-
+        @Override
         public int compare(LayoutNode n1, LayoutNode n2) {
+            int n1VIP = 0;
+            for (LayoutEdge e : n1.preds) {
+                if (e.vip) {
+                    n1VIP++;
+                }
+            }
+            int n2VIP = 0;
+            for (LayoutEdge e : n2.preds) {
+                if (e.vip) {
+                    n2VIP++;
+                }
+            }
+            if (n1VIP != n2VIP) {
+                return n2VIP - n1VIP;
+            }
             if (n1.vertex == null) {
+                if (n2.vertex == null) {
+                    return 0;
+                }
                 return -1;
             }
             if (n2.vertex == null) {
@@ -541,8 +548,27 @@
     };
     private static final Comparator<LayoutNode> nodeProcessingUpComparator = new Comparator<LayoutNode>() {
 
+        @Override
         public int compare(LayoutNode n1, LayoutNode n2) {
+            int n1VIP = 0;
+            for (LayoutEdge e : n1.succs) {
+                if (e.vip) {
+                    n1VIP++;
+                }
+            }
+            int n2VIP = 0;
+            for (LayoutEdge e : n2.succs) {
+                if (e.vip) {
+                    n2VIP++;
+                }
+            }
+            if (n1VIP != n2VIP) {
+                return n2VIP - n1VIP;
+            }
             if (n1.vertex == null) {
+                if (n2.vertex == null) {
+                    return 0;
+                }
                 return -1;
             }
             if (n2.vertex == null) {
@@ -552,7 +578,7 @@
         }
     };
 
-    private class AssignXCoordinates2 extends AlgorithmPart {
+    private class AssignXCoordinates extends AlgorithmPart {
 
         private ArrayList<Integer>[] space;
         private ArrayList<LayoutNode>[] downProcessingOrder;
@@ -564,16 +590,21 @@
             }
         }
 
-        protected void run() {
-
+        @SuppressWarnings("unchecked")
+        private void createArrays() {
             space = new ArrayList[layers.length];
             downProcessingOrder = new ArrayList[layers.length];
             upProcessingOrder = new ArrayList[layers.length];
+        }
+
+        @Override
+        protected void run() {
+            createArrays();
 
             for (int i = 0; i < layers.length; i++) {
-                space[i] = new ArrayList<Integer>();
-                downProcessingOrder[i] = new ArrayList<LayoutNode>();
-                upProcessingOrder[i] = new ArrayList<LayoutNode>();
+                space[i] = new ArrayList<>();
+                downProcessingOrder[i] = new ArrayList<>();
+                upProcessingOrder[i] = new ArrayList<>();
 
                 int curX = 0;
                 for (LayoutNode n : layers[i]) {
@@ -590,72 +621,106 @@
             initialPositions();
             for (int i = 0; i < SWEEP_ITERATIONS; i++) {
                 sweepDown();
-                sweepUp();
+                adjustSpace();
+                sweepUp(false);
+                adjustSpace();
             }
 
-            for (int i = 0; i < SWEEP_ITERATIONS; i++) {
-                doubleSweep();
+            sweepDown();
+            adjustSpace();
+            sweepUp(true);
+        }
+
+        private void adjustSpace() {
+            for (int i = 0; i < layers.length; i++) {
+                //               space[i] = new ArrayList<>();
+                int curX = 0;
+                for (LayoutNode n : layers[i]) {
+                    space[i].add(n.x);
+//                    curX += n.width + xOffset;
+                }
             }
         }
 
         private int calculateOptimalDown(LayoutNode n) {
-
-            List<Integer> values = new ArrayList<Integer>();
-            if (n.preds.size() == 0) {
+            int size = n.preds.size();
+            if (size == 0) {
                 return n.x;
             }
+            int vipCount = 0;
             for (LayoutEdge e : n.preds) {
-                int cur = e.from.x + e.relativeFrom - e.relativeTo;
-                values.add(cur);
+                if (e.vip) {
+                    vipCount++;
+                }
             }
-            return median(values);
+
+            if (vipCount == 0) {
+                int[] values = new int[size];
+                for (int i = 0; i < size; i++) {
+                    LayoutEdge e = n.preds.get(i);
+                    values[i] = e.from.x + e.relativeFrom - e.relativeTo;
+                }
+                return median(values);
+            } else {
+                int z = 0;
+                int[] values = new int[vipCount];
+                for (int i = 0; i < size; i++) {
+                    LayoutEdge e = n.preds.get(i);
+                    if (e.vip) {
+                        values[z++] = e.from.x + e.relativeFrom - e.relativeTo;
+                    }
+                }
+                return median(values);
+            }
         }
 
         private int calculateOptimalBoth(LayoutNode n) {
-
-            List<Integer> values = new ArrayList<Integer>();
-            if (n.preds.size() == 0 + n.succs.size()) {
+            if (n.preds.size() == n.succs.size()) {
                 return n.x;
             }
+
+            int[] values = new int[n.preds.size() + n.succs.size()];
+            int i = 0;
+
             for (LayoutEdge e : n.preds) {
-                int cur = e.from.x + e.relativeFrom - e.relativeTo;
-                values.add(cur);
+                values[i] = e.from.x + e.relativeFrom - e.relativeTo;
+                i++;
             }
 
             for (LayoutEdge e : n.succs) {
-                int cur = e.to.x + e.relativeTo - e.relativeFrom;
-                values.add(cur);
+                values[i] = e.to.x + e.relativeTo - e.relativeFrom;
+                i++;
             }
 
             return median(values);
         }
 
         private int calculateOptimalUp(LayoutNode n) {
-
-            //List<Integer> values = new ArrayList<Integer>();
             int size = n.succs.size();
             if (size == 0) {
                 return n.x;
+            }
+            int[] values = new int[size];
+            for (int i = 0; i < size; i++) {
+                LayoutEdge e = n.succs.get(i);
+                values[i] = e.to.x + e.relativeTo - e.relativeFrom;
+                if (e.vip) {
+                    return values[i];
+                }
+            }
+            return median(values);
+        }
+
+        private int median(int[] values) {
+            Arrays.sort(values);
+            if (values.length % 2 == 0) {
+                return (values[values.length / 2 - 1] + values[values.length / 2]) / 2;
             } else {
-                int result = 0;
-                for (LayoutEdge e : n.succs) {
-                    int cur = e.to.x + e.relativeTo - e.relativeFrom;
-                    result += cur;
-                }
-                return result / size; //median(values);
+                return values[values.length / 2];
             }
         }
 
-        private int median(List<Integer> values) {
-            Collections.sort(values);
-            if (values.size() % 2 == 0) {
-                return (values.get(values.size() / 2 - 1) + values.get(values.size() / 2)) / 2;
-            } else {
-                return values.get(values.size() / 2);
-            }
-        }
-
-        private void sweepUp() {
+        private void sweepUp(boolean onlyDummies) {
             for (int i = layers.length - 1; i >= 0; i--) {
                 NodeRow r = new NodeRow(space[i]);
                 for (LayoutNode n : upProcessingOrder[i]) {
@@ -663,14 +728,6 @@
                     r.insert(n, optimal);
                 }
             }
-        /*
-        for(int i=0; i<layers.length; i++) {
-        NodeRow r = new NodeRow(space[i]);
-        for(LayoutNode n : upProcessingOrder[i]) {
-        int optimal = calculateOptimalUp(n);
-        r.insert(n, optimal);
-        }
-        }*/
         }
 
         private void doubleSweep() {
@@ -700,7 +757,7 @@
         private ArrayList<Integer> space;
 
         public NodeRow(ArrayList<Integer> space) {
-            treeSet = new TreeSet<LayoutNode>(nodePositionComparator);
+            treeSet = new TreeSet<>(nodePositionComparator);
             this.space = space;
         }
 
@@ -739,357 +796,15 @@
                     n.x = pos;
                 }
 
-                assert minX <= maxX;
+                assert minX <= maxX : minX + " vs " + maxX;
             }
 
             treeSet.add(n);
         }
     }
-
-    private class AssignXCoordinates extends AlgorithmPart {
-
-        HashMap<LayoutNode, Segment> hashMap = new HashMap<LayoutNode, Segment>();
-        ArrayList<Segment> segments = new ArrayList<Segment>();
-
-        private void generateSegments() {
-
-            for (int i = 0; i < layerCount; i++) {
-                for (LayoutNode n : layers[i]) {
-                    if (!hashMap.containsKey(n)) {
-                        Segment s = new Segment();
-                        segments.add(s);
-                        LayoutNode curNode = n;
-
-                        int maxLength = 0;
-                        while (curNode.succs.size() == 1 && curNode.preds.size() == 1) {
-                            s.nodes.add(curNode);
-                            assert !hashMap.containsKey(curNode);
-                            hashMap.put(curNode, s);
-                            curNode = curNode.succs.get(0).to;
-                            maxLength++;
-                        //if(maxLength > 10) break;
-                        }
-
-                        if (s.nodes.size() > 0 && curNode.preds.size() == 1 && curNode.vertex == null) {
-                            s.nodes.add(curNode);
-                            assert !hashMap.containsKey(curNode);
-                            hashMap.put(curNode, s);
-                        }
-
-                        if (s.nodes.size() == 0) {
-                            // Simple segment with a single node
-                            s.nodes.add(n);
-                            hashMap.put(n, s);
-                        }
-                    }
-                }
-            }
-        }
-
-        private void addEdges() {
-
-            for (int i = 0; i < layerCount; i++) {
-                LayoutNode prev = null;
-                for (LayoutNode n : layers[i]) {
-
-                    if (prev != null) {
-                        Segment s1 = hashMap.get(prev);
-                        Segment s2 = hashMap.get(n);
-
-                        if (s1 != s2) {
-                            s1.succs.add(s2);
-                            s2.preds.add(s1);
-                        }
-                    }
-                    prev = n;
-
-                }
-            }
-        }
-
-        private void topologicalSorting() {
-
-            Queue<Segment> queue = new LinkedList<Segment>();
-
-            int index = 0;
-            ArrayList<Segment> newList = new ArrayList<Segment>();
-            for (Segment s : segments) {
-                if (s.preds.size() == 0) {
-                    s.orderNumber = index;
-                    newList.add(s);
-                    index++;
-                    queue.add(s);
-                }
-            }
-
-            while (!queue.isEmpty()) {
-                Segment s = queue.remove();
-
-                for (Segment succ : s.succs) {
-                    succ.preds.remove(s);
-                    if (succ.preds.size() == 0) {
-                        queue.add(succ);
-                        succ.orderNumber = index;
-                        newList.add(succ);
-                        index++;
-                    }
-                }
-            }
-
-            segments = newList;
-        }
-
-        private void initialPositions() {
-
-            int[] minPos = new int[layers.length];
-
-            for (Segment s : segments) {
-                int max = 0;
-                for (LayoutNode n : s.nodes) {
-                    int x = minPos[n.layer];
-                    if (x > max) {
-                        max = x;
-                    }
-                }
-
-                for (LayoutNode n : s.nodes) {
-                    minPos[n.layer] = max + n.width + xOffset;
-                    n.x = max;
-                }
-            }
-        }
-
-        private int predSum(LayoutNode n) {
-            int sum = 0;
-            for (LayoutEdge e : n.preds) {
-                assert e.to == n;
-                //sum += (e.from.x + e.relativeFrom + (int)hashMap.get(e.from).d) - (e.to.x + e.relativeTo + (int)hashMap.get(e.to).d);
-                sum += (e.from.x + e.relativeFrom) - (e.to.x + e.relativeTo);
-            }
-
-            return sum;
-        }
-
-        private int succSum(LayoutNode n) {
-            int sum = 0;
-            for (LayoutEdge e : n.succs) {
-
-                assert e.from == n;
-                sum += (e.to.x + e.relativeTo) - (e.from.x + e.relativeFrom);
-            //sum += (e.to.x + e.relativeTo + (int)hashMap.get(e.to).d) - (e.from.x + e.relativeFrom + (int)hashMap.get(e.from).d);
-            }
-
-            return sum;
-
-        }
-
-        private void downValues() {
-
-            for (Segment s : segments) {
-                downValues(s);
-
-            }
-
-        }
-
-        private void downValues(Segment s) {
-            LayoutNode n = s.nodes.get(0); // Only first node needed, all other have same coordinate
-
-            if (n.preds.size() == 0) {
-                // Value is 0.0;
-                if (n.succs.size() == 0) {
-                    s.d = 0.0f;
-                } else {
-                    s.d = (((float) succSum(n) / (float) n.succs.size())) / 2;
-                }
-            } else {
-                s.d = (float) predSum(n) / (float) n.preds.size();
-            }
-        }
-
-        private void upValues() {
-            for (Segment s : segments) {
-                upValues(s);
-            }
-        }
-
-        private void upValues(Segment s) {
-            LayoutNode n = s.nodes.get(0); // Only first node needed, all other have same coordinate
-
-            if (n.succs.size() == 0) {
-                // Value is 0.0;
-                if (n.preds.size() == 0) {
-                    s.d = 0.0f;
-                } else {
-                    s.d = (float) predSum(n) / (float) n.preds.size();
-                }
-            } else {
-                s.d = ((float) succSum(n) / (float) n.succs.size()) / 2;
-            }
-        }
-
-        private void sweep(boolean down) {
-
-            if (down) {
-                downValues();
-            } else {
-                upValues();
-            }
-
-            SortedSet<Region> regions = new TreeSet<Region>(regionComparator);
-            for (Segment s : segments) {
-                s.region = new Region();
-                s.region.minOrderNumber = s.orderNumber;
-                s.region.segments.add(s);
-                s.region.d = s.d;
-                regions.add(s.region);
-            }
-
-            for (Segment s : segments) {
-                for (LayoutNode n : s.nodes) {
-                    if (n.pos != 0) {
-                        LayoutNode prevNode = layers[n.layer].get(n.pos - 1);
-                        if (prevNode.x + prevNode.width + xOffset == n.x) {
-                            Segment other = hashMap.get(prevNode);
-                            Region r1 = s.region;
-                            Region r2 = other.region;
-                            // They are close together
-                            if (r1 != r2 && r2.d >= r1.d) {
-
-                                if (r2.segments.size() < r1.segments.size()) {
-
-                                    r1.d = (r1.d * r1.segments.size() + r2.d * r2.segments.size()) / (r1.segments.size() + r2.segments.size());
-
-                                    for (Segment tempS : r2.segments) {
-                                        r1.segments.add(tempS);
-                                        tempS.region = r1;
-                                        r1.minOrderNumber = Math.min(r1.minOrderNumber, tempS.orderNumber);
-                                    }
-
-                                    regions.remove(r2);
-                                } else {
-
-                                    r2.d = (r1.d * r1.segments.size() + r2.d * r2.segments.size()) / (r1.segments.size() + r2.segments.size());
-
-                                    for (Segment tempS : r1.segments) {
-                                        r2.segments.add(tempS);
-                                        tempS.region = r2;
-                                        r2.minOrderNumber = Math.min(r2.minOrderNumber, tempS.orderNumber);
-                                    }
-
-                                    regions.remove(r1);
-                                }
-                            }
-                        }
-                    }
-                }
-            }
-
-
-
-            ArrayList<Region> reversedRegions = new ArrayList<Region>();
-            for (Region r : regions) {
-                if (r.d < 0) {
-                    processRegion(r, down);
-                } else {
-                    reversedRegions.add(0, r);
-                }
-            }
-
-            for (Region r : reversedRegions) {
-                processRegion(r, down);
-            }
-
-        }
-
-        private void processRegion(Region r, boolean down) {
-
-            // Do not move
-            if ((int) r.d == 0) {
-                return;
-            }
-
-            ArrayList<Segment> arr = new ArrayList<Segment>();
-            for (Segment s : r.segments) {
-                arr.add(s);
-            }
-
-            if (r.d > 0) {
-                Collections.reverse(arr);
-            }
-
-            for (Segment s : arr) {
-
-
-                int min = (int) r.d;
-                if (min < 0) {
-                    min = -min;
-                }
-
-                for (LayoutNode n : s.nodes) {
-
-                    int layer = n.layer;
-                    int pos = n.pos;
-
-
-                    if (r.d > 0) {
-
-                        if (pos != layers[layer].size() - 1) {
-
-                            int off = layers[layer].get(pos + 1).x - n.x - xOffset - n.width;
-                            assert off >= 0;
-                            if (off < min) {
-                                min = off;
-                            }
-                        }
-
-                    } else {
-
-                        if (pos != 0) {
-
-                            int off = n.x - xOffset - layers[layer].get(pos - 1).x - layers[layer].get(pos - 1).width;
-                            assert off >= 0;
-                            if (off < min) {
-                                min = off;
-                            }
-                        }
-                    }
-                }
-
-                assert min >= 0;
-                if (min != 0) {
-                    for (LayoutNode n : s.nodes) {
-                        if (r.d > 0) {
-                            n.x += min;
-                        } else {
-                            n.x -= min;
-                        }
-
-                    }
-                }
-            }
-        }
-
-        protected void run() {
-
-            generateSegments();
-            addEdges();
-            topologicalSorting();
-            initialPositions();
-            for (int i = 0; i < SWEEP_ITERATIONS; i++) {
-
-                sweep(true);
-                sweep(true);
-                sweep(false);
-                sweep(false);
-            }
-
-            sweep(true);
-            sweep(true);
-        }
-    }
     private static Comparator<LayoutNode> crossingNodeComparator = new Comparator<LayoutNode>() {
 
+        @Override
         public int compare(LayoutNode n1, LayoutNode n2) {
             return n1.crossingNumber - n2.crossingNumber;
         }
@@ -1104,22 +819,26 @@
             }
         }
 
-        protected void run() {
-
+        @SuppressWarnings("unchecked")
+        private void createLayers() {
             layers = new List[layerCount];
 
             for (int i = 0; i < layerCount; i++) {
-                layers[i] = new ArrayList<LayoutNode>();
+                layers[i] = new ArrayList<>();
             }
+        }
 
+        @Override
+        protected void run() {
+            createLayers();
 
             // Generate initial ordering
-            HashSet<LayoutNode> visited = new HashSet<LayoutNode>();
+            HashSet<LayoutNode> visited = new HashSet<>();
             for (LayoutNode n : nodes) {
                 if (n.layer == 0) {
                     layers[0].add(n);
                     visited.add(n);
-                } else if (n.preds.size() == 0) {
+                } else if (n.preds.isEmpty()) {
                     layers[n.layer].add(n);
                     visited.add(n);
                 }
@@ -1136,7 +855,6 @@
                 }
             }
 
-
             updatePositions();
 
             initX();
@@ -1146,10 +864,7 @@
                 downSweep();
                 upSweep();
             }
-
-        /*for(int i=0; i<CROSSING_ITERATIONS; i++) {
-        doubleSweep();
-        }*/
+            downSweep();
         }
 
         private void initX() {
@@ -1191,25 +906,23 @@
                 for (LayoutNode n : layers[i]) {
 
                     int sum = 0;
+                    int count = 0;
                     for (LayoutEdge e : n.preds) {
                         int cur = e.from.x + e.relativeFrom;
-
-                        /*pos;
-                        if(e.from.width != 0 && e.relativeFrom != 0) {
-                        cur += (float)e.relativeFrom / (float)(e.from.width);
-                        }*/
-
-                        sum += cur;
+                        int factor = 1;
+                        if (e.vip) {
+                            factor = VIP_BONUS;
+                        }
+                        sum += cur * factor;
+                        count += factor;
                     }
 
-                    if (n.preds.size() > 0) {
-                        sum /= n.preds.size();
+                    if (count > 0) {
+                        sum /= count;
                         n.crossingNumber = sum;
-                    //if(n.vertex == null) n.crossingNumber += layers[i].size();
                     }
                 }
 
-
                 updateCrossingNumbers(i, true);
                 Collections.sort(layers[i], crossingNodeComparator);
                 updateXOfLayer(i);
@@ -1234,9 +947,9 @@
                     next = layers[index].get(i + 1);
                 }
 
-                boolean cond = (n.succs.size() == 0);
+                boolean cond = n.succs.isEmpty();
                 if (down) {
-                    cond = (n.preds.size() == 0);
+                    cond = n.preds.isEmpty();
                 }
 
                 if (cond) {
@@ -1251,44 +964,6 @@
                 }
             }
         }
-        /*
-        private void doubleSweep() {
-        // Downsweep
-        for(int i=0; i<layerCount*2; i++) {
-        int index = i;
-        if(index >= layerCount) {
-        index = 2*layerCount - i - 1;
-        }
-        for(LayoutNode n : layers[index]) {
-        float sum = 0.0f;
-        for(LayoutEdge e : n.preds) {
-        float cur = e.from.pos;
-        if(e.from.width != 0 && e.relativeFrom != 0) {
-        cur += (float)e.relativeFrom / (float)(e.from.width);
-        }
-        sum += cur;
-        }
-        for(LayoutEdge e : n.succs) {
-        float cur = e.to.pos;
-        if(e.to.width != 0 && e.relativeTo != 0) {
-        cur += (float)e.relativeTo / (float)(e.to.width);
-        }
-        sum += cur;
-        }
-        if(n.preds.size() + n.succs.size() > 0) {
-        sum /= n.preds.size() + n.succs.size();
-        n.crossingNumber = sum;
-        }
-        }
-        Collections.sort(layers[index], crossingNodeComparator);
-        updateXOfLayer(index);
-        int z = 0;
-        for(LayoutNode n : layers[index]) {
-        n.pos = z;
-        z++;
-        }
-        }
-        }*/
 
         private void upSweep() {
             // Upsweep
@@ -1300,21 +975,21 @@
 
                 for (LayoutNode n : layers[i]) {
 
+                    int count = 0;
                     int sum = 0;
                     for (LayoutEdge e : n.succs) {
-                        int cur = e.to.x + e.relativeTo;//pos;
-                                                /*
-                        if(e.to.width != 0 && e.relativeTo != 0) {
-                        cur += (float)e.relativeTo / (float)(e.to.width);
-                        }*/
-
-                        sum += cur;
+                        int cur = e.to.x + e.relativeTo;
+                        int factor = 1;
+                        if (e.vip) {
+                            factor = VIP_BONUS;
+                        }
+                        sum += cur * factor;
+                        count += factor;
                     }
 
-                    if (n.succs.size() > 0) {
-                        sum /= n.succs.size();
+                    if (count > 0) {
+                        sum /= count;
                         n.crossingNumber = sum;
-                    //if(n.vertex == null) n.crossingNumber += layers[i].size();
                     }
 
                 }
@@ -1331,15 +1006,10 @@
             }
         }
 
-        private int evaluate() {
-            // TODO: Implement efficient evaluate / crossing min
-            return 0;
-        }
-
         @Override
         public void postCheck() {
 
-            HashSet<LayoutNode> visited = new HashSet<LayoutNode>();
+            HashSet<LayoutNode> visited = new HashSet<>();
             for (int i = 0; i < layers.length; i++) {
                 for (LayoutNode n : layers[i]) {
                     assert !visited.contains(n);
@@ -1353,9 +1023,10 @@
 
     private class AssignYCoordinates extends AlgorithmPart {
 
+        @Override
         protected void run() {
             int curY = 0;
-            //maxLayerHeight = new int[layers.length];
+
             for (int i = 0; i < layers.length; i++) {
                 int maxHeight = 0;
                 int baseLine = 0;
@@ -1383,10 +1054,8 @@
                     }
                 }
 
-                //maxLayerHeight[i] = maxHeight + baseLine + bottomBaseLine;
-
                 curY += maxHeight + baseLine + bottomBaseLine;
-                curY += layerOffset + (int) Math.sqrt(maxXOffset);
+                curY += layerOffset + ((int) (Math.sqrt(maxXOffset) * 1.5));
             }
         }
     }
@@ -1411,26 +1080,27 @@
             }
         }
 
+        @Override
         protected void run() {
             oldNodeCount = nodes.size();
 
-
             if (combine == Combine.SAME_OUTPUTS) {
 
                 Comparator<LayoutEdge> comparator = new Comparator<LayoutEdge>() {
 
+                    @Override
                     public int compare(LayoutEdge e1, LayoutEdge e2) {
                         return e1.to.layer - e2.to.layer;
                     }
                 };
-                HashMap<Integer, List<LayoutEdge>> portHash = new HashMap<Integer, List<LayoutEdge>>();
-                ArrayList<LayoutNode> currentNodes = new ArrayList<LayoutNode>(nodes);
+                HashMap<Integer, List<LayoutEdge>> portHash = new HashMap<>();
+                ArrayList<LayoutNode> currentNodes = new ArrayList<>(nodes);
                 for (LayoutNode n : currentNodes) {
                     portHash.clear();
 
-                    ArrayList<LayoutEdge> succs = new ArrayList<LayoutEdge>(n.succs);
-                    HashMap<Integer, LayoutNode> topNodeHash = new HashMap<Integer, LayoutNode>();
-                    HashMap<Integer, HashMap<Integer, LayoutNode>> bottomNodeHash = new HashMap<Integer, HashMap<Integer, LayoutNode>>();
+                    ArrayList<LayoutEdge> succs = new ArrayList<>(n.succs);
+                    HashMap<Integer, LayoutNode> topNodeHash = new HashMap<>();
+                    HashMap<Integer, HashMap<Integer, LayoutNode>> bottomNodeHash = new HashMap<>();
                     for (LayoutEdge e : succs) {
                         assert e.from.layer < e.to.layer;
                         if (e.from.layer != e.to.layer - 1) {
@@ -1449,6 +1119,7 @@
                                     topEdge.relativeTo = topNode.width / 2;
                                     topEdge.to = topNode;
                                     topEdge.link = e.link;
+                                    topEdge.vip = e.vip;
                                     e.from.succs.add(topEdge);
                                     topNode.preds.add(topEdge);
                                 } else {
@@ -1464,6 +1135,7 @@
                                     topEdge.relativeTo = topNode.width / 2;
                                     topEdge.to = topNode;
                                     topEdge.link = e.link;
+                                    topEdge.vip = e.vip;
                                     e.from.succs.add(topEdge);
                                     topNode.preds.add(topEdge);
                                     topNodeHash.put(e.relativeFrom, topNode);
@@ -1491,6 +1163,7 @@
                                 bottomEdge.relativeFrom = bottomNode.width / 2;
                                 bottomEdge.from = bottomNode;
                                 bottomEdge.link = e.link;
+                                bottomEdge.vip = e.vip;
                                 e.to.preds.add(bottomEdge);
                                 bottomEdgeHash.put(topEdge, bottomEdge);
                                 bottomNode.succs.add(bottomEdge);
@@ -1500,17 +1173,12 @@
                                 if (!portHash.containsKey(i)) {
                                     portHash.put(i, new ArrayList<LayoutEdge>());
                                 }
-
-                                if (n.vertex.toString().equals("1012 CastPP")) {
-                                    int x = 0;
-                                }
-
                                 portHash.get(i).add(e);
                             }
                         }
                     }
 
-                    succs = new ArrayList<LayoutEdge>(n.succs);
+                    succs = new ArrayList<>(n.succs);
                     for (LayoutEdge e : succs) {
 
                         Integer i = e.relativeFrom;
@@ -1528,13 +1196,13 @@
                                     maxLayer = Math.max(maxLayer, curEdge.to.layer);
                                 }
 
-
                                 int cnt = maxLayer - n.layer - 1;
                                 LayoutEdge[] edges = new LayoutEdge[cnt];
                                 LayoutNode[] nodes = new LayoutNode[cnt];
                                 edges[0] = new LayoutEdge();
                                 edges[0].from = n;
                                 edges[0].relativeFrom = i;
+                                edges[0].vip = e.vip;
                                 n.succs.add(edges[0]);
 
                                 nodes[0] = new LayoutNode();
@@ -1546,6 +1214,7 @@
                                 edges[0].relativeTo = nodes[0].width / 2;
                                 for (int j = 1; j < cnt; j++) {
                                     edges[j] = new LayoutEdge();
+                                    edges[j].vip = e.vip;
                                     edges[j].from = nodes[j - 1];
                                     edges[j].relativeFrom = nodes[j - 1].width / 2;
                                     nodes[j - 1].succs.add(edges[j]);
@@ -1577,7 +1246,7 @@
             } else if (combine == Combine.SAME_INPUTS) {
                 throw new UnsupportedOperationException("Currently not supported");
             } else {
-                ArrayList<LayoutNode> currentNodes = new ArrayList<LayoutNode>(nodes);
+                ArrayList<LayoutNode> currentNodes = new ArrayList<>(nodes);
                 for (LayoutNode n : currentNodes) {
                     for (LayoutEdge e : n.succs) {
                         processSingleEdge(e);
@@ -1604,6 +1273,7 @@
             n.preds.add(e);
             nodes.add(n);
             LayoutEdge result = new LayoutEdge();
+            result.vip = e.vip;
             n.succs.add(result);
             result.from = n;
             result.relativeFrom = n.width / 2;
@@ -1623,7 +1293,7 @@
 
         @Override
         public void postCheck() {
-            ArrayList<LayoutNode> currentNodes = new ArrayList<LayoutNode>(nodes);
+            ArrayList<LayoutNode> currentNodes = new ArrayList<>(nodes);
             for (LayoutNode n : currentNodes) {
                 for (LayoutEdge e : n.succs) {
                     assert e.from.layer == e.to.layer - 1;
@@ -1648,91 +1318,114 @@
             }
         }
 
+        @Override
         protected void run() {
-            HashSet<LayoutNode> set = new HashSet<LayoutNode>();
+            assignLayerDownwards();
+            assignLayerUpwards();
+        }
+
+        private void assignLayerDownwards() {
+            ArrayList<LayoutNode> hull = new ArrayList<>();
             for (LayoutNode n : nodes) {
-                if (n.preds.size() == 0) {
-                    set.add(n);
+                if (n.preds.isEmpty()) {
+                    hull.add(n);
                     n.layer = 0;
                 }
             }
 
             int z = minLayerDifference;
-            HashSet<LayoutNode> newSet = new HashSet<LayoutNode>();
-            HashSet<LayoutNode> failed = new HashSet<LayoutNode>();
-            while (!set.isEmpty()) {
-
-                newSet.clear();
-                failed.clear();
-
-                for (LayoutNode n : set) {
-
+            while (!hull.isEmpty()) {
+                ArrayList<LayoutNode> newSet = new ArrayList<>();
+                for (LayoutNode n : hull) {
                     for (LayoutEdge se : n.succs) {
                         LayoutNode s = se.to;
-                        if (!newSet.contains(s) && !failed.contains(s)) {
-                            boolean ok = true;
+                        if (s.layer != -1) {
+                            // This node was assigned before.
+                        } else {
+                            boolean unassignedPred = false;
                             for (LayoutEdge pe : s.preds) {
                                 LayoutNode p = pe.from;
-                                if (p.layer == -1) {
-                                    ok = false;
+                                if (p.layer == -1 || p.layer >= z) {
+                                    // This now has an unscheduled successor or a successor that was scheduled only in this round.
+                                    unassignedPred = true;
                                     break;
                                 }
                             }
 
-                            if (ok) {
+                            if (unassignedPred) {
+                                // This successor node can not yet be assigned.
+                            } else {
+                                s.layer = z;
                                 newSet.add(s);
-                            } else {
-                                failed.add(s);
                             }
                         }
                     }
-
                 }
 
-                for (LayoutNode n : newSet) {
-                    n.layer = z;
-                }
-
-                // Swap sets
-                HashSet<LayoutNode> tmp = set;
-                set = newSet;
-                newSet = tmp;
+                hull = newSet;
                 z += minLayerDifference;
             }
 
-            optimize(set);
+            layerCount = z - minLayerDifference;
+            for (LayoutNode n : nodes) {
+                n.layer = (layerCount - 1 - n.layer);
+            }
+        }
+
+        private void assignLayerUpwards() {
+            ArrayList<LayoutNode> hull = new ArrayList<>();
+            for (LayoutNode n : nodes) {
+                if (n.succs.isEmpty()) {
+                    hull.add(n);
+                } else {
+                    n.layer = -1;
+                }
+            }
+
+            int z = minLayerDifference;
+            while (!hull.isEmpty()) {
+                ArrayList<LayoutNode> newSet = new ArrayList<>();
+                for (LayoutNode n : hull) {
+                    if (n.layer < z) {
+                        for (LayoutEdge se : n.preds) {
+                            LayoutNode s = se.from;
+                            if (s.layer != -1) {
+                                // This node was assigned before.
+                            } else {
+                                boolean unassignedSucc = false;
+                                for (LayoutEdge pe : s.succs) {
+                                    LayoutNode p = pe.to;
+                                    if (p.layer == -1 || p.layer >= z) {
+                                        // This now has an unscheduled successor or a successor that was scheduled only in this round.
+                                        unassignedSucc = true;
+                                        break;
+                                    }
+                                }
+
+                                if (unassignedSucc) {
+                                    // This predecessor node can not yet be assigned.
+                                } else {
+                                    s.layer = z;
+                                    newSet.add(s);
+                                }
+                            }
+                        }
+                    } else {
+                        newSet.add(n);
+                    }
+                }
+
+                hull = newSet;
+                z += minLayerDifference;
+            }
 
             layerCount = z - minLayerDifference;
 
-            for (Vertex v : lastLayerHint) {
-
-                LayoutNode n = vertexToLayoutNode.get(v);
-                assert n.succs.size() == 0;
-                n.layer = layerCount - 1;
-            }
-
-            for (Vertex v : firstLayerHint) {
-                LayoutNode n = vertexToLayoutNode.get(v);
-                assert n.preds.size() == 0;
-                assert n.layer == 0;
+            for (LayoutNode n : nodes) {
+                n.layer = (layerCount - 1 - n.layer);
             }
         }
 
-        public void optimize(HashSet<LayoutNode> set) {
-
-            for (LayoutNode n : set) {
-                if (n.preds.size() == 0 && n.succs.size() > 0) {
-                    int minLayer = n.succs.get(0).to.layer;
-                    for (LayoutEdge e : n.succs) {
-                        minLayer = Math.min(minLayer, e.to.layer);
-                    }
-
-                    n.layer = minLayer - 1;
-                }
-            }
-
-        }
-
         @Override
         public void postCheck() {
             for (LayoutNode n : nodes) {
@@ -1750,11 +1443,12 @@
         private HashSet<LayoutNode> visited;
         private HashSet<LayoutNode> active;
 
+        @Override
         protected void run() {
 
-            // Remove self-edges, TODO: Special treatment
+            // Remove self-edges
             for (LayoutNode node : nodes) {
-                ArrayList<LayoutEdge> succs = new ArrayList<LayoutEdge>(node.succs);
+                ArrayList<LayoutEdge> succs = new ArrayList<>(node.succs);
                 for (LayoutEdge e : succs) {
                     assert e.from == node;
                     if (e.to == node) {
@@ -1780,18 +1474,16 @@
                 }
             }
 
-
             // Start DFS and reverse back edges
-            visited = new HashSet<LayoutNode>();
-            active = new HashSet<LayoutNode>();
+            visited = new HashSet<>();
+            active = new HashSet<>();
             for (LayoutNode node : nodes) {
                 DFS(node);
             }
 
-
             for (LayoutNode node : nodes) {
 
-                SortedSet<Integer> reversedDown = new TreeSet<Integer>();
+                SortedSet<Integer> reversedDown = new TreeSet<>();
 
                 for (LayoutEdge e : node.succs) {
                     if (reversedLinks.contains(e.link)) {
@@ -1799,12 +1491,11 @@
                     }
                 }
 
-
                 SortedSet<Integer> reversedUp = null;
                 if (reversedDown.size() == 0) {
-                    reversedUp = new TreeSet<Integer>(Collections.reverseOrder());
+                    reversedUp = new TreeSet<>(Collections.reverseOrder());
                 } else {
-                    reversedUp = new TreeSet<Integer>();
+                    reversedUp = new TreeSet<>();
                 }
 
                 for (LayoutEdge e : node.preds) {
@@ -1818,7 +1509,7 @@
                 int curX = 0;
                 int curWidth = node.width + reversedDown.size() * offset;
                 for (int pos : reversedDown) {
-                    ArrayList<LayoutEdge> reversedSuccs = new ArrayList<LayoutEdge>();
+                    ArrayList<LayoutEdge> reversedSuccs = new ArrayList<>();
                     for (LayoutEdge e : node.succs) {
                         if (e.relativeFrom == pos && reversedLinks.contains(e.link)) {
                             reversedSuccs.add(e);
@@ -1826,7 +1517,7 @@
                         }
                     }
 
-                    ArrayList<Point> startPoints = new ArrayList<Point>();
+                    ArrayList<Point> startPoints = new ArrayList<>();
                     startPoints.add(new Point(curWidth, curX));
                     startPoints.add(new Point(pos, curX));
                     startPoints.add(new Point(pos, reversedDown.size() * offset));
@@ -1856,7 +1547,7 @@
 
                 int oldNodeHeight = node.height;
                 for (int pos : reversedUp) {
-                    ArrayList<LayoutEdge> reversedPreds = new ArrayList<LayoutEdge>();
+                    ArrayList<LayoutEdge> reversedPreds = new ArrayList<>();
                     for (LayoutEdge e : node.preds) {
                         if (e.relativeTo == pos && reversedLinks.contains(e.link)) {
                             if (reversedDown.size() == 0) {
@@ -1869,7 +1560,7 @@
                         }
                     }
                     node.height += offset;
-                    ArrayList<Point> endPoints = new ArrayList<Point>();
+                    ArrayList<Point> endPoints = new ArrayList<>();
 
                     if (reversedDown.size() == 0) {
 
@@ -1887,7 +1578,6 @@
                     curX += offset;
                     node.bottomYOffset += offset;
 
-
                     endPoints.add(new Point(pos, node.height));
                     endPoints.add(new Point(pos, oldNodeHeight));
                     for (LayoutEdge e : reversedPreds) {
@@ -1895,7 +1585,6 @@
                     }
                 }
 
-
                 if (minX < 0) {
                     for (LayoutEdge e : node.preds) {
                         e.relativeTo -= minX;
@@ -1917,7 +1606,7 @@
                 return;
             }
 
-            Stack<LayoutNode> stack = new Stack<LayoutNode>();
+            Stack<LayoutNode> stack = new Stack<>();
             stack.push(startNode);
 
             while (!stack.empty()) {
@@ -1934,7 +1623,7 @@
                 visited.add(node);
                 active.add(node);
 
-                ArrayList<LayoutEdge> succs = new ArrayList<LayoutEdge>(node.succs);
+                ArrayList<LayoutEdge> succs = new ArrayList<>(node.succs);
                 for (LayoutEdge e : succs) {
                     if (active.contains(e.to)) {
                         assert visited.contains(e.to);
@@ -1989,8 +1678,8 @@
 
             for (LayoutNode n : nodes) {
 
-                HashSet<LayoutNode> curVisited = new HashSet<LayoutNode>();
-                Queue<LayoutNode> queue = new LinkedList<LayoutNode>();
+                HashSet<LayoutNode> curVisited = new HashSet<>();
+                Queue<LayoutNode> queue = new LinkedList<>();
                 for (LayoutEdge e : n.succs) {
                     LayoutNode s = e.to;
                     queue.add(s);
@@ -2013,7 +1702,15 @@
     }
     private Comparator<Link> linkComparator = new Comparator<Link>() {
 
+        @Override
         public int compare(Link l1, Link l2) {
+            if (l1.isVIP() && !l2.isVIP()) {
+                return -1;
+            }
+
+            if (!l1.isVIP() && l2.isVIP()) {
+                return 1;
+            }
 
             int result = l1.getFrom().getVertex().compareTo(l2.getFrom().getVertex());
             if (result != 0) {
@@ -2034,9 +1731,10 @@
 
     private class BuildDatastructure extends AlgorithmPart {
 
+        @Override
         protected void run() {
             // Set up nodes
-            List<Vertex> vertices = new ArrayList<Vertex>(graph.getVertices());
+            List<Vertex> vertices = new ArrayList<>(graph.getVertices());
             Collections.sort(vertices);
 
             for (Vertex v : vertices) {
@@ -2050,7 +1748,7 @@
             }
 
             // Set up edges
-            List<Link> links = new ArrayList<Link>(graph.getLinks());
+            List<Link> links = new ArrayList<>(graph.getLinks());
             Collections.sort(links, linkComparator);
             for (Link l : links) {
                 LayoutEdge edge = new LayoutEdge();
@@ -2061,14 +1759,15 @@
                 edge.relativeFrom = l.getFrom().getRelativePosition().x;
                 edge.relativeTo = l.getTo().getRelativePosition().x;
                 edge.link = l;
+                edge.vip = l.isVIP();
                 edge.from.succs.add(edge);
                 edge.to.preds.add(edge);
-            //assert edge.from != edge.to; // No self-loops allowed
+                //assert edge.from != edge.to; // No self-loops allowed
             }
 
             for (Link l : importantLinks) {
-                if (!vertexToLayoutNode.containsKey(l.getFrom().getVertex()) ||
-                        vertexToLayoutNode.containsKey(l.getTo().getVertex())) {
+                if (!vertexToLayoutNode.containsKey(l.getFrom().getVertex())
+                        || vertexToLayoutNode.containsKey(l.getTo().getVertex())) {
                     continue;
                 }
                 LayoutNode from = vertexToLayoutNode.get(l.getFrom().getVertex());
@@ -2104,7 +1803,8 @@
         }
     }
 
+    @Override
     public void doRouting(LayoutGraph graph) {
-    // Do nothing for now
+        // Do nothing for now
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/InterClusterConnection.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/InterClusterConnection.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -73,4 +73,8 @@
     public String toString() {
         return "InterClusterConnection[from=" + getFrom() + ", to=" + getTo() + "]";
     }
+
+    public boolean isVIP() {
+        return false;
+    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Node.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Node.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -90,8 +90,8 @@
     protected Node(Graph<N, E> graph, N data) {
         setData(data);
         this.graph = graph;
-        inEdges = new ArrayList<Edge<N, E>>();
-        outEdges = new ArrayList<Edge<N, E>>();
+        inEdges = new ArrayList<>();
+        outEdges = new ArrayList<>();
     }
 
     protected void addInEdge(Edge<N, E> e) {
@@ -125,7 +125,7 @@
     }
 
     public List<Node<N, E>> getSuccessors() {
-        ArrayList<Node<N, E>> succ = new ArrayList<Node<N, E>>();
+        ArrayList<Node<N, E>> succ = new ArrayList<>();
         for (Edge<N, E> e : getOutEdges()) {
             Node<N, E> n = e.getDest();
             if (!succ.contains(n)) {
@@ -136,7 +136,7 @@
     }
 
     public List<Node<N, E>> getPredecessors() {
-        ArrayList<Node<N, E>> pred = new ArrayList<Node<N, E>>();
+        ArrayList<Node<N, E>> pred = new ArrayList<>();
         for (Edge<N, E> e : getInEdges()) {
             Node<N, E> n = e.getSource();
             if (!pred.contains(n)) {
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/OldHierarchicalLayoutManager.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1222 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.hierarchicallayout;
-
-import java.awt.Point;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import com.sun.hotspot.igv.layout.LayoutGraph;
-import com.sun.hotspot.igv.layout.LayoutManager;
-import com.sun.hotspot.igv.layout.Link;
-import com.sun.hotspot.igv.layout.Port;
-import com.sun.hotspot.igv.layout.Vertex;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class OldHierarchicalLayoutManager implements LayoutManager {
-
-    public static final int DUMMY_WIDTH = 0;
-    public static final int DUMMY_HEIGHT = 0;
-    public static final int LAYER_OFFSET = 50;
-    public static final int OFFSET = 8;
-    public static final boolean VERTICAL_LAYOUT = true;
-    public static final boolean ASSERT = false;
-    public static final boolean TRACE = false;
-    public static final Timing initTiming = new Timing("init");
-    public static final Timing removeCyclesTiming = new Timing("removeCycles");
-    public static final Timing reversedEdgesTiming = new Timing("reversedEdges");
-    public static final Timing assignLayersTiming = new Timing("assignLayers");
-    public static final Timing dummyNodesTiming = new Timing("dummyNodes");
-    public static final Timing crossingReductionTiming = new Timing("crossingReduction");
-    public static final Timing assignCoordinatesTiming = new Timing("assignCoordinates");
-    public static final Timing assignRealTiming = new Timing("assignReal");
-    public static final Timing rootVertexTiming = new Timing("rootVertex");
-    public static final Timing createEdgesTiming = new Timing("createEdges");
-    public static final Timing optimizeMedianTiming = new Timing("optimizeMedian");
-    private Combine combine;
-
-    public enum Combine {
-
-        NONE,
-        SAME_INPUTS,
-        SAME_OUTPUTS
-    }
-
-    private class NodeData {
-
-        private Map<Port, Integer> reversePositions;
-        private Vertex node;
-        private Link edge;
-        private int layer;
-        private int x;
-        private int y;
-        private int width;
-
-        public NodeData(Vertex node) {
-            reversePositions = new HashMap<Port, Integer>();
-            layer = -1;
-            this.node = node;
-            assert node != null;
-
-            if (VERTICAL_LAYOUT) {
-                width = node.getSize().width;
-            } else {
-                width = node.getSize().height;
-            }
-        }
-
-        public NodeData(Link edge) {
-            layer = -1;
-            this.edge = edge;
-            assert edge != null;
-
-            if (VERTICAL_LAYOUT) {
-                width = DUMMY_WIDTH;
-            } else {
-                width = DUMMY_HEIGHT;
-            }
-        }
-
-        public Vertex getNode() {
-            return node;
-        }
-
-        public Link getEdge() {
-            return edge;
-        }
-
-        public int getCoordinate() {
-            return x;
-        }
-
-        public void setCoordinate(int x) {
-            this.x = x;
-        }
-
-        public int getX() {
-            if (VERTICAL_LAYOUT) {
-                return x;
-            } else {
-                return y;
-            }
-        }
-
-        public int getY() {
-            if (VERTICAL_LAYOUT) {
-                return y;
-            } else {
-                return x;
-            }
-        }
-
-        public void setLayerCoordinate(int y) {
-            this.y = y;
-        }
-
-        public void setLayer(int x) {
-            layer = x;
-        }
-
-        public int getLayer() {
-            return layer;
-        }
-
-        public boolean isDummy() {
-            return edge != null;
-        }
-
-        public int getWidth() {
-            return width;
-        }
-
-        public void addReversedStartEdge(Edge<NodeData, EdgeData> e) {
-            assert e.getData().isReversed();
-            Port port = e.getData().getEdge().getTo();
-            int pos = addReversedPort(port);
-            Point start = e.getData().getRelativeStart();
-            e.getData().addStartPoint(start);
-            int yCoord = node.getSize().height + width - node.getSize().width;
-            e.getData().addStartPoint(new Point(start.x, yCoord));
-            e.getData().addStartPoint(new Point(pos, yCoord));
-            e.getData().setRelativeStart(new Point(pos, 0));
-        }
-
-        private int addReversedPort(Port p) {
-            if (reversePositions.containsKey(p)) {
-                return reversePositions.get(p);
-            } else {
-                width += OFFSET;
-                reversePositions.put(p, width);
-                return width;
-            }
-        }
-
-        public void addReversedEndEdge(Edge<NodeData, EdgeData> e) {
-            assert e.getData().isReversed();
-            int pos = addReversedPort(e.getData().getEdge().getFrom());
-            Point end = e.getData().getRelativeEnd();
-            e.getData().setRelativeEnd(new Point(pos, node.getSize().height));
-            int yCoord = 0 - width + node.getSize().width;
-            e.getData().addEndPoint(new Point(pos, yCoord));
-            e.getData().addEndPoint(new Point(end.x, yCoord));
-            e.getData().addEndPoint(end);
-        }
-
-        public int getHeight() {
-            if (isDummy()) {
-                if (VERTICAL_LAYOUT) {
-                    return DUMMY_HEIGHT;
-                } else {
-                    return DUMMY_WIDTH;
-                }
-
-            } else {
-                if (VERTICAL_LAYOUT) {
-                    return node.getSize().height;
-                } else {
-                    return node.getSize().width;
-                }
-            }
-        }
-
-        @Override
-        public String toString() {
-            if (isDummy()) {
-                return edge.toString() + "(layer=" + layer + ")";
-            } else {
-                return node.toString() + "(layer=" + layer + ")";
-            }
-        }
-    }
-
-    private class EdgeData {
-
-        private Point relativeEnd;
-        private Point relativeStart;
-        private List<Point> startPoints;
-        private List<Point> endPoints;
-        private boolean important;
-        private boolean reversed;
-        private Link edge;
-
-        public EdgeData(Link edge) {
-            this(edge, false);
-        }
-
-        public EdgeData(Link edge, boolean rev) {
-            this.edge = edge;
-            reversed = rev;
-            relativeStart = edge.getFrom().getRelativePosition();
-            relativeEnd = edge.getTo().getRelativePosition();
-            assert relativeStart.x >= 0 && relativeStart.x <= edge.getFrom().getVertex().getSize().width;
-            assert relativeStart.y >= 0 && relativeStart.y <= edge.getFrom().getVertex().getSize().height;
-            assert relativeEnd.x >= 0 && relativeEnd.x <= edge.getTo().getVertex().getSize().width;
-            assert relativeEnd.y >= 0 && relativeEnd.y <= edge.getTo().getVertex().getSize().height;
-            startPoints = new ArrayList<Point>();
-            endPoints = new ArrayList<Point>();
-            this.important = true;
-        }
-
-        public boolean isImportant() {
-            return important;
-        }
-
-        public void setImportant(boolean b) {
-            this.important = b;
-        }
-
-        public List<Point> getStartPoints() {
-            return startPoints;
-        }
-
-        public List<Point> getEndPoints() {
-            return endPoints;
-        }
-
-        public List<Point> getAbsoluteEndPoints() {
-            if (endPoints.size() == 0) {
-                return endPoints;
-            }
-
-            List<Point> result = new ArrayList<Point>();
-            Point point = edge.getTo().getVertex().getPosition();
-            for (Point p : endPoints) {
-                Point p2 = new Point(p.x + point.x, p.y + point.y);
-                result.add(p2);
-            }
-
-            return result;
-        }
-
-        public List<Point> getAbsoluteStartPoints() {
-            if (startPoints.size() == 0) {
-                return startPoints;
-            }
-
-            List<Point> result = new ArrayList<Point>();
-            Point point = edge.getFrom().getVertex().getPosition();
-            for (Point p : startPoints) {
-                Point p2 = new Point(p.x + point.x, p.y + point.y);
-                result.add(p2);
-            }
-
-            return result;
-        }
-
-        public void addEndPoint(Point p) {
-            endPoints.add(p);
-        }
-
-        public void addStartPoint(Point p) {
-            startPoints.add(p);
-        }
-
-        public Link getEdge() {
-            return edge;
-        }
-
-        public void setRelativeEnd(Point p) {
-            relativeEnd = p;
-        }
-
-        public void setRelativeStart(Point p) {
-            relativeStart = p;
-        }
-
-        public Point getRelativeEnd() {
-            return relativeEnd;
-        }
-
-        public Point getRelativeStart() {
-            return relativeStart;
-        }
-
-        public boolean isReversed() {
-            return reversed;
-        }
-
-        public void setReversed(boolean b) {
-            reversed = b;
-        }
-
-        @Override
-        public String toString() {
-            return "EdgeData[reversed=" + reversed + "]";
-        }
-    }
-    private Graph<NodeData, EdgeData> graph;
-    private Map<Vertex, Node<NodeData, EdgeData>> nodeMap;
-    private int layerOffset;
-
-    /** Creates a new instance of HierarchicalPositionManager */
-    public OldHierarchicalLayoutManager(Combine combine) {
-        this(combine, LAYER_OFFSET);
-    }
-
-    public OldHierarchicalLayoutManager(Combine combine, int layerOffset) {
-        this.combine = combine;
-        this.layerOffset = layerOffset;
-    }
-
-    public void doRouting(LayoutGraph graph) {
-    }
-
-    //public void setPositions(PositionedNode rootNode, List<? extends PositionedNode> nodes, List<? extends PositionedEdge> edges) {
-    public void doLayout(LayoutGraph layoutGraph) {
-        doLayout(layoutGraph, new HashSet<Vertex>(), new HashSet<Vertex>());
-    }
-
-    public void doLayout(LayoutGraph layoutGraph, Set<? extends Vertex> firstLayerHint, Set<? extends Vertex> lastLayerHint) {
-        doLayout(layoutGraph, firstLayerHint, lastLayerHint, new HashSet<Link>());
-    }
-
-    public void doLayout(LayoutGraph layoutGraph, Set<? extends Vertex> firstLayerHint, Set<? extends Vertex> lastLayerHint, Set<? extends Link> importantLinksHint) {
-
-        if (TRACE) {
-            System.out.println("HierarchicalPositionManager.doLayout called");
-            System.out.println("Vertex count = " + layoutGraph.getVertices().size() + " Link count = " + layoutGraph.getLinks().size());
-        }
-
-        // Nothing to do => quit immediately
-        if (layoutGraph.getVertices().size() == 0) {
-            return;
-        }
-
-        initTiming.start();
-
-        // Mapping vertex to Node in graph
-        nodeMap = new HashMap<Vertex, Node<NodeData, EdgeData>>();
-
-        graph = new Graph<NodeData, EdgeData>();
-
-        Set<Node<NodeData, EdgeData>> rootNodes = new HashSet<Node<NodeData, EdgeData>>();
-        Set<Vertex> startRootVertices = new HashSet<Vertex>();
-
-        for (Vertex v : layoutGraph.getVertices()) {
-            if (v.isRoot()) {
-                startRootVertices.add(v);
-            }
-        }
-
-        rootVertexTiming.start();
-        Set<Vertex> rootVertices = layoutGraph.findRootVertices(startRootVertices);
-        rootVertexTiming.stop();
-
-
-        for (Vertex node : layoutGraph.getVertices()) {
-
-            NodeData data = new NodeData(node);
-            Node<NodeData, EdgeData> n = graph.createNode(data, node);
-            nodeMap.put(node, n);
-
-            if (rootVertices.contains(node)) {
-                rootNodes.add(n);
-            }
-        }
-
-        Set<? extends Link> links = layoutGraph.getLinks();
-        Link[] linkArr = new Link[links.size()];
-        links.toArray(linkArr);
-
-        List<Link> linkList = new ArrayList<Link>();
-        for (Link l : linkArr) {
-            linkList.add(l);
-        }
-
-        createEdgesTiming.start();
-        Collections.sort(linkList, new Comparator<Link>() {
-
-            public int compare(Link o1, Link o2) {
-                int result = o1.getFrom().getVertex().compareTo(o2.getFrom().getVertex());
-                if (result == 0) {
-                    return o1.getTo().getVertex().compareTo(o2.getTo().getVertex());
-                } else {
-                    return result;
-                }
-            }
-        });
-
-        for (Link edge : linkList) {
-            EdgeData data = new EdgeData(edge);
-            graph.createEdge(graph.getNode(edge.getFrom().getVertex()), graph.getNode(edge.getTo().getVertex()), data, data);
-            if (importantLinksHint.size() > 0 && !importantLinksHint.contains(edge)) {
-                data.setImportant(false);
-            }
-        }
-        createEdgesTiming.stop();
-
-        initTiming.stop();
-
-        removeCyclesTiming.start();
-
-        // STEP 1: Remove cycles!
-        removeCycles(rootNodes);
-        if (ASSERT) {
-            assert checkRemoveCycles();
-        }
-
-        removeCyclesTiming.stop();
-
-        reversedEdgesTiming.start();
-
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            List<Edge<NodeData, EdgeData>> edges = new ArrayList<Edge<NodeData, EdgeData>>(n.getOutEdges());
-            Collections.sort(edges, new Comparator<Edge<NodeData, EdgeData>>() {
-
-                public int compare(Edge<NodeData, EdgeData> o1, Edge<NodeData, EdgeData> o2) {
-                    return o2.getData().getRelativeEnd().x - o1.getData().getRelativeEnd().x;
-                }
-            });
-
-
-            for (Edge<NodeData, EdgeData> e : edges) {
-
-                if (e.getData().isReversed()) {
-                    e.getSource().getData().addReversedEndEdge(e);
-                }
-            }
-        }
-
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            List<Edge<NodeData, EdgeData>> edges = new ArrayList<Edge<NodeData, EdgeData>>(n.getInEdges());
-            Collections.sort(edges, new Comparator<Edge<NodeData, EdgeData>>() {
-
-                public int compare(Edge<NodeData, EdgeData> o1, Edge<NodeData, EdgeData> o2) {
-                    return o2.getData().getRelativeStart().x - o1.getData().getRelativeStart().x;
-                }
-            });
-
-
-            for (Edge<NodeData, EdgeData> e : edges) {
-                if (e.getData().isReversed()) {
-                    e.getDest().getData().addReversedStartEdge(e);
-                }
-            }
-        }
-
-        reversedEdgesTiming.stop();
-
-        assignLayersTiming.start();
-        // STEP 2: Assign layers!
-        int maxLayer = assignLayers(rootNodes, firstLayerHint, lastLayerHint);
-        if (ASSERT) {
-            assert checkAssignLayers();
-        }
-
-        // Put into layer array
-        //int maxLayer = 0;
-        //for(Node<NodeData, EdgeData> n : graph.getNodes()) {
-        //    maxLayer = Math.max(maxLayer, n.getData().getLayer());
-        //}
-
-
-        ArrayList<Node<NodeData, EdgeData>> layers[] = new ArrayList[maxLayer + 1];
-        int layerSizes[] = new int[maxLayer + 1];
-        for (int i = 0; i < maxLayer + 1; i++) {
-            layers[i] = new ArrayList<Node<NodeData, EdgeData>>();
-        }
-
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            int curLayer = n.getData().getLayer();
-            layers[curLayer].add(n);
-        }
-
-        assignLayersTiming.stop();
-
-        // STEP 3: Insert dummy nodes!
-        dummyNodesTiming.start();
-        insertDummyNodes(layers);
-        if (ASSERT) {
-            assert checkDummyNodes();
-        }
-        dummyNodesTiming.stop();
-
-        crossingReductionTiming.start();
-        // STEP 4: Assign Y coordinates
-        assignLayerCoordinates(layers, layerSizes);
-
-        // STEP 5: Crossing reduction
-        crossingReduction(layers);
-        crossingReductionTiming.stop();
-
-        // STEP 6: Assign Y coordinates
-        assignCoordinatesTiming.start();
-        assignCoordinates(layers);
-        assignCoordinatesTiming.stop();
-
-        assignRealTiming.start();
-
-        // Assign coordinates of nodes to real objects
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            if (!n.getData().isDummy()) {
-
-                Vertex node = n.getData().getNode();
-                node.setPosition(new Point(n.getData().getX(), n.getData().getY()));
-            }
-        }
-
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            if (!n.getData().isDummy()) {
-
-                Vertex node = n.getData().getNode();
-
-                List<Edge<NodeData, EdgeData>> outEdges = n.getOutEdges();
-                for (Edge<NodeData, EdgeData> e : outEdges) {
-                    Node<NodeData, EdgeData> succ = e.getDest();
-                    if (succ.getData().isDummy()) {
-                        //PositionedEdge edge = succ.getData().getEdge();
-                        List<Point> points = new ArrayList<Point>();
-                        assignToRealObjects(layerSizes, succ, points);
-                    } else {
-                        List<Point> points = new ArrayList<Point>();
-
-                        EdgeData otherEdgeData = e.getData();
-                        points.addAll(otherEdgeData.getAbsoluteStartPoints());
-                        Link otherEdge = otherEdgeData.getEdge();
-                        Point relFrom = new Point(otherEdgeData.getRelativeStart());
-                        Point from = otherEdge.getFrom().getVertex().getPosition();
-                        relFrom.move(relFrom.x + from.x, relFrom.y + from.y);
-                        points.add(relFrom);
-
-                        Point relTo = new Point(otherEdgeData.getRelativeEnd());
-                        Point to = otherEdge.getTo().getVertex().getPosition();
-                        relTo.move(relTo.x + to.x, relTo.y + to.y);
-                        assert from != null;
-                        assert to != null;
-                        points.add(relTo);
-                        points.addAll(otherEdgeData.getAbsoluteEndPoints());
-                        e.getData().getEdge().setControlPoints(points);
-                    }
-                }
-            }
-        }
-
-        assignRealTiming.stop();
-
-        initTiming.print();
-        removeCyclesTiming.print();
-        reversedEdgesTiming.print();
-        assignLayersTiming.print();
-        dummyNodesTiming.print();
-        crossingReductionTiming.print();
-        assignCoordinatesTiming.print();
-        assignRealTiming.print();
-        rootVertexTiming.print();
-        createEdgesTiming.print();
-        optimizeMedianTiming.print();
-    }
-
-    public boolean onOneLine(Point p1, Point p2, Point p3) {
-        int xoff1 = p1.x - p2.x;
-        int yoff1 = p1.y - p2.y;
-        int xoff2 = p3.x - p2.x;
-        int yoff2 = p3.y - p2.x;
-
-        return (xoff1 * yoff2 - yoff1 * xoff2 == 0);
-    }
-
-    private void assignToRealObjects(int layerSizes[], Node<NodeData, EdgeData> cur, List<Point> points) {
-        assert cur.getData().isDummy();
-
-        ArrayList<Point> otherPoints = new ArrayList<Point>(points);
-
-        int size = layerSizes[cur.getData().getLayer()];
-        otherPoints.add(new Point(cur.getData().getX(), cur.getData().getY() - size / 2));
-        if (otherPoints.size() >= 3 && onOneLine(otherPoints.get(otherPoints.size() - 1), otherPoints.get(otherPoints.size() - 2), otherPoints.get(otherPoints.size() - 3))) {
-            otherPoints.remove(otherPoints.size() - 2);
-        }
-        otherPoints.add(new Point(cur.getData().getX(), cur.getData().getY() + size / 2));
-        if (otherPoints.size() >= 3 && onOneLine(otherPoints.get(otherPoints.size() - 1), otherPoints.get(otherPoints.size() - 2), otherPoints.get(otherPoints.size() - 3))) {
-            otherPoints.remove(otherPoints.size() - 2);
-        }
-
-        for (int i = 0; i < cur.getOutEdges().size(); i++) {
-            Node<NodeData, EdgeData> otherSucc = cur.getOutEdges().get(i).getDest();
-
-            if (otherSucc.getData().isDummy()) {
-                assignToRealObjects(layerSizes, otherSucc, otherPoints);
-            } else {
-                EdgeData otherEdgeData = cur.getOutEdges().get(i).getData();
-                Link otherEdge = otherEdgeData.getEdge();
-
-                List<Point> middlePoints = new ArrayList<Point>(otherPoints);
-                if (cur.getOutEdges().get(i).getData().isReversed()) {
-                    Collections.reverse(middlePoints);
-                }
-
-                ArrayList<Point> copy = new ArrayList<Point>();
-                Point relFrom = new Point(otherEdgeData.getRelativeStart());
-                Point from = otherEdge.getFrom().getVertex().getPosition();
-                //int moveUp = (size - otherEdge.getFrom().getVertex().getSize().height) / 2;
-                relFrom.move(relFrom.x + from.x, relFrom.y + from.y);
-                copy.addAll(otherEdgeData.getAbsoluteStartPoints());
-                copy.add(relFrom);
-                copy.addAll(middlePoints);
-
-                Point relTo = new Point(otherEdgeData.getRelativeEnd());
-                Point to = otherEdge.getTo().getVertex().getPosition();
-                relTo.move(relTo.x + to.x, relTo.y + to.y);
-                copy.add(relTo);
-
-                copy.addAll(otherEdgeData.getAbsoluteEndPoints());
-
-
-                otherEdge.setControlPoints(copy);
-            }
-        }
-    }
-
-    private boolean checkDummyNodes() {
-        for (Edge<NodeData, EdgeData> e : graph.getEdges()) {
-            if (e.getSource().getData().getLayer() != e.getDest().getData().getLayer() - 1) {
-                return false;
-            }
-        }
-
-        return true;
-    }
-
-    private void insertDummyNodes(ArrayList<Node<NodeData, EdgeData>> layers[]) {
-
-        int sum = 0;
-        List<Node<NodeData, EdgeData>> nodes = new ArrayList<Node<NodeData, EdgeData>>(graph.getNodes());
-        int edgeCount = 0;
-        int innerMostLoop = 0;
-
-        for (Node<NodeData, EdgeData> n : nodes) {
-            List<Edge<NodeData, EdgeData>> edges = new ArrayList<Edge<NodeData, EdgeData>>(n.getOutEdges());
-            for (Edge<NodeData, EdgeData> e : edges) {
-
-                edgeCount++;
-                Link edge = e.getData().getEdge();
-                Node<NodeData, EdgeData> destNode = e.getDest();
-                Node<NodeData, EdgeData> lastNode = n;
-                Edge<NodeData, EdgeData> lastEdge = e;
-
-                boolean searchForNode = (combine != Combine.NONE);
-                for (int i = n.getData().getLayer() + 1; i < destNode.getData().getLayer(); i++) {
-
-                    Node<NodeData, EdgeData> foundNode = null;
-                    if (searchForNode) {
-                        for (Node<NodeData, EdgeData> sameLayerNode : layers[i]) {
-                            innerMostLoop++;
-
-                            if (combine == Combine.SAME_OUTPUTS) {
-                                if (sameLayerNode.getData().isDummy() && sameLayerNode.getData().getEdge().getFrom() == edge.getFrom()) {
-                                    foundNode = sameLayerNode;
-                                    break;
-                                }
-                            } else if (combine == Combine.SAME_INPUTS) {
-                                if (sameLayerNode.getData().isDummy() && sameLayerNode.getData().getEdge().getTo() == edge.getTo()) {
-                                    foundNode = sameLayerNode;
-                                    break;
-                                }
-                            }
-                        }
-                    }
-
-                    if (foundNode == null) {
-                        searchForNode = false;
-                        NodeData intermediateData = new NodeData(edge);
-                        Node<NodeData, EdgeData> curNode = graph.createNode(intermediateData, null);
-                        curNode.getData().setLayer(i);
-                        layers[i].add(0, curNode);
-                        sum++;
-                        lastEdge.remove();
-                        graph.createEdge(lastNode, curNode, e.getData(), null);
-                        assert lastNode.getData().getLayer() == curNode.getData().getLayer() - 1;
-                        lastEdge = graph.createEdge(curNode, destNode, e.getData(), null);
-                        lastNode = curNode;
-                    } else {
-                        lastEdge.remove();
-                        lastEdge = graph.createEdge(foundNode, destNode, e.getData(), null);
-                        lastNode = foundNode;
-                    }
-
-                }
-            }
-        }
-
-        if (TRACE) {
-            System.out.println("Number of edges: " + edgeCount);
-        }
-        if (TRACE) {
-            System.out.println("Dummy nodes inserted: " + sum);
-        }
-    }
-
-    private void assignLayerCoordinates(ArrayList<Node<NodeData, EdgeData>> layers[], int layerSizes[]) {
-        int cur = 0;
-        for (int i = 0; i < layers.length; i++) {
-            int maxHeight = 0;
-            for (Node<NodeData, EdgeData> n : layers[i]) {
-                maxHeight = Math.max(maxHeight, n.getData().getHeight());
-            }
-
-            layerSizes[i] = maxHeight;
-            for (Node<NodeData, EdgeData> n : layers[i]) {
-                int curCoordinate = cur + (maxHeight - n.getData().getHeight()) / 2;
-                n.getData().setLayerCoordinate(curCoordinate);
-            }
-            cur += maxHeight + layerOffset;
-
-        }
-    }
-
-    private void assignCoordinates(ArrayList<Node<NodeData, EdgeData>> layers[]) {
-
-        // TODO: change this
-        for (int i = 0; i < layers.length; i++) {
-            ArrayList<Node<NodeData, EdgeData>> curArray = layers[i];
-            int curY = 0;
-            for (Node<NodeData, EdgeData> n : curArray) {
-
-                n.getData().setCoordinate(curY);
-                if (!n.getData().isDummy()) {
-                    curY += n.getData().getWidth();
-                }
-                curY += OFFSET;
-
-            }
-        }
-
-        int curSol = evaluateSolution();
-        if (TRACE) {
-            System.out.println("First coordinate solution found: " + curSol);
-        }
-
-        // Sort to correct order
-        for (int i = 0; i < layers.length; i++) {
-            Collections.sort(layers[i], new Comparator<Node<NodeData, EdgeData>>() {
-
-                public int compare(Node<NodeData, EdgeData> o1, Node<NodeData, EdgeData> o2) {
-                    if (o2.getData().isDummy()) {
-                        return 1;
-                    } else if (o1.getData().isDummy()) {
-                        return -1;
-                    }
-                    return o2.getInEdges().size() + o2.getOutEdges().size() - o1.getInEdges().size() - o1.getOutEdges().size();
-                }
-            });
-        }
-
-
-        optimizeMedianTiming.start();
-        for (int i = 0; i < 2; i++) {
-            optimizeMedian(layers);
-            curSol = evaluateSolution();
-            if (TRACE) {
-                System.out.println("Current coordinate solution found: " + curSol);
-            }
-        }
-        optimizeMedianTiming.stop();
-        normalizeCoordinate();
-
-    }
-
-    private void normalizeCoordinate() {
-
-        int min = Integer.MAX_VALUE;
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            min = Math.min(min, n.getData().getCoordinate());
-        }
-
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            n.getData().setCoordinate(n.getData().getCoordinate() - min);
-        }
-
-    }
-
-    private void optimizeMedian(ArrayList<Node<NodeData, EdgeData>> layers[]) {
-
-        // Downsweep
-        for (int i = 1; i < layers.length; i++) {
-
-            ArrayList<Node<NodeData, EdgeData>> processingList = layers[i];
-            ArrayList<Node<NodeData, EdgeData>> alreadyAssigned = new ArrayList<Node<NodeData, EdgeData>>();
-            for (Node<NodeData, EdgeData> n : processingList) {
-
-
-                ArrayList<Node<NodeData, EdgeData>> preds = new ArrayList<Node<NodeData, EdgeData>>(n.getPredecessors());
-                int pos = n.getData().getCoordinate();
-                if (preds.size() > 0) {
-
-                    Collections.sort(preds, new Comparator<Node<NodeData, EdgeData>>() {
-
-                        public int compare(Node<NodeData, EdgeData> o1, Node<NodeData, EdgeData> o2) {
-                            return o1.getData().getCoordinate() - o2.getData().getCoordinate();
-                        }
-                    });
-
-                    if (preds.size() % 2 == 0) {
-                        assert preds.size() >= 2;
-                        pos = (preds.get(preds.size() / 2).getData().getCoordinate() - calcRelativeCoordinate(preds.get(preds.size() / 2), n) + preds.get(preds.size() / 2 - 1).getData().getCoordinate() - calcRelativeCoordinate(preds.get(preds.size() / 2 - 1), n)) / 2;
-                    } else {
-                        assert preds.size() >= 1;
-                        pos = preds.get(preds.size() / 2).getData().getCoordinate() - calcRelativeCoordinate(preds.get(preds.size() / 2), n);
-                    }
-                }
-
-                tryAdding(alreadyAssigned, n, pos);
-            }
-        }
-        // Upsweep
-        for (int i = layers.length - 2; i >= 0; i--) {
-            ArrayList<Node<NodeData, EdgeData>> processingList = layers[i];
-            ArrayList<Node<NodeData, EdgeData>> alreadyAssigned = new ArrayList<Node<NodeData, EdgeData>>();
-            for (Node<NodeData, EdgeData> n : processingList) {
-
-                ArrayList<Node<NodeData, EdgeData>> succs = new ArrayList<Node<NodeData, EdgeData>>(n.getSuccessors());
-                int pos = n.getData().getCoordinate();
-                if (succs.size() > 0) {
-
-                    Collections.sort(succs, new Comparator<Node<NodeData, EdgeData>>() {
-
-                        public int compare(Node<NodeData, EdgeData> o1, Node<NodeData, EdgeData> o2) {
-                            return o1.getData().getCoordinate() - o2.getData().getCoordinate();
-                        }
-                    });
-
-                    if (succs.size() % 2 == 0) {
-                        assert succs.size() >= 2;
-                        pos = (succs.get(succs.size() / 2).getData().getCoordinate() - calcRelativeCoordinate(n, succs.get(succs.size() / 2)) + succs.get(succs.size() / 2 - 1).getData().getCoordinate() - calcRelativeCoordinate(n, succs.get(succs.size() / 2 - 1))) / 2;
-                    } else {
-                        assert succs.size() >= 1;
-                        pos = succs.get(succs.size() / 2).getData().getCoordinate() - calcRelativeCoordinate(n, succs.get(succs.size() / 2));
-                    }
-                }
-
-                tryAdding(alreadyAssigned, n, pos);
-            }
-        }
-    }
-
-    private int median(ArrayList<Integer> arr) {
-        assert arr.size() > 0;
-        Collections.sort(arr);
-        if (arr.size() % 2 == 0) {
-            return (arr.get(arr.size() / 2) + arr.get(arr.size() / 2 - 1)) / 2;
-        } else {
-            return arr.get(arr.size() / 2);
-        }
-    }
-
-    private int calcRelativeCoordinate(Node<NodeData, EdgeData> n, Node<NodeData, EdgeData> succ) {
-
-        if (n.getData().isDummy() && succ.getData().isDummy()) {
-            return 0;
-        }
-
-        int pos = 0;
-        int pos2 = 0;
-        ArrayList<Integer> coords2 = new ArrayList<Integer>();
-        ArrayList<Integer> coords = new ArrayList<Integer>();
-        /*if(!n.getData().isDummy())*/ {
-            for (Edge<NodeData, EdgeData> e : n.getOutEdges()) {
-
-                //System.out.println("reversed: " + e.getData().isReversed());
-                if (e.getDest() == succ) {
-
-                    if (e.getData().isReversed()) {
-                        if (!n.getData().isDummy()) {
-                            coords.add(e.getData().getRelativeEnd().x);
-                        }
-
-                        if (!succ.getData().isDummy()) {
-                            coords2.add(e.getData().getRelativeStart().x);
-                        }
-                    } else {
-                        if (!n.getData().isDummy()) {
-                            coords.add(e.getData().getRelativeStart().x);
-                        }
-
-                        if (!succ.getData().isDummy()) {
-                            coords2.add(e.getData().getRelativeEnd().x);
-                        }
-                    }
-                }
-            }
-
-            // assert coords.size() > 0;
-            if (!n.getData().isDummy()) {
-                pos = median(coords);
-            }
-
-            if (!succ.getData().isDummy()) {
-                pos2 = median(coords2);
-            }
-        }
-        //System.out.println("coords=" + coords);
-        //System.out.println("coords2=" + coords2);
-
-        return pos - pos2;
-    }
-
-    private boolean intersect(int v1, int w1, int v2, int w2) {
-        if (v1 >= v2 && v1 < v2 + w2) {
-            return true;
-        }
-        if (v1 + w1 > v2 && v1 + w1 < v2 + w2) {
-            return true;
-        }
-        if (v1 < v2 && v1 + w1 > v2) {
-            return true;
-        }
-        return false;
-    }
-
-    private boolean intersect(Node<NodeData, EdgeData> n1, Node<NodeData, EdgeData> n2) {
-        return intersect(n1.getData().getCoordinate(), n1.getData().getWidth() + OFFSET, n2.getData().getCoordinate(), n2.getData().getWidth() + OFFSET);
-    }
-
-    private void tryAdding(List<Node<NodeData, EdgeData>> alreadyAssigned, Node<NodeData, EdgeData> node, int pos) {
-
-        boolean doesIntersect = false;
-        node.getData().setCoordinate(pos);
-        for (Node<NodeData, EdgeData> n : alreadyAssigned) {
-            if (n.getData().getCoordinate() + n.getData().getWidth() < pos) {
-                break;
-            } else if (intersect(node, n)) {
-                doesIntersect = true;
-                break;
-            }
-
-        }
-
-        if (!doesIntersect) {
-
-            // Everything fine, just place the node
-            int z = 0;
-            for (Node<NodeData, EdgeData> n : alreadyAssigned) {
-                if (pos > n.getData().getCoordinate()) {
-                    break;
-                }
-                z++;
-            }
-
-            if (z == -1) {
-                z = alreadyAssigned.size();
-            }
-
-
-            if (ASSERT) {
-                assert !findOverlap(alreadyAssigned, node);
-            }
-            alreadyAssigned.add(z, node);
-
-        } else {
-
-            assert alreadyAssigned.size() > 0;
-
-            // Search for alternative location
-            int minOffset = Integer.MAX_VALUE;
-            int minIndex = -1;
-            int minPos = 0;
-            int w = node.getData().getWidth() + OFFSET;
-
-            // Try top-most
-            minIndex = 0;
-            minPos = alreadyAssigned.get(0).getData().getCoordinate() + alreadyAssigned.get(0).getData().getWidth() + OFFSET;
-            minOffset = Math.abs(minPos - pos);
-
-            // Try bottom-most
-            Node<NodeData, EdgeData> lastNode = alreadyAssigned.get(alreadyAssigned.size() - 1);
-            int lastPos = lastNode.getData().getCoordinate() - w;
-            int lastOffset = Math.abs(lastPos - pos);
-            if (lastOffset < minOffset) {
-                minPos = lastPos;
-                minOffset = lastOffset;
-                minIndex = alreadyAssigned.size();
-            }
-
-            // Try between
-            for (int i = 0; i < alreadyAssigned.size() - 1; i++) {
-                Node<NodeData, EdgeData> curNode = alreadyAssigned.get(i);
-                Node<NodeData, EdgeData> nextNode = alreadyAssigned.get(i + 1);
-
-                int start = nextNode.getData().getCoordinate() + nextNode.getData().getWidth() + OFFSET;
-                int end = curNode.getData().getCoordinate() - OFFSET;
-
-                int bestPoss = end - node.getData().getWidth();
-                if (bestPoss < pos && pos - bestPoss > minOffset) {
-                    // No better solution possible => break
-                    break;
-                }
-
-                if (end - start >= node.getData().getWidth()) {
-                    // Node could fit here
-                    int cand1 = start;
-                    int cand2 = end - node.getData().getWidth();
-                    int off1 = Math.abs(cand1 - pos);
-                    int off2 = Math.abs(cand2 - pos);
-                    if (off1 < minOffset) {
-                        minPos = cand1;
-                        minOffset = off1;
-                        minIndex = i + 1;
-                    }
-
-                    if (off2 < minOffset) {
-                        minPos = cand2;
-                        minOffset = off2;
-                        minIndex = i + 1;
-                    }
-                }
-            }
-
-            assert minIndex != -1;
-            node.getData().setCoordinate(minPos);
-            if (ASSERT) {
-                assert !findOverlap(alreadyAssigned, node);
-            }
-            alreadyAssigned.add(minIndex, node);
-        }
-
-    }
-
-    private boolean findOverlap(List<Node<NodeData, EdgeData>> nodes, Node<NodeData, EdgeData> node) {
-
-        for (Node<NodeData, EdgeData> n1 : nodes) {
-            if (intersect(n1, node)) {
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    private int evaluateSolution() {
-
-        int sum = 0;
-        for (Edge<NodeData, EdgeData> e : graph.getEdges()) {
-            Node<NodeData, EdgeData> source = e.getSource();
-            Node<NodeData, EdgeData> dest = e.getDest();
-            int offset = 0;
-            offset = Math.abs(source.getData().getCoordinate() - dest.getData().getCoordinate());
-            sum += offset;
-        }
-
-        return sum;
-    }
-
-    private void crossingReduction(ArrayList<Node<NodeData, EdgeData>> layers[]) {
-
-        for (int i = 0; i < layers.length - 1; i++) {
-
-            ArrayList<Node<NodeData, EdgeData>> curNodes = layers[i];
-            ArrayList<Node<NodeData, EdgeData>> nextNodes = layers[i + 1];
-            for (Node<NodeData, EdgeData> n : curNodes) {
-                for (Node<NodeData, EdgeData> succ : n.getSuccessors()) {
-                    if (ASSERT) {
-                        assert nextNodes.contains(succ);
-                    }
-                    nextNodes.remove(succ);
-                    nextNodes.add(succ);
-                }
-            }
-
-        }
-
-    }
-
-    private void removeCycles(Set<Node<NodeData, EdgeData>> rootNodes) {
-        final List<Edge<NodeData, EdgeData>> reversedEdges = new ArrayList<Edge<NodeData, EdgeData>>();
-
-
-        int removedCount = 0;
-        int reversedCount = 0;
-
-        Graph.DFSTraversalVisitor visitor = graph.new DFSTraversalVisitor() {
-
-            @Override
-            public boolean visitEdge(Edge<NodeData, EdgeData> e, boolean backEdge) {
-                if (backEdge) {
-                    if (ASSERT) {
-                        assert !reversedEdges.contains(e);
-                    }
-                    reversedEdges.add(e);
-                    e.getData().setReversed(!e.getData().isReversed());
-                }
-
-                return e.getData().isImportant();
-            }
-        };
-        Set<Node<NodeData, EdgeData>> nodes = new HashSet<Node<NodeData, EdgeData>>();
-        nodes.addAll(rootNodes);
-
-        assert nodes.size() > 0;
-
-        this.graph.traverseDFS(nodes, visitor);
-
-        for (Edge<NodeData, EdgeData> e : reversedEdges) {
-            if (e.isSelfLoop()) {
-                e.remove();
-                removedCount++;
-            } else {
-                e.reverse();
-                reversedCount++;
-            }
-        }
-    }
-
-    private boolean checkRemoveCycles() {
-        return !graph.hasCycles();
-    }
-    // Only used by assignLayers
-    private int maxLayerTemp;
-
-    private int assignLayers(Set<Node<NodeData, EdgeData>> rootNodes, Set<? extends Vertex> firstLayerHints,
-            Set<? extends Vertex> lastLayerHints) {
-        this.maxLayerTemp = -1;
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            n.getData().setLayer(-1);
-        }
-
-        Graph.BFSTraversalVisitor traverser = graph.new BFSTraversalVisitor() {
-
-            @Override
-            public void visitNode(Node<NodeData, EdgeData> n, int depth) {
-                if (depth > n.getData().getLayer()) {
-                    n.getData().setLayer(depth);
-                    maxLayerTemp = Math.max(maxLayerTemp, depth);
-                }
-            }
-        };
-
-        for (Node<NodeData, EdgeData> n : rootNodes) {
-            if (n.getData().getLayer() == -1) {
-                this.graph.traverseBFS(n, traverser, true);
-            }
-        }
-
-        for (Vertex v : firstLayerHints) {
-            assert nodeMap.containsKey(v);
-            nodeMap.get(v).getData().setLayer(0);
-        }
-
-        for (Vertex v : lastLayerHints) {
-            assert nodeMap.containsKey(v);
-            nodeMap.get(v).getData().setLayer(maxLayerTemp);
-        }
-
-        return maxLayerTemp;
-    }
-
-    private boolean checkAssignLayers() {
-
-        for (Edge<NodeData, EdgeData> e : graph.getEdges()) {
-            Node<NodeData, EdgeData> source = e.getSource();
-            Node<NodeData, EdgeData> dest = e.getDest();
-
-
-            if (source.getData().getLayer() >= dest.getData().getLayer()) {
-                return false;
-            }
-        }
-        int maxLayer = 0;
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            assert n.getData().getLayer() >= 0;
-            if (n.getData().getLayer() > maxLayer) {
-                maxLayer = n.getData().getLayer();
-            }
-        }
-
-        int countPerLayer[] = new int[maxLayer + 1];
-        for (Node<NodeData, EdgeData> n : graph.getNodes()) {
-            countPerLayer[n.getData().getLayer()]++;
-        }
-
-        if (TRACE) {
-            System.out.println("Number of layers: " + maxLayer);
-        }
-        return true;
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Timing.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Timing.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Cluster.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Cluster.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,4 @@
     public void setBounds(Rectangle r);
 
     public Set<? extends Cluster> getSuccessors();
-
-    public Set<? extends Cluster> getPredecessors();
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,11 +23,7 @@
  */
 package com.sun.hotspot.igv.layout;
 
-import java.util.HashSet;
-import java.util.HashMap;
-import java.util.Set;
-import java.util.SortedSet;
-import java.util.TreeSet;
+import java.util.*;
 
 /**
  *
@@ -49,10 +45,10 @@
         this.links = links;
         assert verify();
 
-        vertices = new TreeSet<Vertex>();
-        portLinks = new HashMap<Port, Set<Link>>();
-        inputPorts = new HashMap<Vertex, Set<Port>>();
-        outputPorts = new HashMap<Vertex, Set<Port>>();
+        vertices = new TreeSet<>();
+        portLinks = new HashMap<>(links.size());
+        inputPorts = new HashMap<>(links.size());
+        outputPorts = new HashMap<>(links.size());
 
         for (Link l : links) {
             Port p = l.getFrom();
@@ -76,7 +72,7 @@
             }
 
             if (!portLinks.containsKey(p)) {
-                HashSet<Link> hashSet = new HashSet<Link>(3);
+                HashSet<Link> hashSet = new HashSet<>(3);
                 portLinks.put(p, hashSet);
             }
 
@@ -152,7 +148,7 @@
     //   whole graph is visited.
     public Set<Vertex> findRootVertices(Set<Vertex> startingRoots) {
 
-        Set<Vertex> notRootSet = new HashSet<Vertex>();
+        Set<Vertex> notRootSet = new HashSet<>();
         for (Vertex v : startingRoots) {
             if (!notRootSet.contains(v)) {
                 markNotRoot(notRootSet, v, v);
@@ -174,7 +170,7 @@
             }
         }
 
-        Set<Vertex> result = new HashSet<Vertex>();
+        Set<Vertex> result = new HashSet<>();
         for (Vertex v : tmpVertices) {
             if (!notRootSet.contains(v)) {
                 result.add(v);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutManager.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutManager.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
 
     public void doLayout(LayoutGraph graph);
 
-    public void doLayout(LayoutGraph graph, Set<? extends Vertex> firstLayerHint, Set<? extends Vertex> lastLayerHint, Set<? extends Link> importantLinks);
+    public void doLayout(LayoutGraph graph, Set<? extends Link> importantLinks);
 
     public void doRouting(LayoutGraph graph);
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Link.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Link.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -36,6 +36,8 @@
 
     public Port getTo();
 
+    public boolean isVIP();
+
     public List<Point> getControlPoints();
 
     public void setControlPoints(List<Point> list);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Port.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Port.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Vertex.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Vertex.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,8 +32,6 @@
  */
 public interface Vertex extends Comparable<Vertex> {
 
-    public Cluster getCluster();
-
     public Dimension getSize();
 
     public Point getPosition();
@@ -41,4 +39,6 @@
     public void setPosition(Point p);
 
     public boolean isRoot();
+
+    public Cluster getCluster();
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/genfiles.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/genfiles.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,8 +1,5 @@
-build.xml.data.CRC32=f8e21cb6
-build.xml.script.CRC32=a265137e
-build.xml.stylesheet.CRC32=79c3b980
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=f8e21cb6
-nbproject/build-impl.xml.script.CRC32=36f3138c
-nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
+nbproject/build-impl.xml.data.CRC32=5a0e591e
+nbproject/build-impl.xml.script.CRC32=4c38ce23
+nbproject/build-impl.xml.stylesheet.CRC32=e50cf570@2.62.1
--- a/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -27,7 +27,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.11.1.1</specification-version>
+                        <specification-version>7.30.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -35,7 +35,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.5.1</specification-version>
+                        <specification-version>7.18.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -43,7 +43,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.10.1.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupReceiver	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.sun.hotspot.igv.connection.Server
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Client.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Client.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,73 +24,48 @@
  */
 package com.sun.hotspot.igv.connection;
 
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.services.GroupCallback;
+import com.sun.hotspot.igv.data.GraphDocument;
+import com.sun.hotspot.igv.data.serialization.BinaryParser;
 import com.sun.hotspot.igv.data.serialization.Parser;
-import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
+import com.sun.hotspot.igv.data.services.GroupCallback;
 import java.io.IOException;
-import java.io.InputStream;
-import java.net.Socket;
-import javax.swing.JTextField;
+import java.nio.channels.SocketChannel;
 import org.openide.util.Exceptions;
-import org.openide.xml.XMLUtil;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
 
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class Client implements Runnable, GroupCallback {
+public class Client implements Runnable {
+    private final boolean binary;
+    private final SocketChannel socket;
+    private final GraphDocument rootDocument;
+    private final GroupCallback callback;
 
-    private Socket socket;
-    private JTextField networkTextField;
-    private GroupCallback callback;
-
-    public Client(Socket socket, JTextField networkTextField, GroupCallback callback) {
+    public Client(SocketChannel socket, GraphDocument rootDocument, GroupCallback callback, boolean  binary) {
         this.callback = callback;
         this.socket = socket;
-        this.networkTextField = networkTextField;
+        this.binary = binary;
+        this.rootDocument = rootDocument;
     }
 
+    @Override
     public void run() {
 
         try {
-            InputStream inputStream = socket.getInputStream();
-
-            if (networkTextField.isEnabled()) {
-
-                socket.getOutputStream().write('y');
-                InputSource is = new InputSource(inputStream);
-
-                try {
-                    XMLReader reader = XMLUtil.createXMLReader();
-                    Parser parser = new Parser(this);
-                    parser.parse(reader, is, null);
-                } catch (SAXException ex) {
-                    ex.printStackTrace();
-                }
+            final SocketChannel channel = socket;
+            channel.configureBlocking(true);
+            if (binary) {
+                new BinaryParser(channel, null, rootDocument, callback).parse();
             } else {
-                socket.getOutputStream().write('n');
+                // signal readiness to client VM (old protocol)
+                channel.socket().getOutputStream().write('y');
+                new Parser(channel, null, callback).parse();
             }
-
-            socket.close();
         } catch (IOException ex) {
             Exceptions.printStackTrace(ex);
-        }
-    }
-
-    public void started(final Group g) {
-        try {
-            RegexpPropertyMatcher matcher = new RegexpPropertyMatcher("name", ".*" + networkTextField.getText() + ".*");
-            if (g.getProperties().selectSingle(matcher) != null && networkTextField.isEnabled()) {
-                socket.getOutputStream().write('y');
-                callback.started(g);
-            } else {
-                socket.getOutputStream().write('n');
+        } finally {
+            try {
+                socket.close();
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
             }
-        } catch (IOException e) {
         }
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Server.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Server.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,17 +24,15 @@
  */
 package com.sun.hotspot.igv.connection;
 
-import com.sun.hotspot.igv.data.Group;
+import com.sun.hotspot.igv.data.GraphDocument;
 import com.sun.hotspot.igv.data.services.GroupCallback;
-import com.sun.hotspot.igv.data.services.GroupReceiver;
 import com.sun.hotspot.igv.settings.Settings;
-import java.awt.Component;
 import java.io.IOException;
-import java.net.ServerSocket;
-import java.net.Socket;
+import java.net.InetSocketAddress;
+import java.nio.channels.ServerSocketChannel;
+import java.nio.channels.SocketChannel;
 import java.util.prefs.PreferenceChangeEvent;
 import java.util.prefs.PreferenceChangeListener;
-import javax.swing.SwingUtilities;
 import org.openide.DialogDisplayer;
 import org.openide.NotifyDescriptor;
 import org.openide.util.RequestProcessor;
@@ -43,54 +41,26 @@
  *
  * @author Thomas Wuerthinger
  */
-public class Server implements GroupCallback, GroupReceiver, PreferenceChangeListener {
-
-    private javax.swing.JPanel jPanel1;
-    private javax.swing.JCheckBox networkCheckBox;
-    private javax.swing.JTextField networkTextField;
-    private ServerSocket serverSocket;
-    private GroupCallback callback;
+public class Server implements PreferenceChangeListener {
+    private final boolean binary;
+    private ServerSocketChannel serverSocket;
+    private final GraphDocument rootDocument;
+    private final GroupCallback callback;
     private int port;
     private Runnable serverRunnable;
 
-    public Component init(GroupCallback callback) {
-
+    public Server(GraphDocument rootDocument, GroupCallback callback, boolean binary) {
+        this.binary = binary;
+        this.rootDocument = rootDocument;
         this.callback = callback;
-
-        jPanel1 = new javax.swing.JPanel();
-        networkTextField = new javax.swing.JTextField();
-        networkCheckBox = new javax.swing.JCheckBox();
-
-
-        jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(5, 5, 5, 5));
-        jPanel1.setLayout(new java.awt.BorderLayout(10, 10));
-        jPanel1.add(networkTextField, java.awt.BorderLayout.CENTER);
-
-        networkCheckBox.setSelected(true);
-        org.openide.awt.Mnemonics.setLocalizedText(networkCheckBox, "Receive when name contains");
-        networkCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
-        networkCheckBox.setMargin(new java.awt.Insets(0, 0, 0, 0));
-        networkCheckBox.addChangeListener(new javax.swing.event.ChangeListener() {
-
-            public void stateChanged(javax.swing.event.ChangeEvent evt) {
-                networkCheckBoxChanged(evt);
-            }
-        });
-        jPanel1.add(networkCheckBox, java.awt.BorderLayout.WEST);
-        networkCheckBox.getAccessibleContext().setAccessibleName("Read from network when name contains");
-
         initializeNetwork();
         Settings.get().addPreferenceChangeListener(this);
-        return jPanel1;
     }
 
-    private void networkCheckBoxChanged(javax.swing.event.ChangeEvent evt) {
-        networkTextField.setEnabled(networkCheckBox.isSelected());
-    }
-
+    @Override
     public void preferenceChange(PreferenceChangeEvent e) {
 
-        int curPort = Integer.parseInt(Settings.get().get(Settings.PORT, Settings.PORT_DEFAULT));
+        int curPort = Integer.parseInt(Settings.get().get(binary ? Settings.PORT_BINARY : Settings.PORT, binary ? Settings.PORT_BINARY_DEFAULT : Settings.PORT_DEFAULT));
         if (curPort != port) {
             initializeNetwork();
         }
@@ -98,30 +68,32 @@
 
     private void initializeNetwork() {
 
-        int curPort = Integer.parseInt(Settings.get().get(Settings.PORT, Settings.PORT_DEFAULT));
+        int curPort = Integer.parseInt(Settings.get().get(binary ? Settings.PORT_BINARY : Settings.PORT, binary ? Settings.PORT_BINARY_DEFAULT : Settings.PORT_DEFAULT));
         this.port = curPort;
         try {
-            serverSocket = new java.net.ServerSocket(curPort);
-        } catch (IOException ex) {
-            NotifyDescriptor message = new NotifyDescriptor.Message("Could not create server. Listening for incoming data is disabled.", NotifyDescriptor.ERROR_MESSAGE);
+            serverSocket = ServerSocketChannel.open();
+            serverSocket.bind(new InetSocketAddress(curPort));
+        } catch (Throwable ex) {
+            NotifyDescriptor message = new NotifyDescriptor.Message("Could not create server. Listening for incoming binary data is disabled.", NotifyDescriptor.ERROR_MESSAGE);
             DialogDisplayer.getDefault().notifyLater(message);
             return;
         }
 
         Runnable runnable = new Runnable() {
 
+            @Override
             public void run() {
                 while (true) {
                     try {
-                        Socket clientSocket = serverSocket.accept();
+                        SocketChannel clientSocket = serverSocket.accept();
                         if (serverRunnable != this) {
                             clientSocket.close();
                             return;
                         }
-                        RequestProcessor.getDefault().post(new Client(clientSocket, networkTextField, Server.this), 0, Thread.MAX_PRIORITY);
+                        RequestProcessor.getDefault().post(new Client(clientSocket, rootDocument, callback, binary), 0, Thread.MAX_PRIORITY);
                     } catch (IOException ex) {
                         serverSocket = null;
-                        NotifyDescriptor message = new NotifyDescriptor.Message("Error during listening for incoming connections. Listening for incoming data is disabled.", NotifyDescriptor.ERROR_MESSAGE);
+                        NotifyDescriptor message = new NotifyDescriptor.Message("Error during listening for incoming connections. Listening for incoming binary data is disabled.", NotifyDescriptor.ERROR_MESSAGE);
                         DialogDisplayer.getDefault().notifyLater(message);
                         return;
                     }
@@ -133,13 +105,4 @@
 
         RequestProcessor.getDefault().post(runnable, 0, Thread.MAX_PRIORITY);
     }
-
-    public void started(final Group g) {
-        SwingUtilities.invokeLater(new Runnable() {
-
-            public void run() {
-                callback.started(g);
-            }
-        });
-    }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/README	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-The Ideal Graph Visualizer is a tool developed to help examine the
-intermediate representation of C2 which is commonly referred to as the
-"ideal graph".  It was developed in collaboration with the University
-of Linz in Austria and has been included as part of hotspot since that
-was the primary target of the tool.  The tool itself is fairly general
-with only a few modules that contain C2 specific elements.
-
-The tool is built on top of the NetBeans 6.1 rich client
-infrastructure and so requires NetBeans to build.  It currently
-requires Java 6 to run as it needs support for JavaScript for its
-filtering mechanism and assumes it's built into the platform.  It
-should build out of the box with NetBeans 6.1 and Java 6 or later.
-It's possible to run it on 1.5 by including Rhino on the classpath
-though that currently isn't working correctly.  Support for exporting
-graphs as SVG can be enabled by adding batik to the classpath which
-isn't included by default.  It can be built on top of NetBeans 6.0 if
-you change the required modules to be platform7 instead of platform8.
-
-The JVM support is controlled by the flag -XX:PrintIdealGraphLevel=#
-where # is:
-
-  0: no output, the default
-  1: dumps graph after parsing, before matching, and final code.
-     also dumps graph for failed compiles, if available
-  2: more detail, including after loop opts
-  3: even more detail
-  4: prints graph after parsing every bytecode (very slow)
-
-By default the JVM expects that it will connect to a visualizer on the
-local host on port 4444.  This can be configured using the options
--XX:PrintIdealGraphAddress= and -XX:PrintIdealGraphPort=.
-PrintIdealGraphAddress can actually be a hostname.
-
-Alternatively the output can be sent to a file using
--XX:PrintIdealGraphFile=filename.  Each compiler thread will get it's
-own file with unique names being generated by adding a number onto the
-provided file name.
-
-More information about the tool is available at
-http://wikis.sun.com/display/HotSpotInternals/IdealGraphVisualizer.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/README.md	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,50 @@
+# Overview
+
+The Ideal Graph Visualizer is a tool developed to help examine the intermediate
+representation of C2 which is commonly referred to as the "ideal graph". It was
+developed in collaboration with the University of Linz in Austria and has been
+included as part of hotspot since that was the primary target of the tool. The
+tool itself is fairly general with only a few modules that contain C2 specific
+elements.
+
+The tool is built on top of the NetBeans 7 rich client infrastructure and so
+requires NetBeans to build. It currently requires at least Java 6 to run as it
+needs support for JavaScript for its filtering mechanism and assumes it's built
+into the platform.  It should build out of the box with NetBeans 7.0 and Java 6
+or later.
+
+# Building and Running
+
+The build system used for IGV is ant. To download all required libraries and
+build IGV, issue `ant build`. To run IGV, use the `igv.sh` command; it will put
+all log messages generated by the run to the file `.igv.log`. To see all log
+messages generated during an IGV run, use `ant run`.
+
+# Usage
+
+The JVM support is controlled by the flag `-XX:PrintIdealGraphLevel=#` where `#`
+is:
+
+* 0: no output, the default
+* 1: dumps graph after parsing, before matching, and final code (also dumps
+     graphs for failed compilations, if available)
+* 2: more detail, including after loop opts
+* 3: even more detail
+* 4: prints graph after parsing every bytecode (very slow)
+
+By default the JVM expects that it will connect to a visualizer on the local
+host on port 4444. This can be configured using the options
+`-XX:PrintIdealGraphAddress=` and `-XX:PrintIdealGraphPort=`.
+`PrintIdealGraphAddress` can actually be a hostname.
+
+It is advisable to run the JVM with background compilation disabled (-Xbatch).
+Compilations going on in the background may be cancelled when the VM terminates,
+which can lead to incomplete dumps being sent to IGV.
+
+Alternatively the output can be sent to a file using
+`-XX:PrintIdealGraphFile=filename`. Each compiler thread will get it's own file
+with unique names being generated by adding a number onto the provided file
+name.
+
+More information about the tool is available at
+https://wikis.oracle.com/display/HotSpotInternals/IdealGraphVisualizer.
--- a/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/build.xml	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
-<!-- for some information on what you could do (e.g. targets to override). -->
-<!-- If you delete this file and reopen the project it will be recreated. -->
-<project name="com.sun.hotspot.igv.rhino" default="netbeans" basedir=".">
-    <description>Builds, tests, and runs the project com.sun.hotspot.igv.rhino.</description>
-    <import file="nbproject/build-impl.xml"/>
-</project>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/manifest.mf	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,6 +0,0 @@
-Manifest-Version: 1.0
-OpenIDE-Module: com.sun.hotspot.igv.rhino
-OpenIDE-Module-Layer: com/sun/hotspot/igv/rhino/layer.xml
-OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/rhino/Bundle.properties
-OpenIDE-Module-Specification-Version: 1.0
-
--- a/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/build-impl.xml	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-*** GENERATED FROM project.xml - DO NOT EDIT  ***
-***         EDIT ../build.xml INSTEAD         ***
--->
-<project name="com.sun.hotspot.igv.rhino-impl" basedir="..">
-    <property file="nbproject/private/suite-private.properties"/>
-    <property file="nbproject/suite.properties"/>
-    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
-    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
-    <property file="${suite.dir}/nbproject/platform.properties"/>
-    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
-        <attribute name="name"/>
-        <attribute name="value"/>
-        <sequential>
-            <property name="@{name}" value="${@{value}}"/>
-        </sequential>
-    </macrodef>
-    <property file="${user.properties.file}"/>
-    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <nbmproject2:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
-    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
-        <condition>
-            <not>
-                <available file="${harness.dir}" type="dir"/>
-            </not>
-        </condition>
-    </fail>
-    <import file="${harness.dir}/build.xml"/>
-</project>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/genfiles.properties	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-build.xml.data.CRC32=0c3e7912
-build.xml.script.CRC32=44d0050c
-build.xml.stylesheet.CRC32=79c3b980
-# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
-# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=0c3e7912
-nbproject/build-impl.xml.script.CRC32=7aab3f52
-nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- a/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
-    <type>org.netbeans.modules.apisupport.project</type>
-    <configuration>
-        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
-            <code-name-base>com.sun.hotspot.igv.rhino</code-name-base>
-            <suite-component/>
-            <module-dependencies>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.filter</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-            </module-dependencies>
-            <public-packages>
-                <package>com.sun.hotspot.igv.rhino</package>
-            </public-packages>
-        </data>
-    </configuration>
-</project>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/suite.properties	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-suite.dir=${basedir}/..
--- a/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.sun.hotspot.igv.rhino.RhinoScriptEngine
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/Bundle.properties	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-OpenIDE-Module-Name=RhinoScriptEngineProxy
--- a/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/RhinoScriptEngine.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.hotspot.igv.rhino;
-
-import com.sun.hotspot.igv.filter.ScriptEngineAbstraction;
-import com.sun.hotspot.igv.graph.Diagram;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class RhinoScriptEngine implements ScriptEngineAbstraction {
-
-    private String jsHelperText;
-    private Constructor importer;
-    private Method scope_put;
-    private Method cx_evaluateString;
-    private Method context_enter;
-    private Method context_exit;
-
-    public boolean initialize(String s) {
-        this.jsHelperText = s;
-        Class importerTopLevel = null;
-        try {
-            ClassLoader cl = RhinoScriptEngine.class.getClassLoader();
-            Class context = cl.loadClass("org.mozilla.javascript.Context");
-            Class scriptable = cl.loadClass("org.mozilla.javascript.Scriptable");
-            importerTopLevel = cl.loadClass("org.mozilla.javascript.ImporterTopLevel");
-            importer = importerTopLevel.getDeclaredConstructor(context);
-            scope_put = importerTopLevel.getMethod("put", new Class[]{String.class, scriptable, Object.class});
-            cx_evaluateString = context.getDeclaredMethod("evaluateString", new Class[]{scriptable, String.class, String.class, Integer.TYPE, Object.class});
-            context_enter = context.getDeclaredMethod("enter", new Class[0]);
-            context_exit = context.getDeclaredMethod("exit", new Class[0]);
-            return true;
-        } catch (NoSuchMethodException nsme) {
-            return false;
-        } catch (ClassNotFoundException cnfe) {
-            return false;
-        }
-    }
-
-    public void execute(Diagram d, String code) {
-        try {
-            Object cx = context_enter.invoke(null, (Object[]) null);
-            try {
-                Object scope = importer.newInstance(cx);
-                scope_put.invoke(scope, "IO", scope, System.out);
-                scope_put.invoke(scope, "graph", scope, d);
-                cx_evaluateString.invoke(cx, scope, jsHelperText, "jsHelper.js", 1, null);
-                cx_evaluateString.invoke(cx, scope, code, "<cmd>", 1, null);
-            } finally {
-                // Exit from the context.
-                context_exit.invoke(null, (Object[]) null);
-            }
-        } catch (InvocationTargetException iae) {
-        } catch (IllegalAccessException iae) {
-        } catch (InstantiationException iae) {
-        }
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/layer.xml	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
-<filesystem>
-</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/build.xml	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="com.sun.hotspot.igv.selectioncoordinator" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.selectioncoordinator.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/manifest.mf	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.selectioncoordinator
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/selectioncoordinator/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/build-impl.xml	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.selectioncoordinator-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/genfiles.properties	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,5 @@
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=13553862
+nbproject/build-impl.xml.script.CRC32=3db87c68
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@2.67.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/platform.properties	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,129 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    gsf1,\
+    harness,\
+    java2,\
+    nb6.1,\
+    profiler3
+disabled.modules=\
+    org.apache.xml.resolver,\
+    org.netbeans.api.debugger,\
+    org.netbeans.api.xml,\
+    org.netbeans.core.execution,\
+    org.netbeans.core.ide,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.nativeaccess,\
+    org.netbeans.core.output2,\
+    org.netbeans.insane,\
+    org.netbeans.lib.cvsclient,\
+    org.netbeans.libs.commons_logging,\
+    org.netbeans.libs.freemarker,\
+    org.netbeans.libs.ini4j,\
+    org.netbeans.libs.jna,\
+    org.netbeans.libs.jsch,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.libs.lucene,\
+    org.netbeans.libs.svnClientAdapter,\
+    org.netbeans.libs.xerces,\
+    org.netbeans.modules.applemenu,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.classfile,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.db,\
+    org.netbeans.modules.db.core,\
+    org.netbeans.modules.db.drivers,\
+    org.netbeans.modules.db.kit,\
+    org.netbeans.modules.db.mysql,\
+    org.netbeans.modules.db.sql.editor,\
+    org.netbeans.modules.db.sql.visualeditor,\
+    org.netbeans.modules.dbapi,\
+    org.netbeans.modules.defaults,\
+    org.netbeans.modules.diff,\
+    org.netbeans.modules.editor.bookmarks,\
+    org.netbeans.modules.editor.bracesmatching,\
+    org.netbeans.modules.editor.codetemplates,\
+    org.netbeans.modules.editor.completion,\
+    org.netbeans.modules.editor.errorstripe,\
+    org.netbeans.modules.editor.errorstripe.api,\
+    org.netbeans.modules.editor.guards,\
+    org.netbeans.modules.editor.highlights,\
+    org.netbeans.modules.editor.macros,\
+    org.netbeans.modules.editor.plain,\
+    org.netbeans.modules.editor.plain.lib,\
+    org.netbeans.modules.editor.structure,\
+    org.netbeans.modules.extbrowser,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.gototest,\
+    org.netbeans.modules.httpserver,\
+    org.netbeans.modules.ide.kit,\
+    org.netbeans.modules.image,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.jumpto,\
+    org.netbeans.modules.languages,\
+    org.netbeans.modules.languages.bat,\
+    org.netbeans.modules.languages.diff,\
+    org.netbeans.modules.languages.manifest,\
+    org.netbeans.modules.languages.sh,\
+    org.netbeans.modules.lexer.editorbridge,\
+    org.netbeans.modules.lexer.nbbridge,\
+    org.netbeans.modules.localhistory,\
+    org.netbeans.modules.masterfs,\
+    org.netbeans.modules.mercurial,\
+    org.netbeans.modules.progress.ui,\
+    org.netbeans.modules.project.ant,\
+    org.netbeans.modules.project.libraries,\
+    org.netbeans.modules.projectui,\
+    org.netbeans.modules.projectuiapi,\
+    org.netbeans.modules.properties,\
+    org.netbeans.modules.properties.syntax,\
+    org.netbeans.modules.refactoring.api,\
+    org.netbeans.modules.schema2beans,\
+    org.netbeans.modules.sendopts,\
+    org.netbeans.modules.server,\
+    org.netbeans.modules.servletapi,\
+    org.netbeans.modules.subversion,\
+    org.netbeans.modules.tasklist.kit,\
+    org.netbeans.modules.tasklist.projectint,\
+    org.netbeans.modules.tasklist.todo,\
+    org.netbeans.modules.tasklist.ui,\
+    org.netbeans.modules.templates,\
+    org.netbeans.modules.timers,\
+    org.netbeans.modules.usersguide,\
+    org.netbeans.modules.utilities,\
+    org.netbeans.modules.utilities.project,\
+    org.netbeans.modules.versioning,\
+    org.netbeans.modules.versioning.system.cvss,\
+    org.netbeans.modules.versioning.util,\
+    org.netbeans.modules.web.flyingsaucer,\
+    org.netbeans.modules.xml,\
+    org.netbeans.modules.xml.axi,\
+    org.netbeans.modules.xml.catalog,\
+    org.netbeans.modules.xml.core,\
+    org.netbeans.modules.xml.lexer,\
+    org.netbeans.modules.xml.multiview,\
+    org.netbeans.modules.xml.retriever,\
+    org.netbeans.modules.xml.schema.completion,\
+    org.netbeans.modules.xml.schema.model,\
+    org.netbeans.modules.xml.tax,\
+    org.netbeans.modules.xml.text,\
+    org.netbeans.modules.xml.tools,\
+    org.netbeans.modules.xml.wsdl.model,\
+    org.netbeans.modules.xml.xam,\
+    org.netbeans.modules.xml.xdm,\
+    org.netbeans.modules.xsl,\
+    org.netbeans.spi.debugger.ui,\
+    org.netbeans.spi.editor.hints,\
+    org.netbeans.spi.navigator,\
+    org.netbeans.spi.palette,\
+    org.netbeans.spi.tasklist,\
+    org.netbeans.spi.viewmodel,\
+    org.netbeans.swing.dirchooser,\
+    org.openide.compat,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    ide9,\
+    platform8
+nbjdk.active=default
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,2 @@
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.selectioncoordinator</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.selectioncoordinator</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/nbproject/suite.properties	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/src/com/sun/hotspot/igv/selectioncoordinator/Bundle.properties	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=SelectionCoordinator
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/SelectionCoordinator/src/com/sun/hotspot/igv/selectioncoordinator/SelectionCoordinator.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.selectioncoordinator;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas
+ */
+public class SelectionCoordinator {
+
+    private static SelectionCoordinator singleInstance = new SelectionCoordinator();
+    private Set<Object> selectedObjects;
+    private Set<Object> highlightedObjects;
+    private ChangedEvent<SelectionCoordinator> selectedChangedEvent;
+    private ChangedEvent<SelectionCoordinator> highlightedChangedEvent;
+
+    public static SelectionCoordinator getInstance() {
+        return singleInstance;
+    }
+
+    private SelectionCoordinator() {
+        selectedChangedEvent = new ChangedEvent<>(this);
+        highlightedChangedEvent = new ChangedEvent<>(this);
+        selectedObjects = new HashSet<>();
+        highlightedObjects = new HashSet<>();
+    }
+
+    public Set<Object> getSelectedObjects() {
+        return Collections.unmodifiableSet(selectedObjects);
+    }
+
+    public Set<Object> getHighlightedObjects() {
+        return Collections.unmodifiableSet(highlightedObjects);
+    }
+
+    public ChangedEvent<SelectionCoordinator> getHighlightedChangedEvent() {
+        return highlightedChangedEvent;
+    }
+
+    public ChangedEvent<SelectionCoordinator> getSelectedChangedEvent() {
+        return selectedChangedEvent;
+    }
+
+    public void addHighlighted(Object o) {
+        if (!highlightedObjects.contains(o)) {
+            highlightedObjects.add(o);
+            highlightedObjectsChanged();
+        }
+    }
+
+    public void removeHighlighted(Object o) {
+        if (highlightedObjects.contains(o)) {
+            highlightedObjects.remove(o);
+            highlightedObjectsChanged();
+        }
+    }
+
+    public void addAllHighlighted(Set<? extends Object> s) {
+        int oldSize = highlightedObjects.size();
+        highlightedObjects.addAll(s);
+        if (oldSize != highlightedObjects.size()) {
+            highlightedObjectsChanged();
+        }
+    }
+
+    public void removeAllHighlighted(Set<? extends Object> s) {
+        int oldSize = highlightedObjects.size();
+        highlightedObjects.removeAll(s);
+        if (oldSize != highlightedObjects.size()) {
+            highlightedObjectsChanged();
+        }
+    }
+
+    private void highlightedObjectsChanged() {
+        highlightedChangedEvent.fire();
+
+    }
+
+    public void addAllSelected(Set<? extends Object> s) {
+        int oldSize = selectedObjects.size();
+        selectedObjects.addAll(s);
+        if (oldSize != selectedObjects.size()) {
+            selectedObjectsChanged();
+        }
+    }
+
+    public void removeAllSelected(Set<? extends Object> s) {
+        int oldSize = selectedObjects.size();
+        selectedObjects.removeAll(s);
+        if (oldSize != selectedObjects.size()) {
+            selectedObjectsChanged();
+        }
+    }
+
+    public void setSelectedObjects(Set<? extends Object> s) {
+        assert s != null;
+        selectedObjects.clear();
+        selectedObjects.addAll(s);
+        selectedObjectsChanged();
+    }
+
+    private void selectedObjectsChanged() {
+        selectedChangedEvent.fire();
+    }
+
+    public void setHighlightedObjects(Set<? extends Object> s) {
+        assert s != null;
+        this.highlightedObjects.clear();
+        this.highlightedObjects.addAll(s);
+        highlightedObjectsChanged();
+    }
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -1,21 +1,29 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://www.netbeans.org/ns/project/1">
-    <type>org.netbeans.modules.apisupport.project</type>
-    <configuration>
-        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
-            <code-name-base>com.sun.hotspot.igv.servercompiler</code-name-base>
-            <suite-component/>
-            <module-dependencies>
-                <dependency>
-                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
-                    <build-prerequisite/>
-                    <compile-dependency/>
-                    <run-dependency>
-                        <specification-version>1.0</specification-version>
-                    </run-dependency>
-                </dependency>
-            </module-dependencies>
-            <public-packages/>
-        </data>
-    </configuration>
-</project>
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-project/3">
+            <code-name-base>com.sun.hotspot.igv.servercompiler</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.data</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.graph</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages/>
+        </data>
+    </configuration>
+</project>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupOrganizer	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.sun.hotspot.igv.servercompiler.JavaGroupOrganizer
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/JavaGroupOrganizer.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,200 +0,0 @@
-/*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.sun.hotspot.igv.servercompiler;
-
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.services.GroupOrganizer;
-import com.sun.hotspot.igv.data.Pair;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class JavaGroupOrganizer implements GroupOrganizer {
-
-    public String getName() {
-        return "Java structure";
-    }
-
-    public List<Pair<String, List<Group>>> organize(List<String> subFolders, List<Group> groups) {
-
-        List<Pair<String, List<Group>>> result = new ArrayList<Pair<String, List<Group>>>();
-
-        if (subFolders.size() == 0) {
-            buildResult(result, groups, packageNameProvider);
-        } else if (subFolders.size() == 1) {
-            buildResult(result, groups, classNameProvider);
-        } else if (subFolders.size() == 2) {
-            for (Group g : groups) {
-                List<Group> children = new ArrayList<Group>();
-                children.add(g);
-                Pair<String, List<Group>> p = new Pair<String, List<Group>>();
-                p.setLeft(reducedNameProvider.getName(g));
-                p.setRight(children);
-                result.add(p);
-            }
-        } else {
-            result.add(new Pair<String, List<Group>>("", groups));
-        }
-
-        return result;
-    }
-
-    private void buildResult(List<Pair<String, List<Group>>> result, List<Group> groups, NameProvider provider) {
-        HashMap<String, List<Group>> map = new HashMap<String, List<Group>>();
-        for (Group g : groups) {
-            String s = provider.getName(g);
-
-            if (!map.containsKey(s)) {
-                List<Group> list = new ArrayList<Group>();
-                Pair<String, List<Group>> pair = new Pair<String, List<Group>>(s, list);
-                result.add(pair);
-                map.put(s, list);
-            }
-
-            List<Group> curList = map.get(s);
-            curList.add(g);
-        }
-
-        Collections.sort(result, new Comparator<Pair<String, List<Group>>>() {
-
-            public int compare(Pair<String, List<Group>> a, Pair<String, List<Group>> b) {
-                return a.getLeft().compareTo(b.getLeft());
-            }
-        });
-    }
-
-    private static interface NameProvider {
-
-        public String getName(Group g);
-    }
-    private NameProvider reducedNameProvider = new NameProvider() {
-
-        public String getName(Group g) {
-            String name = g.getName();
-            assert name != null : "name of group must be set!";
-            final String noReducedName = name;
-
-            int firstPoint = name.indexOf(".");
-            if (firstPoint == -1) {
-                return noReducedName;
-            }
-
-            int firstParenthese = name.indexOf("(");
-            if (firstParenthese == -1 || firstParenthese < firstPoint) {
-                return noReducedName;
-            }
-
-            int current = firstPoint;
-            while (current > 0 && name.charAt(current) != ' ') {
-                current--;
-            }
-
-            String tmp = name.substring(0, firstParenthese);
-            int lastPoint = tmp.lastIndexOf(".");
-            if (lastPoint == -1) {
-                return noReducedName;
-            }
-
-            name = name.substring(0, current + 1) + name.substring(lastPoint + 1);
-            return name;
-        }
-    };
-    private NameProvider packageNameProvider = new NameProvider() {
-
-        public String getName(Group g) {
-            String name = g.getName();
-            assert name != null : "name of group must be set!";
-            final String noPackage = "<default>";
-
-            int firstPoint = name.indexOf(".");
-            if (firstPoint == -1) {
-                return noPackage;
-            }
-
-            int firstParenthese = name.indexOf("(");
-            if (firstParenthese == -1 || firstParenthese < firstPoint) {
-                return noPackage;
-            }
-
-            int current = firstPoint;
-            while (current > 0 && name.charAt(current) != ' ') {
-                current--;
-            }
-
-            String fullClassName = name.substring(current + 1, firstParenthese);
-            int lastPoint = fullClassName.lastIndexOf(".");
-            if (lastPoint == -1) {
-                return noPackage;
-            }
-            lastPoint = fullClassName.lastIndexOf(".", lastPoint - 1);
-            if (lastPoint == -1) {
-                return noPackage;
-            }
-
-            String packageName = fullClassName.substring(0, lastPoint);
-            return packageName;
-        }
-    };
-    private NameProvider classNameProvider = new NameProvider() {
-
-        public String getName(Group g) {
-            String name = g.getName();
-            assert name != null : "name of group must be set!";
-
-            final String noClass = "<noclass>";
-
-            int firstPoint = name.indexOf(".");
-            if (firstPoint == -1) {
-                return noClass;
-            }
-
-            int firstParenthese = name.indexOf("(");
-            if (firstParenthese == -1 || firstParenthese < firstPoint) {
-                return noClass;
-            }
-
-            int current = firstPoint;
-            while (current > 0 && name.charAt(current) != ' ') {
-                current--;
-            }
-
-            String fullClassName = name.substring(current + 1, firstParenthese);
-            int lastPoint = fullClassName.lastIndexOf(".");
-            if (lastPoint == -1) {
-                return noClass;
-            }
-            int lastlastPoint = fullClassName.lastIndexOf(".", lastPoint - 1);
-
-            String className = fullClassName.substring(lastlastPoint + 1, lastPoint);
-            return className;
-        }
-    };
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/ServerCompilerScheduler.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/ServerCompilerScheduler.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,17 +29,7 @@
 import com.sun.hotspot.igv.data.InputGraph;
 import com.sun.hotspot.igv.data.InputNode;
 import com.sun.hotspot.igv.data.services.Scheduler;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-import java.util.Vector;
+import java.util.*;
 
 /**
  *
@@ -50,8 +40,8 @@
     private static class Node {
 
         public InputNode inputNode;
-        public Set<Node> succs = new HashSet<Node>();
-        public List<Node> preds = new ArrayList<Node>();
+        public Set<Node> succs = new HashSet<>();
+        public List<Node> preds = new ArrayList<>();
         public InputBlock block;
         public boolean isBlockProjection;
         public boolean isBlockStart;
@@ -65,6 +55,7 @@
     private InputBlock[][] commonDominator;
     private static final Comparator<InputEdge> edgeComparator = new Comparator<InputEdge>() {
 
+        @Override
         public int compare(InputEdge o1, InputEdge o2) {
             return o1.getToIndex() - o2.getToIndex();
         }
@@ -72,13 +63,13 @@
 
     public void buildBlocks() {
 
-        blocks = new Vector<InputBlock>();
+        blocks = new Vector<>();
         Node root = findRoot();
         if (root == null) {
             return;
         }
-        Stack<Node> stack = new Stack<Node>();
-        Set<Node> visited = new HashSet<Node>();
+        Stack<Node> stack = new Stack<>();
+        Set<Node> visited = new HashSet<>();
         stack.add(root);
         int blockCount = 0;
         InputBlock rootBlock = null;
@@ -93,7 +84,7 @@
 
             if (!visited.contains(parent)) {
                 visited.add(parent);
-                InputBlock block = new InputBlock(graph, "" + blockCount);
+                InputBlock block = graph.addBlock(Integer.toString(blockCount));
                 blocks.add(block);
                 if (parent == root) {
                     rootBlock = block;
@@ -111,7 +102,12 @@
                         p = parent;
                         break;
                     }
+
                     p = p.preds.get(0);
+                    if (p == proj) {
+                        // Cycle, stop
+                        break;
+                    }
 
                     if (p.block == null) {
                         p.block = block;
@@ -125,7 +121,7 @@
                                 n = n.preds.get(0);
                             }
                             if (n.block != null) {
-                                n.block.addSuccessor(block);
+                                graph.addBlockEdge(n.block, block);
                             }
                         }
                     }
@@ -136,12 +132,12 @@
                         for (Node n2 : n.succs) {
 
                             if (n2 != parent && n2.block != null && n2.block != rootBlock) {
-                                block.addSuccessor(n2.block);
+                                graph.addBlockEdge(block, n2.block);
                             }
                         }
                     } else {
                         if (n != parent && n.block != null && n.block != rootBlock) {
-                            block.addSuccessor(n.block);
+                            graph.addBlockEdge(block, n.block);
                         }
                     }
                 }
@@ -161,7 +157,7 @@
                 }
 
                 if (pushed == 0 && p == root) {
-                // TODO: special handling when root backedges are not built yet
+                    // TODO: special handling when root backedges are not built yet
                 }
             }
         }
@@ -174,7 +170,7 @@
         }
 
         int z = 0;
-        blockIndex = new HashMap<InputBlock, Integer>();
+        blockIndex = new HashMap<>(blocks.size());
         for (InputBlock b : blocks) {
             blockIndex.put(b, z);
             z++;
@@ -185,20 +181,25 @@
         return n.getProperties().get("block");
     }
 
+    @Override
     public Collection<InputBlock> schedule(InputGraph graph) {
+        if (graph.getNodes().isEmpty()) {
+            return Collections.emptyList();
+        }
+
         if (graph.getBlocks().size() > 0) {
-            Collection<InputNode> tmpNodes = new ArrayList<InputNode>(graph.getNodes());
+            Collection<InputNode> tmpNodes = new ArrayList<>(graph.getNodes());
             for (InputNode n : tmpNodes) {
                 String block = getBlockName(n);
                 if (graph.getBlock(n) == null) {
-                    graph.getBlock(block).addNode(n);
+                    graph.getBlock(block).addNode(n.getId());
                     assert graph.getBlock(n) != null;
                 }
             }
             return graph.getBlocks();
         } else {
-            nodes = new ArrayList<Node>();
-            inputNodeToNode = new HashMap<InputNode, Node>();
+            nodes = new ArrayList<>();
+            inputNodeToNode = new HashMap<>(graph.getNodes().size());
 
             this.graph = graph;
             buildUpGraph();
@@ -207,7 +208,16 @@
             buildCommonDominators();
             scheduleLatest();
 
+            InputBlock noBlock = null;
             for (InputNode n : graph.getNodes()) {
+                if (graph.getBlock(n) == null) {
+                    if (noBlock == null) {
+                        noBlock = graph.addBlock("(no block)");
+                        blocks.add(noBlock);
+                    }
+
+                    graph.setBlock(n, noBlock);
+                }
                 assert graph.getBlock(n) != null;
             }
 
@@ -215,15 +225,17 @@
         }
     }
 
-    public void scheduleLatest() {
-
-
+    private void scheduleLatest() {
         Node root = findRoot();
+        if(root == null) {
+            assert false : "No root found!";
+            return;
+        }
 
         // Mark all nodes reachable in backward traversal from root
-        Set<Node> reachable = new HashSet<Node>();
+        Set<Node> reachable = new HashSet<>();
         reachable.add(root);
-        Stack<Node> stack = new Stack<Node>();
+        Stack<Node> stack = new Stack<>();
         stack.push(root);
         while (!stack.isEmpty()) {
             Node cur = stack.pop();
@@ -235,7 +247,7 @@
             }
         }
 
-        Set<Node> unscheduled = new HashSet<Node>();
+        Set<Node> unscheduled = new HashSet<>();
         for (Node n : this.nodes) {
             if (n.block == null && reachable.contains(n)) {
                 unscheduled.add(n);
@@ -245,7 +257,7 @@
         while (unscheduled.size() > 0) {
             boolean progress = false;
 
-            Set<Node> newUnscheduled = new HashSet<Node>();
+            Set<Node> newUnscheduled = new HashSet<>();
             for (Node n : unscheduled) {
 
                 InputBlock block = null;
@@ -285,7 +297,7 @@
             }
         }
 
-        Set<Node> curReachable = new HashSet<Node>(reachable);
+        Set<Node> curReachable = new HashSet<>(reachable);
         for (Node n : curReachable) {
             if (n.block != null) {
                 for (Node s : n.succs) {
@@ -300,7 +312,7 @@
 
     private void markWithBlock(Node n, InputBlock b, Set<Node> reachable) {
         assert !reachable.contains(n);
-        Stack<Node> stack = new Stack<Node>();
+        Stack<Node> stack = new Stack<>();
         stack.push(n);
         n.block = b;
         b.addNode(n.inputNode.getId());
@@ -356,7 +368,7 @@
         if (ba == bb) {
             return ba;
         }
-        Set<InputBlock> visited = new HashSet<InputBlock>();
+        Set<InputBlock> visited = new HashSet<>();
         while (ba != null) {
             visited.add(ba);
             ba = dominatorMap.get(ba);
@@ -374,12 +386,12 @@
     }
 
     public void buildDominators() {
-        dominatorMap = new HashMap<InputBlock, InputBlock>();
+        dominatorMap = new HashMap<>(graph.getBlocks().size());
         if (blocks.size() == 0) {
             return;
         }
-        Vector<BlockIntermediate> intermediate = new Vector<BlockIntermediate>();
-        Map<InputBlock, BlockIntermediate> map = new HashMap<InputBlock, BlockIntermediate>();
+        Vector<BlockIntermediate> intermediate = new Vector<>(graph.getBlocks().size());
+        Map<InputBlock, BlockIntermediate> map = new HashMap<>(graph.getBlocks().size());
         int z = 0;
         for (InputBlock b : blocks) {
             BlockIntermediate bi = new BlockIntermediate();
@@ -390,16 +402,16 @@
             bi.parent = -1;
             bi.label = z;
             bi.ancestor = -1;
-            bi.pred = new ArrayList<Integer>();
-            bi.bucket = new ArrayList<Integer>();
+            bi.pred = new ArrayList<>();
+            bi.bucket = new ArrayList<>();
             intermediate.add(bi);
             map.put(b, bi);
             z++;
         }
-        Stack<Integer> stack = new Stack<Integer>();
+        Stack<Integer> stack = new Stack<>();
         stack.add(0);
 
-        Vector<BlockIntermediate> array = new Vector<BlockIntermediate>();
+        Vector<BlockIntermediate> array = new Vector<>();
         intermediate.get(0).dominator = 0;
 
         int n = 0;
@@ -538,15 +550,30 @@
     }
 
     private Node findRoot() {
+        Node minNode = null;
+        Node alternativeRoot = null;
 
-        for (Node n : nodes) {
-            InputNode inputNode = n.inputNode;
-            if (inputNode.getProperties().get("name").equals("Root")) {
-                return n;
+        for (Node node : nodes) {
+            InputNode inputNode = node.inputNode;
+            String s = inputNode.getProperties().get("name");
+            if (s != null && s.equals("Root")) {
+                return node;
+            }
+
+            if (alternativeRoot == null && node.preds.isEmpty()) {
+                alternativeRoot = node;
+            }
+
+            if (minNode == null || node.inputNode.getId() < minNode.inputNode.getId()) {
+                minNode = node;
             }
         }
 
-        return null;
+        if (alternativeRoot != null) {
+            return alternativeRoot;
+        } else {
+            return minNode;
+        }
     }
 
     public void buildUpGraph() {
@@ -562,7 +589,7 @@
             inputNodeToNode.put(n, node);
         }
 
-        Map<Integer, List<InputEdge>> edgeMap = new HashMap<Integer, List<InputEdge>>();
+        Map<Integer, List<InputEdge>> edgeMap = new HashMap<>(graph.getEdges().size());
         for (InputEdge e : graph.getEdges()) {
 
             int to = e.getTo();
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/color.filter	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/color.filter	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,18 @@
 colorize("name", ".*", yellow);
 colorize("name", "Catch.*", blue);
-
 colorize("name", "Region|Loop|CountedLoop|Root", red);
 colorize("name", "CProj|IfFalse|IfTrue|JProj|CatchProj", magenta);
+colorize("name", "Con.*", orange);
+colorize("name", "Parm|Proj", lightGray);
+
+// Nodes with bci
+colorize("bci", "..*", magenta);
+
+// Line style
+var f = new ColorFilter("Line Style filter");
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "int:")), null, Color.BLUE, null));
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "control")), null, Color.RED, null));
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "memory")), null, Color.GREEN, null));
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "tuple:")), null, Color.MAGENTA, null));
+f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "bottom")), null, Color.LIGHT_GRAY, null));
+f.apply(graph);
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/combine.filter	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-var f = new CombineFilter("Combine Filter");
-f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", ".*"), new Properties.RegexpPropertyMatcher("name", "Proj|IfFalse|IfTrue|JProj|MachProj|JumpProj|CatchProj")));
-f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", "Cmp.*"), new Properties.RegexpPropertyMatcher("name", "Bool")));
-f.apply(graph);
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/extendedColor.filter	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
-colorize("name", "Con.*", orange);
-colorize("name", "Parm|Proj", lightGray);
-colorize("bci", "..*", magenta);
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/linestyle.filter	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-var f = new ColorFilter("Line Style filter");
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "int:")), null, Color.BLUE, null));
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "control")), null, Color.RED, null));
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "memory")), null, Color.GREEN, null));
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "tuple:")), null, Color.MAGENTA, null));
-f.addRule(new ColorFilter.ColorRule(new MatcherSelector(new Properties.StringPropertyMatcher("type", "bottom")), null, Color.LIGHT_GRAY, null));
-f.apply(graph);
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/onlyControlFlow.filter	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/onlyControlFlow.filter	Tue May 05 19:27:08 2015 +0200
@@ -20,5 +20,5 @@
     ), false
   )
 );
-f.addRule( new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher("name", "Phi|Store.")), false));
+f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher("name", "Phi|Store."))));
 f.apply(graph);
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/register.filter	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/register.filter	Tue May 05 19:27:08 2015 +0200
@@ -1,4 +1,5 @@
+// Register coloring
 colorize("reg", "EAX", green);
 colorize("reg", "EFLAGS", gray);
 colorize("reg", "EBP", orange);
-colorize("reg", "ECX", cyan);
+colorize("reg", "ECX", cyan);
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/remove.filter	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/remove.filter	Tue May 05 19:27:08 2015 +0200
@@ -1,1 +1,8 @@
-remove("dump_spec", "FramePtr|ReturnAdr|I_O"); 
\ No newline at end of file
+remove("dump_spec", "FramePtr|ReturnAdr|I_O"); 
+removeInputs("name", "Root");
+var f = new RemoveSelfLoopsFilter("Remove Self-Loops");
+f.apply(graph);
+removeInputs("name", "SafePoint|CallStaticJava|CallDynamicJava|CallJava|CallLeaf|CallRuntime|AbstractLock|CallLeafNoFP|Call|CallStaticJavaDirect", 5);
+removeInputs("name", "Unlock|Lock", 7);
+removeInputs("name", "Allocate", 7);
+removeInputs("name", "AllocateArray", 9);
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeMemory.filter	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
-
-//var f = new RemoveFilter("Remove Memory");
-//f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.StringPropertyMatcher("dump_spec", "Memory")), false));
-//f.addRule(new RemoveFilter.RemoveRule(new AndSelector(new MatcherSelector(new Properties.StringPropertyMatcher("name", "Proj")), new MatcherSelector(new Properties.StringPropertyMatcher("type", "memory"))), false));
-//f.apply(graph);
-
-remove("dump_spec", "Memory");
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeRootInputs.filter	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-removeInputs("name", "Root");
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeSafepointInputs.filter	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,4 +0,0 @@
-removeInputs("name", "SafePoint|CallStaticJava|CallDynamicJava|CallJava|CallLeaf|CallRuntime|AbstractLock|CallLeafNoFP|Call|CallStaticJavaDirect", 5);
-removeInputs("name", "Unlock|Lock", 7);
-removeInputs("name", "Allocate", 7);
-removeInputs("name", "AllocateArray", 9);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeSelfLoops.filter	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-var f = new RemoveSelfLoopsFilter("Remove Self-Loops");
-f.apply(graph);
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/split.filter	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2 +0,0 @@
-split("name", "BoxLock");
-split("name", "(Con.*)|(loadCon.*)");
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/structural.filter	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,6 @@
+var f = new CombineFilter("Combine Filter");
+f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", ".*"), new Properties.RegexpPropertyMatcher("name", "Proj|IfFalse|IfTrue|JProj|MachProj|JumpProj|CatchProj")));
+f.addRule(new CombineFilter.CombineRule(new Properties.RegexpPropertyMatcher("name", "Cmp.*"), new Properties.RegexpPropertyMatcher("name", "Bool")));
+f.apply(graph);
+split("name", "BoxLock");
+split("name", "(Con.*)|(loadCon.*)", "[dump_spec]");
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/layer.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/layer.xml	Tue May 05 19:27:08 2015 +0200
@@ -2,60 +2,28 @@
 <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
 <filesystem>
       <folder name="Filters">
-        <file name="Basic Coloring" url="filters/color.filter">
-            <attr name="enabled" boolvalue="true"/>
-        </file>
-        <file name="Matcher Flags Coloring" url="filters/matchingFlags.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Basic Coloring"/>
-        </file>
-        <file name="Register Coloring" url="filters/register.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Matcher Flags Coloring"/>
+        <file name="C2 Basic Coloring" url="filters/color.filter">
+            <attr name="enabled" boolvalue="false"/>
         </file>
-        <file name="Extended Coloring" url="filters/extendedColor.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Register Coloring"/>
-        </file>
-        <file name="Line Coloring" url="filters/linestyle.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Extended Coloring"/>
+        <file name="C2 Matcher Flags Coloring" url="filters/matchingFlags.filter">
+            <attr name="enabled" boolvalue="false"/>
+            <attr name="after" stringvalue="C2 Basic Coloring"/>
         </file>
-        <file name="Difference Coloring" url="filters/difference.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Line Coloring"/>
-        </file>
-        <file name="Only Control Flow" url="filters/onlyControlFlow.filter">
+        <file name="C2 Register Coloring" url="filters/register.filter">
             <attr name="enabled" boolvalue="false"/>
-            <attr name="after" stringvalue="Difference Coloring"/>
+            <attr name="after" stringvalue="C2 Matcher Flags Coloring"/>
         </file>
-        <file name="Remove FramePtr, I_O and Return Address" url="filters/remove.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Only Control Flow"/>
-        </file>
-        <file name="Remove Memory" url="filters/removeMemory.filter">
+        <file name="C2 Only Control Flow" url="filters/onlyControlFlow.filter">
             <attr name="enabled" boolvalue="false"/>
-            <attr name="after" stringvalue="Remove FramePtr, I_O and Return Address"/>
-        </file>
-        <file name="Remove Root Inputs" url="filters/removeRootInputs.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Remove Memory"/>
+            <attr name="after" stringvalue="C2 Register Coloring"/>
         </file>
-        <file name="Remove Safepoint Inputs" url="filters/removeSafepointInputs.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Remove Root Inputs"/>
-        </file>
-        <file name="Remove Self Loops" url="filters/removeSelfLoops.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Remove Safepoint Inputs"/>
+        <file name="C2 Remove Filter" url="filters/remove.filter">
+            <attr name="enabled" boolvalue="false"/>
+            <attr name="after" stringvalue="C2 Only Control Flow"/>
         </file>
-        <file name="Combine" url="filters/combine.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Remove Self Loops"/>
+        <file name="C2 Structural" url="filters/structural.filter">
+            <attr name="enabled" boolvalue="false"/>
+            <attr name="after" stringvalue="C2 Remove Filter"/>
         </file>
-        <file name="Split" url="filters/split.filter">
-            <attr name="enabled" boolvalue="true"/>
-            <attr name="after" stringvalue="Combine"/>
-        </file>
-    </folder>
+    </folder>	
 </filesystem>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -12,7 +12,7 @@
                     <compile-dependency/>
                     <run-dependency>
                         <release-version>1</release-version>
-                        <specification-version>1.4</specification-version>
+                        <specification-version>1.16.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -21,7 +21,7 @@
                     <compile-dependency/>
                     <run-dependency>
                         <release-version>1</release-version>
-                        <specification-version>1.5</specification-version>
+                        <specification-version>1.21.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -29,7 +29,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.11.0.1</specification-version>
+                        <specification-version>7.30.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -37,7 +37,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/Settings.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/Settings.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,7 +37,9 @@
     public final static String NODE_WIDTH = "nodeWidth";
     public final static String NODE_WIDTH_DEFAULT = "100";
     public final static String PORT = "port";
+    public final static String PORT_BINARY = "portBinary";
     public final static String PORT_DEFAULT = "4444";
+    public final static String PORT_BINARY_DEFAULT = "4445";
     public final static String DIRECTORY = "directory";
     public final static String DIRECTORY_DEFAULT = System.getProperty("user.dir");
 
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsCategory.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsCategory.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,8 +27,8 @@
 import javax.swing.ImageIcon;
 import org.netbeans.spi.options.OptionsCategory;
 import org.netbeans.spi.options.OptionsPanelController;
+import org.openide.util.ImageUtilities;
 import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
 
 /**
  *
@@ -38,17 +38,20 @@
 
     @Override
     public Icon getIcon() {
-        return new ImageIcon(Utilities.loadImage("com/sun/hotspot/igv/settings/settings.gif"));
+        return new ImageIcon(ImageUtilities.loadImage("com/sun/hotspot/igv/settings/settings.png"));
     }
 
+    @Override
     public String getCategoryName() {
         return NbBundle.getMessage(ViewOptionsCategory.class, "OptionsCategory_Name_View");
     }
 
+    @Override
     public String getTitle() {
         return NbBundle.getMessage(ViewOptionsCategory.class, "OptionsCategory_Title_View");
     }
 
+    @Override
     public OptionsPanelController create() {
         return new ViewOptionsPanelController();
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsPanelController.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsPanelController.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,40 +40,49 @@
     private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
     private boolean changed;
 
+    @Override
     public void update() {
         getPanel().load();
         changed = false;
     }
 
+    @Override
     public void applyChanges() {
         getPanel().store();
         changed = false;
     }
 
+    @Override
     public void cancel() {
     // need not do anything special, if no changes have been persisted yet
     }
 
+    @Override
     public boolean isValid() {
         return getPanel().valid();
     }
 
+    @Override
     public boolean isChanged() {
         return changed;
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return null; // new HelpCtx("...ID") if you have a help set
     }
 
+    @Override
     public JComponent getComponent(Lookup masterLookup) {
         return getPanel();
     }
 
+    @Override
     public void addPropertyChangeListener(PropertyChangeListener l) {
         pcs.addPropertyChangeListener(l);
     }
 
+    @Override
     public void removePropertyChangeListener(PropertyChangeListener l) {
         pcs.removePropertyChangeListener(l);
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewPanel.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewPanel.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/layer.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/layer.xml	Tue May 05 19:27:08 2015 +0200
@@ -2,8 +2,10 @@
 <!DOCTYPE filesystem PUBLIC "-//NetBeans//DTD Filesystem 1.1//EN" "http://www.netbeans.org/dtds/filesystem-1_1.dtd">
 <filesystem>
     <folder name="OptionsDialog">
-        <file name="Advanced.instance_hidden"/>
-        <file name="General.instance_hidden"/>
-        <file name="com-sun-hotspot-igv-settings-ViewOptionsCategory.instance"/>
+      <!-- <file name="Advanced.instance_hidden"/>
+        <file name="General.instance_hidden"/>-->
+        <file name="com-sun-hotspot-igv-settings-ViewOptionsCategory.instance">
+            <attr name="position" intvalue="100" />
+        </file>
     </folder>
 </filesystem>
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/settings.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/settings.png has changed
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -19,7 +19,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>2.9</specification-version>
+                        <specification-version>2.27.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.39.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -27,7 +35,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.2.1.1</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -35,7 +43,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.10.1.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/BoundedZoomAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/BoundedZoomAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ColorIcon.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ColorIcon.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -34,21 +34,26 @@
  */
 public class ColorIcon implements Icon {
 
-    private Color color;
+    private final Color color;
 
     public ColorIcon(Color c) {
         color = c;
     }
 
+    @Override
     public void paintIcon(Component c, Graphics g, int x, int y) {
+        Color oldColor = g.getColor();
         g.setColor(color);
         g.fillRect(x, y, 16, 16);
+        g.setColor(oldColor);
     }
 
+    @Override
     public int getIconWidth() {
         return 16;
     }
 
+    @Override
     public int getIconHeight() {
         return 16;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ContextAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ContextAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,7 @@
 package com.sun.hotspot.igv.util;
 
 import java.awt.EventQueue;
-import org.openide.util.ContextAwareAction;
-import org.openide.util.Lookup;
-import org.openide.util.LookupEvent;
-import org.openide.util.LookupListener;
-import org.openide.util.Utilities;
+import org.openide.util.*;
 import org.openide.util.actions.CallableSystemAction;
 
 /**
@@ -56,6 +52,7 @@
         resultChanged(null);
     }
 
+    @Override
     public void resultChanged(LookupEvent e) {
         if (result.allItems().size() != 0) {
             update(result.allInstances().iterator().next());
@@ -71,6 +68,7 @@
         // Ensure it's AWT event thread
         EventQueue.invokeLater(new Runnable() {
 
+            @Override
             public void run() {
                 performAction(t);
             }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/DoubleClickAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/DoubleClickAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/DoubleClickHandler.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/DoubleClickHandler.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ExtendedSatelliteComponent.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ExtendedSatelliteComponent.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,11 +23,10 @@
  */
 package com.sun.hotspot.igv.util;
 
-import org.netbeans.api.visual.widget.Scene;
-
-import javax.swing.*;
 import java.awt.*;
 import java.awt.event.*;
+import javax.swing.JComponent;
+import org.netbeans.api.visual.widget.Scene;
 
 /**
  * @author David Kaspar
@@ -118,27 +117,34 @@
         }
     }
 
+    @Override
     public void mouseClicked(MouseEvent e) {
     }
 
+    @Override
     public void mousePressed(MouseEvent e) {
         moveVisibleRect(e.getPoint());
     }
 
+    @Override
     public void mouseReleased(MouseEvent e) {
         moveVisibleRect(e.getPoint());
     }
 
+    @Override
     public void mouseEntered(MouseEvent e) {
     }
 
+    @Override
     public void mouseExited(MouseEvent e) {
     }
 
+    @Override
     public void mouseDragged(MouseEvent e) {
         moveVisibleRect(e.getPoint());
     }
 
+    @Override
     public void mouseMoved(MouseEvent e) {
     }
 
@@ -170,26 +176,33 @@
 
     }
 
+    @Override
     public void sceneRepaint() {
     }
 
+    @Override
     public void sceneValidating() {
     }
 
+    @Override
     public void sceneValidated() {
     }
 
+    @Override
     public void componentResized(ComponentEvent e) {
         repaint();
     }
 
+    @Override
     public void componentMoved(ComponentEvent e) {
         repaint();
     }
 
+    @Override
     public void componentShown(ComponentEvent e) {
     }
 
+    @Override
     public void componentHidden(ComponentEvent e) {
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ExtendedSelectAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ExtendedSelectAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/LookupHistory.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.util;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.openide.util.Lookup.Result;
+import org.openide.util.LookupEvent;
+import org.openide.util.LookupListener;
+import org.openide.util.Utilities;
+
+/**
+ *
+ * @author Thomas
+ */
+public class LookupHistory {
+
+    private static Map<Class, LookupHistoryImpl> cache = new HashMap<>();
+
+    private static class LookupHistoryImpl<T> implements LookupListener {
+
+        private Class<T> klass;
+        private Result<T> result;
+        private T last;
+
+        public LookupHistoryImpl(Class<T> klass) {
+            this.klass = klass;
+            result = Utilities.actionsGlobalContext().lookupResult(klass);
+            result.addLookupListener(this);
+            last = Utilities.actionsGlobalContext().lookup(klass);
+        }
+
+        public T getLast() {
+            return last;
+        }
+
+        @Override
+        public void resultChanged(LookupEvent ev) {
+            T current = Utilities.actionsGlobalContext().lookup(klass);
+            if (current != null) {
+                last = current;
+            }
+        }
+    }
+
+    public static <T> void init(Class<T> klass) {
+        if (!cache.containsKey(klass)) {
+            cache.put(klass, new LookupHistoryImpl<>(klass));
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public static <T> T getLast(Class<T> klass) {
+        init(klass);
+        assert cache.containsKey(klass);
+        return (T) cache.get(klass).getLast();
+    }
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/PropertiesSheet.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/PropertiesSheet.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSlider.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSlider.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,33 +25,27 @@
 package com.sun.hotspot.igv.util;
 
 import com.sun.hotspot.igv.data.ChangedListener;
-import java.awt.Color;
-import java.awt.Cursor;
-import java.awt.Dimension;
-import java.awt.FontMetrics;
-import java.awt.Graphics;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
+import java.awt.*;
+import java.awt.geom.*;
 import java.awt.event.MouseEvent;
 import java.awt.event.MouseListener;
 import java.awt.event.MouseMotionListener;
 import java.util.List;
-import javax.swing.JComponent;
+import javax.swing.*;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public class RangeSlider extends JComponent implements ChangedListener<RangeSliderModel>, MouseListener, MouseMotionListener {
+public class RangeSlider extends JComponent implements ChangedListener<RangeSliderModel>, MouseListener, MouseMotionListener, Scrollable {
 
     public static final int HEIGHT = 40;
-    public static final int BAR_HEIGHT = 22;
-    public static final int BAR_SELECTION_ENDING_HEIGHT = 16;
-    public static final int BAR_SELECTION_HEIGHT = 10;
-    public static final int BAR_THICKNESS = 2;
-    public static final int BAR_CIRCLE_SIZE = 9;
+    public static final float BAR_HEIGHT = 22;
+    public static final float BAR_SELECTION_ENDING_HEIGHT = 16;
+    public static final float BAR_SELECTION_HEIGHT = 10;
+    public static final float BAR_THICKNESS = 2;
+    public static final float BAR_CIRCLE_SIZE = 9;
+    public static final float BAR_CIRCLE_CONNECTOR_SIZE = 6;
     public static final int MOUSE_ENDING_OFFSET = 3;
     public static final Color BACKGROUND_COLOR = Color.white;
     public static final Color BAR_COLOR = Color.black;
@@ -98,14 +92,61 @@
         return model;
     }
 
+    /**
+     * Returns the preferred size of the viewport for a view component.
+     * For example, the preferred size of a <code>JList</code> component
+     * is the size required to accommodate all of the cells in its list.
+     * However, the value of <code>preferredScrollableViewportSize</code>
+     * is the size required for <code>JList.getVisibleRowCount</code> rows.
+     * A component without any properties that would affect the viewport
+     * size should just return <code>getPreferredSize</code> here.
+     *
+     * @return the preferredSize of a <code>JViewport</code> whose view
+     *    is this <code>Scrollable</code>
+     * @see JViewport#getPreferredSize
+     */
+    public Dimension getPreferredScrollableViewportSize() {
+        return getPreferredSize();
+    }
+
+    public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
+        if (orientation == SwingConstants.VERTICAL) {
+            return 1;
+        }
+
+        return (int)(BAR_CIRCLE_SIZE + BAR_CIRCLE_CONNECTOR_SIZE);
+    }
+
+    public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
+        return orientation == SwingConstants.VERTICAL ? visibleRect.height / 2 : visibleRect.width / 2;
+    }
+
+    public boolean getScrollableTracksViewportWidth() {
+        return false;
+    }
+
+    public boolean getScrollableTracksViewportHeight() {
+        return true;
+    }
+
     @Override
     public Dimension getPreferredSize() {
         Dimension d = super.getPreferredSize();
         d.height = HEIGHT;
+        d.width = Math.max(d.width, (int)(2 * BAR_CIRCLE_CONNECTOR_SIZE + getPaintingModel().getPositions().size() * (BAR_CIRCLE_SIZE + BAR_CIRCLE_CONNECTOR_SIZE)));
         return d;
     }
 
+    @Override
     public void changed(RangeSliderModel source) {
+        revalidate();
+
+        float barStartY = getBarStartY();
+        int circleCenterY = (int)(barStartY + BAR_HEIGHT / 2);
+        int startX = (int)getStartXPosition(model.getFirstPosition());
+        int endX = (int)getEndXPosition(model.getSecondPosition());
+        Rectangle r = new Rectangle(startX, circleCenterY, endX - startX, 1);
+        scrollRectToVisible(r);
         update();
     }
 
@@ -113,22 +154,22 @@
         this.repaint();
     }
 
-    private int getXPosition(int index) {
+    private float getXPosition(int index) {
         assert index >= 0 && index < getPaintingModel().getPositions().size();
         return getXOffset() * (index + 1);
     }
 
-    private int getXOffset() {
+    private float getXOffset() {
         int size = getPaintingModel().getPositions().size();
-        int width = getWidth();
+        float width = (float)getWidth();
         return (width / (size + 1));
     }
 
-    private int getEndXPosition(int index) {
+    private float getEndXPosition(int index) {
         return getXPosition(index) + getXOffset() / 2;
     }
 
-    private int getStartXPosition(int index) {
+    private float getStartXPosition(int index) {
         return getXPosition(index) - getXOffset() / 2;
     }
 
@@ -142,7 +183,7 @@
         int height = getHeight();
 
         g2.setColor(BACKGROUND_COLOR);
-        g2.fillRect(0, 0, width, height);
+        g2.fill(new Rectangle2D.Float(0, 0, width, height));
 
         // Nothing to paint?
         if (getPaintingModel() == null || getPaintingModel().getPositions().size() == 0) {
@@ -157,30 +198,30 @@
 
     }
 
-    private int getBarStartY() {
-        return getHeight() - BAR_HEIGHT;
+    private float getBarStartY() {
+        return getHeight() / 2 - BAR_HEIGHT / 2;
     }
 
     private void paintBar(Graphics2D g) {
         List<String> list = getPaintingModel().getPositions();
-        int barStartY = getBarStartY();
+        float barStartY = getBarStartY();
 
         g.setColor(BAR_COLOR);
-        g.fillRect(getXPosition(0), barStartY + BAR_HEIGHT / 2 - BAR_THICKNESS / 2, getXPosition(list.size() - 1) - getXPosition(0), BAR_THICKNESS);
+        g.fill(new Rectangle2D.Float(getXPosition(0), barStartY + BAR_HEIGHT / 2 - BAR_THICKNESS / 2, getXPosition(list.size() - 1) - getXPosition(0), BAR_THICKNESS));
 
-        int circleCenterY = barStartY + BAR_HEIGHT / 2;
+        float circleCenterY = barStartY + BAR_HEIGHT / 2;
         for (int i = 0; i < list.size(); i++) {
-            int curX = getXPosition(i);
+            float curX = getXPosition(i);
             g.setColor(getPaintingModel().getColors().get(i));
-            g.fillOval(curX - BAR_CIRCLE_SIZE / 2, circleCenterY - BAR_CIRCLE_SIZE / 2, BAR_CIRCLE_SIZE, BAR_CIRCLE_SIZE);
+            g.fill(new Ellipse2D.Float(curX - BAR_CIRCLE_SIZE / 2, circleCenterY - BAR_CIRCLE_SIZE / 2, BAR_CIRCLE_SIZE, BAR_CIRCLE_SIZE));
             g.setColor(Color.black);
-            g.drawOval(curX - BAR_CIRCLE_SIZE / 2, circleCenterY - BAR_CIRCLE_SIZE / 2, BAR_CIRCLE_SIZE, BAR_CIRCLE_SIZE);
+            g.draw(new Ellipse2D.Float(curX - BAR_CIRCLE_SIZE / 2, circleCenterY - BAR_CIRCLE_SIZE / 2, BAR_CIRCLE_SIZE, BAR_CIRCLE_SIZE));
 
 
             String curS = list.get(i);
             if (curS != null && curS.length() > 0) {
-                int startX = getStartXPosition(i);
-                int endX = getEndXPosition(i);
+                float startX = getStartXPosition(i);
+                float endX = getEndXPosition(i);
                 FontMetrics metrics = g.getFontMetrics();
                 Rectangle bounds = metrics.getStringBounds(curS, g).getBounds();
                 if (bounds.width < endX - startX && bounds.height < barStartY) {
@@ -194,10 +235,10 @@
 
     private void paintSelected(Graphics2D g, int start, int end) {
 
-        int startX = getStartXPosition(start);
-        int endX = getEndXPosition(end);
-        int barStartY = getBarStartY();
-        int barSelectionEndingStartY = barStartY + BAR_HEIGHT / 2 - BAR_SELECTION_ENDING_HEIGHT / 2;
+        float startX = getStartXPosition(start);
+        float endX = getEndXPosition(end);
+        float barStartY = getBarStartY();
+        float barSelectionEndingStartY = barStartY + BAR_HEIGHT / 2 - BAR_SELECTION_ENDING_HEIGHT / 2;
         paintSelectedEnding(g, startX, barSelectionEndingStartY);
         paintSelectedEnding(g, endX, barSelectionEndingStartY);
 
@@ -207,18 +248,18 @@
         } else if (isOverBar) {
             g.setColor(BAR_SELECTION_COLOR_ROLLOVER);
         }
-        g.fillRect(startX, barStartY + BAR_HEIGHT / 2 - BAR_SELECTION_HEIGHT / 2, endX - startX, BAR_SELECTION_HEIGHT);
+        g.fill(new Rectangle2D.Float(startX, barStartY + BAR_HEIGHT / 2 - BAR_SELECTION_HEIGHT / 2, endX - startX, BAR_SELECTION_HEIGHT));
     }
 
-    private void paintSelectedEnding(Graphics g, int x, int y) {
+    private void paintSelectedEnding(Graphics2D g, float x, float y) {
         g.setColor(BAR_COLOR);
-        g.fillRect(x - BAR_THICKNESS / 2, y, BAR_THICKNESS, BAR_SELECTION_ENDING_HEIGHT);
+        g.fill(new Rectangle2D.Float(x - BAR_THICKNESS / 2, y, BAR_THICKNESS, BAR_SELECTION_ENDING_HEIGHT));
     }
 
     private boolean isOverSecondPosition(Point p) {
         if (p.y >= getBarStartY()) {
-            int destX = getEndXPosition(getPaintingModel().getSecondPosition());
-            int off = Math.abs(destX - p.x);
+            float destX = getEndXPosition(getPaintingModel().getSecondPosition());
+            float off = Math.abs(destX - p.x);
             return off <= MOUSE_ENDING_OFFSET;
         }
         return false;
@@ -226,8 +267,8 @@
 
     private boolean isOverFirstPosition(Point p) {
         if (p.y >= getBarStartY()) {
-            int destX = getStartXPosition(getPaintingModel().getFirstPosition());
-            int off = Math.abs(destX - p.x);
+            float destX = getStartXPosition(getPaintingModel().getFirstPosition());
+            float off = Math.abs(destX - p.x);
             return off <= MOUSE_ENDING_OFFSET;
         }
         return false;
@@ -240,10 +281,14 @@
         return false;
     }
 
+    @Override
     public void mouseDragged(MouseEvent e) {
+        Rectangle r = new Rectangle(e.getX(), e.getY(), 1, 1);
+        scrollRectToVisible(r);
+
         if (state == State.DragBar) {
-            int firstX = this.getStartXPosition(model.getFirstPosition());
-            int newFirstX = firstX + e.getPoint().x - startPoint.x;
+            float firstX = this.getStartXPosition(model.getFirstPosition());
+            float newFirstX = firstX + e.getPoint().x - startPoint.x;
             int newIndex = getIndexFromPosition(newFirstX) + 1;
             if (newIndex + model.getSecondPosition() - model.getFirstPosition() >= model.getPositions().size()) {
                 newIndex = model.getPositions().size() - (model.getSecondPosition() - model.getFirstPosition()) - 1;
@@ -270,13 +315,13 @@
         }
     }
 
-    private int getIndexFromPosition(int x) {
+    private int getIndexFromPosition(float x) {
         if (x < getXPosition(0)) {
             return -1;
         }
         for (int i = 0; i < getPaintingModel().getPositions().size() - 1; i++) {
-            int startX = getXPosition(i);
-            int endX = getXPosition(i + 1);
+            float startX = getXPosition(i);
+            float endX = getXPosition(i + 1);
             if (x >= startX && x <= endX) {
                 return i;
             }
@@ -286,7 +331,7 @@
 
     private int getCircleIndexFromPosition(int x) {
         int result = 0;
-        for (int i = 1; i < getPaintingModel().getPositions().size() - 1; i++) {
+        for (int i = 1; i < getPaintingModel().getPositions().size(); i++) {
             if (x > getStartXPosition(i)) {
                 result = i;
             }
@@ -294,6 +339,7 @@
         return result;
     }
 
+    @Override
     public void mouseMoved(MouseEvent e) {
         isOverBar = false;
         if (model == null) {
@@ -313,6 +359,7 @@
         repaint();
     }
 
+    @Override
     public void mouseClicked(MouseEvent e) {
         if (e.getClickCount() > 1) {
             // Double click
@@ -321,6 +368,7 @@
         }
     }
 
+    @Override
     public void mousePressed(MouseEvent e) {
         if (model == null) {
             return;
@@ -341,6 +389,7 @@
         tempModel = model.copy();
     }
 
+    @Override
     public void mouseReleased(MouseEvent e) {
         if (model == null || tempModel == null) {
             return;
@@ -350,9 +399,11 @@
         tempModel = null;
     }
 
+    @Override
     public void mouseEntered(MouseEvent e) {
     }
 
+    @Override
     public void mouseExited(MouseEvent e) {
         isOverBar = false;
         repaint();
--- a/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,8 +24,8 @@
  */
 package com.sun.hotspot.igv.util;
 
+import com.sun.hotspot.igv.data.ChangedEvent;
 import com.sun.hotspot.igv.data.ChangedEventProvider;
-import com.sun.hotspot.igv.data.ChangedEvent;
 import java.awt.Color;
 import java.util.ArrayList;
 import java.util.Collections;
@@ -65,17 +65,19 @@
 
     public RangeSliderModel(List<String> positions) {
         assert positions.size() > 0;
-        this.changedEvent = new ChangedEvent<RangeSliderModel>(this);
-        this.colorChangedEvent = new ChangedEvent<RangeSliderModel>(this);
+        this.changedEvent = new ChangedEvent<>(this);
+        this.colorChangedEvent = new ChangedEvent<>(this);
         setPositions(positions);
     }
 
     protected void setPositions(List<String> positions) {
         this.positions = positions;
-        colors = new ArrayList<Color>();
+        colors = new ArrayList<>();
         for (int i = 0; i < positions.size(); i++) {
             colors.add(Color.black);
         }
+        firstPosition = Math.min(firstPosition, positions.size() - 1);
+        secondPosition = Math.min(secondPosition, positions.size() - 1);
         changedEvent.fire();
         colorChangedEvent.fire();
     }
@@ -91,9 +93,7 @@
 
     public RangeSliderModel copy() {
         RangeSliderModel newModel = new RangeSliderModel(positions);
-        newModel.firstPosition = firstPosition;
-        newModel.secondPosition = secondPosition;
-        newModel.colors = colors;
+        newModel.setData(this);
         return newModel;
     }
 
@@ -130,6 +130,7 @@
         return colorChangedEvent;
     }
 
+    @Override
     public ChangedEvent<RangeSliderModel> getChangedEvent() {
         return changedEvent;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-javac.source=1.5
-javac.compilerargs=-Xlint -Xlint:-serial
+javac.source=1.7
+javac.compilerargs=-Xlint -Xlint:-serial
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/project.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/project.xml	Tue May 05 19:27:08 2015 +0200
@@ -55,6 +55,14 @@
                     </run-dependency>
                 </dependency>
                 <dependency>
+                    <code-name-base>com.sun.hotspot.igv.selectioncoordinator</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
                     <code-name-base>com.sun.hotspot.igv.settings</code-name-base>
                     <build-prerequisite/>
                     <compile-dependency/>
@@ -83,7 +91,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>2.9</specification-version>
+                        <specification-version>2.27.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.spi.quicksearch</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -91,7 +107,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.6.0.1</specification-version>
+                        <specification-version>6.21.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -99,7 +115,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.11.0.1</specification-version>
+                        <specification-version>7.30.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -107,7 +123,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.5.1</specification-version>
+                        <specification-version>7.18.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -115,7 +131,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.7</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -123,7 +139,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.2.1.1</specification-version>
+                        <specification-version>7.20.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -131,7 +147,15 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>7.9.0.1</specification-version>
+                        <specification-version>8.14.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.6.1</specification-version>
                     </run-dependency>
                 </dependency>
                 <dependency>
@@ -139,7 +163,7 @@
                     <build-prerequisite/>
                     <compile-dependency/>
                     <run-dependency>
-                        <specification-version>6.16</specification-version>
+                        <specification-version>6.39.1</specification-version>
                     </run-dependency>
                 </dependency>
             </module-dependencies>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/META-INF/services/com.sun.hotspot.igv.data.services.InputGraphProvider	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-com.sun.hotspot.igv.view.EditorInputGraphProvider
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/BoundedZoomAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/BoundedZoomAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/Bundle.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/Bundle.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,3 +1,3 @@
-HINT_EditorTopComponent=This is a Editor window
-OpenIDE-Module-Name=View
-CTL_EditorTopComponent=Editor Window
+HINT_EditorTopComponent=Visualizes a graph.
+OpenIDE-Module-Name=View
+CTL_EditorTopComponent=Graph
\ No newline at end of file
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ConnectionAnchor.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view;
-
-import com.sun.hotspot.igv.view.widgets.SlotWidget;
-import java.awt.Point;
-import java.awt.Rectangle;
-import org.netbeans.api.visual.anchor.Anchor;
-import org.netbeans.api.visual.anchor.Anchor.Entry;
-import org.netbeans.api.visual.anchor.Anchor.Result;
-import org.netbeans.api.visual.widget.Widget;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class ConnectionAnchor extends Anchor {
-
-    public enum HorizontalAlignment {
-
-        Left,
-        Center,
-        Right
-    }
-    private HorizontalAlignment alignment;
-
-    public ConnectionAnchor(Widget widget) {
-        this(HorizontalAlignment.Center, widget);
-    }
-
-    public ConnectionAnchor(HorizontalAlignment alignment, Widget widget) {
-        super(widget);
-        this.alignment = alignment;
-    }
-
-    public Result compute(Entry entry) {
-        return new Result(getRelatedSceneLocation(), Anchor.DIRECTION_ANY);
-    }
-
-    @Override
-    public Point getRelatedSceneLocation() {
-        Point p = null;
-        Widget w = getRelatedWidget();
-        if (w != null) {
-            if (w instanceof SlotWidget) {
-                p = ((SlotWidget) w).getAnchorPosition();
-            } else {
-                Rectangle r = w.convertLocalToScene(w.getBounds());
-                int y = r.y + r.height / 2;
-                int x = r.x;
-                if (alignment == HorizontalAlignment.Center) {
-                    x = r.x + r.width / 2;
-                } else if (alignment == HorizontalAlignment.Right) {
-                    x = r.x + r.width;
-                }
-
-                p = new Point(x, y);
-            }
-        }
-
-        return p;
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,77 +23,42 @@
  */
 package com.sun.hotspot.igv.view;
 
-import com.sun.hotspot.igv.view.widgets.BlockWidget;
-import com.sun.hotspot.igv.view.widgets.LineWidget;
-import com.sun.hotspot.igv.util.DoubleClickAction;
+import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.data.ControllableChangedListener;
 import com.sun.hotspot.igv.data.InputBlock;
 import com.sun.hotspot.igv.data.InputNode;
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.graph.InputSlot;
-import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Slot;
+import com.sun.hotspot.igv.data.Pair;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.services.Scheduler;
+import com.sun.hotspot.igv.graph.*;
 import com.sun.hotspot.igv.hierarchicallayout.HierarchicalClusterLayoutManager;
-import com.sun.hotspot.igv.hierarchicallayout.OldHierarchicalLayoutManager;
 import com.sun.hotspot.igv.hierarchicallayout.HierarchicalLayoutManager;
-import com.sun.hotspot.igv.view.widgets.FigureWidget;
-import com.sun.hotspot.igv.view.widgets.InputSlotWidget;
-import com.sun.hotspot.igv.view.widgets.OutputSlotWidget;
-import com.sun.hotspot.igv.view.widgets.SlotWidget;
 import com.sun.hotspot.igv.layout.LayoutGraph;
-import com.sun.hotspot.igv.data.services.Scheduler;
-import com.sun.hotspot.igv.data.ChangedListener;
-import com.sun.hotspot.igv.graph.Block;
+import com.sun.hotspot.igv.selectioncoordinator.SelectionCoordinator;
 import com.sun.hotspot.igv.util.ColorIcon;
-import com.sun.hotspot.igv.util.ExtendedSelectAction;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.event.ActionEvent;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
-import java.awt.event.MouseEvent;
-import java.awt.event.MouseListener;
-import java.awt.event.MouseMotionListener;
-import java.awt.event.MouseWheelEvent;
-import java.awt.event.MouseWheelListener;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.HashMap;
+import com.sun.hotspot.igv.util.DoubleClickAction;
+import com.sun.hotspot.igv.util.PropertiesSheet;
+import com.sun.hotspot.igv.view.actions.CustomizablePanAction;
+import com.sun.hotspot.igv.view.widgets.*;
+import java.awt.*;
+import java.awt.event.*;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import javax.swing.AbstractAction;
-import javax.swing.Action;
-import javax.swing.BorderFactory;
-import javax.swing.JComponent;
-import javax.swing.JPopupMenu;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
+import java.util.*;
+import javax.swing.*;
 import javax.swing.event.UndoableEditEvent;
 import javax.swing.undo.AbstractUndoableEdit;
 import javax.swing.undo.CannotRedoException;
 import javax.swing.undo.CannotUndoException;
-import org.netbeans.api.visual.action.ActionFactory;
-import org.netbeans.api.visual.action.PopupMenuProvider;
-import org.netbeans.api.visual.action.RectangularSelectDecorator;
-import org.netbeans.api.visual.action.RectangularSelectProvider;
-import org.netbeans.api.visual.action.SelectProvider;
-import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.action.*;
 import org.netbeans.api.visual.animator.SceneAnimator;
 import org.netbeans.api.visual.layout.LayoutFactory;
-import org.netbeans.api.visual.widget.ConnectionWidget;
+import org.netbeans.api.visual.model.*;
 import org.netbeans.api.visual.widget.LayerWidget;
-import org.netbeans.api.visual.widget.Scene;
 import org.netbeans.api.visual.widget.Widget;
-import org.netbeans.api.visual.widget.LabelWidget;
 import org.openide.awt.UndoRedo;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Sheet;
 import org.openide.util.Lookup;
 import org.openide.util.lookup.AbstractLookup;
 import org.openide.util.lookup.InstanceContent;
@@ -102,54 +67,58 @@
  *
  * @author Thomas Wuerthinger
  */
-public class DiagramScene extends Scene implements ChangedListener<DiagramViewModel> {
+public class DiagramScene extends ObjectScene implements DiagramViewer {
 
-    private HashMap<Figure, FigureWidget> figureWidgets;
-    private HashMap<Slot, SlotWidget> slotWidgets;
-    private HashMap<Connection, ConnectionWidget> connectionWidgets;
-    private HashMap<InputBlock, BlockWidget> blockWidgets;
-    private Widget hoverWidget;
+    private CustomizablePanAction panAction;
     private WidgetAction hoverAction;
-    private List<FigureWidget> selectedWidgets;
+    private WidgetAction selectAction;
     private Lookup lookup;
     private InstanceContent content;
     private Action[] actions;
+    private Action[] actionsWithSelection;
     private LayerWidget connectionLayer;
     private JScrollPane scrollPane;
     private UndoRedo.Manager undoRedoManager;
     private LayerWidget mainLayer;
-    private LayerWidget slotLayer;
     private LayerWidget blockLayer;
-    private double realZoomFactor;
-    private BoundedZoomAction zoomAction;
-    private WidgetAction panAction;
     private Widget topLeft;
     private Widget bottomRight;
-    private LayerWidget startLayer;
-    private LabelWidget startLabel;
     private DiagramViewModel model;
     private DiagramViewModel modelCopy;
-    public static final int AFTER = 1;
-    public static final int BEFORE = 1;
+    private WidgetAction zoomAction;
+    private boolean rebuilding;
+
+    /**
+     * The alpha level of partially visible figures.
+     */
     public static final float ALPHA = 0.4f;
-    public static final int GRID_SIZE = 30;
+
+    /**
+     * The offset of the graph to the border of the window showing it.
+     */
     public static final int BORDER_SIZE = 20;
+
+
     public static final int UNDOREDO_LIMIT = 100;
     public static final int SCROLL_UNIT_INCREMENT = 80;
     public static final int SCROLL_BLOCK_INCREMENT = 400;
     public static final float ZOOM_MAX_FACTOR = 3.0f;
     public static final float ZOOM_MIN_FACTOR = 0.0f;//0.15f;
     public static final float ZOOM_INCREMENT = 1.5f;
-    public static final int SLOT_OFFSET = 6;
+    public static final int SLOT_OFFSET = 8;
     public static final int ANIMATION_LIMIT = 40;
+
     private PopupMenuProvider popupMenuProvider = new PopupMenuProvider() {
 
+        @Override
         public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
             return DiagramScene.this.createPopupMenu();
         }
     };
+
     private RectangularSelectDecorator rectangularSelectDecorator = new RectangularSelectDecorator() {
 
+        @Override
         public Widget createSelectionWidget() {
             Widget widget = new Widget(DiagramScene.this);
             widget.setBorder(BorderFactory.createLineBorder(Color.black, 2));
@@ -157,8 +126,98 @@
             return widget;
         }
     };
+
+    @SuppressWarnings("unchecked")
+    public <T> T getWidget(Object o) {
+        Widget w = this.findWidget(o);
+        return (T) w;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <T> T getWidget(Object o, Class<T> klass) {
+        Widget w = this.findWidget(o);
+        return (T) w;
+    }
+
+    private static boolean intersects(Set<? extends Object> s1, Set<? extends Object> s2) {
+        for (Object o : s1) {
+            if (s2.contains(o)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    public void zoomOut() {
+        double zoom = getZoomFactor();
+        Point viewPosition = getScrollPane().getViewport().getViewPosition();
+        double newZoom = zoom / DiagramScene.ZOOM_INCREMENT;
+        if (newZoom > DiagramScene.ZOOM_MIN_FACTOR) {
+            setZoomFactor(newZoom);
+            validate();
+            getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x / DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y / DiagramScene.ZOOM_INCREMENT)));
+        }
+    }
+
+    @Override
+    public void zoomIn() {
+
+        double zoom = getZoomFactor();
+        Point viewPosition = getScrollPane().getViewport().getViewPosition();
+        double newZoom = zoom * DiagramScene.ZOOM_INCREMENT;
+        if (newZoom < DiagramScene.ZOOM_MAX_FACTOR) {
+            setZoomFactor(newZoom);
+            validate();
+            getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x * DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y * DiagramScene.ZOOM_INCREMENT)));
+        }
+    }
+
+
+    @Override
+    public void centerFigures(List<Figure> list) {
+
+        boolean b = getUndoRedoEnabled();
+        setUndoRedoEnabled(false);
+        gotoFigures(list);
+        setUndoRedoEnabled(b);
+    }
+
+    private Set<Object> getObjectsFromIdSet(Set<Object> set) {
+        Set<Object> selectedObjects = new HashSet<>();
+        for (Figure f : getModel().getDiagramToView().getFigures()) {
+            if (intersects(f.getSource().getSourceNodesAsSet(), set)) {
+                selectedObjects.add(f);
+            }
+
+            for (Slot s : f.getSlots()) {
+                if (intersects(s.getSource().getSourceNodesAsSet(), set)) {
+                    selectedObjects.add(s);
+                }
+            }
+        }
+        return selectedObjects;
+    }
+    private ControllableChangedListener<SelectionCoordinator> highlightedCoordinatorListener = new ControllableChangedListener<SelectionCoordinator>() {
+
+        @Override
+        public void filteredChanged(SelectionCoordinator source) {
+            DiagramScene.this.setHighlightedObjects(getObjectsFromIdSet(source.getHighlightedObjects()));
+            DiagramScene.this.validate();
+        }
+    };
+    private ControllableChangedListener<SelectionCoordinator> selectedCoordinatorListener = new ControllableChangedListener<SelectionCoordinator>() {
+
+        @Override
+        public void filteredChanged(SelectionCoordinator source) {
+            DiagramScene.this.gotoSelection(source.getSelectedObjects());
+            DiagramScene.this.validate();
+        }
+    };
+
     private RectangularSelectProvider rectangularSelectProvider = new RectangularSelectProvider() {
 
+        @Override
         public void performSelection(Rectangle rectangle) {
             if (rectangle.width < 0) {
                 rectangle.x += rectangle.width;
@@ -170,168 +229,44 @@
                 rectangle.height *= -1;
             }
 
-            boolean updated = false;
+            Set<Object> selectedObjects = new HashSet<>();
             for (Figure f : getModel().getDiagramToView().getFigures()) {
-                FigureWidget w = figureWidgets.get(f);
-                Rectangle r = new Rectangle(w.getBounds());
-                r.setLocation(w.getLocation());
-                if (r.intersects(rectangle)) {
-                    if (!selectedWidgets.contains(w)) {
-                        addToSelection(w);
-                        updated = true;
+                FigureWidget w = getWidget(f);
+                if (w != null) {
+                    Rectangle r = new Rectangle(w.getBounds());
+                    r.setLocation(w.getLocation());
+
+                    if (r.intersects(rectangle)) {
+                        selectedObjects.add(f);
+                    }
+
+                    for (Slot s : f.getSlots()) {
+                        SlotWidget sw = getWidget(s);
+                        Rectangle r2 = new Rectangle(sw.getBounds());
+                        r2.setLocation(sw.convertLocalToScene(new Point(0, 0)));
+
+                        if (r2.intersects(rectangle)) {
+                            selectedObjects.add(s);
+                        }
                     }
                 } else {
-                    if (selectedWidgets.contains(w)) {
-                        selectedWidgets.remove(w);
-                        content.remove(w.getNode());
-                        w.setState(w.getState().deriveSelected(false));
-                        updated = true;
-                    }
-                }
-            }
-
-            if (updated) {
-                selectionUpdated();
-            }
-        }
-    };
-    private SelectProvider selectProvider = new SelectProvider() {
-
-        public boolean isAimingAllowed(Widget widget, Point point, boolean b) {
-            return false;
-        }
-
-        public boolean isSelectionAllowed(Widget widget, Point point, boolean b) {
-            return widget instanceof FigureWidget || widget == DiagramScene.this;
-        }
-
-        public void select(Widget w, Point point, boolean change) {
-
-            boolean updated = false;
-
-            if (w == DiagramScene.this) {
-                if (DiagramScene.this.selectedWidgets.size() != 0) {
-                    clearSelection();
-                    selectionUpdated();
-                }
-                return;
-            }
-
-            FigureWidget widget = (FigureWidget) w;
-
-
-            if (change) {
-                if (widget.getState().isSelected()) {
-                    assert selectedWidgets.contains(widget);
-                    widget.setState(widget.getState().deriveSelected(false));
-                    selectedWidgets.remove(widget);
-                    content.remove(widget.getNode());
-                    updated = true;
-                } else {
-                    assert !selectedWidgets.contains(widget);
-                    addToSelection(widget);
-                    updated = true;
-                    assert widget.getState().isSelected();
-                }
-            } else {
-
-                if (widget.getState().isSelected()) {
-                    assert selectedWidgets.contains(widget);
-                } else {
-
-                    assert !selectedWidgets.contains(widget);
-                    clearSelection();
-                    addToSelection(widget);
-                    updated = true;
-                    assert widget.getState().isSelected();
+                    assert false : "w should not be null here!";
                 }
             }
 
-            if (updated) {
-                selectionUpdated();
-            }
-
+            setSelectedObjects(selectedObjects);
         }
     };
 
-    private FigureWidget getFigureWidget(Figure f) {
-        return figureWidgets.get(f);
-    }
-    private FocusListener focusListener = new FocusListener() {
-
-        public void focusGained(FocusEvent e) {
-            DiagramScene.this.getView().requestFocus();
-        }
-
-        public void focusLost(FocusEvent e) {
-        }
-    };
     private MouseWheelListener mouseWheelListener = new MouseWheelListener() {
 
+        @Override
         public void mouseWheelMoved(MouseWheelEvent e) {
-            DiagramScene.this.zoomAction.mouseWheelMoved(DiagramScene.this, new WidgetAction.WidgetMouseWheelEvent(0, e));
-            DiagramScene.this.validate();
+            if (e.isControlDown()) {
+                DiagramScene.this.relayoutWithoutLayout(null);
+            }
         }
     };
-    private MouseListener mouseListener = new MouseListener() {
-
-        public void mouseClicked(MouseEvent e) {
-            DiagramScene.this.panAction.mouseClicked(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mousePressed(MouseEvent e) {
-            DiagramScene.this.panAction.mousePressed(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mouseReleased(MouseEvent e) {
-            DiagramScene.this.panAction.mouseReleased(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mouseEntered(MouseEvent e) {
-            DiagramScene.this.panAction.mouseEntered(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mouseExited(MouseEvent e) {
-            DiagramScene.this.panAction.mouseExited(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-    };
-    private MouseMotionListener mouseMotionListener = new MouseMotionListener() {
-
-        public void mouseDragged(MouseEvent e) {
-            DiagramScene.this.panAction.mouseDragged(DiagramScene.this, new WidgetAction.WidgetMouseEvent(0, e));
-        }
-
-        public void mouseMoved(MouseEvent e) {
-        }
-    };
-    private ScrollChangeListener scrollChangeListener = new ScrollChangeListener();
-
-    private class ScrollChangeListener implements ChangeListener {
-
-        private Map<Widget, Point> relativePositions = new HashMap<Widget, Point>();
-        private Point oldPosition;
-
-        public void register(Widget w, Point p) {
-            relativePositions.put(w, p);
-        }
-
-        public void unregister(Widget w) {
-            relativePositions.remove(w);
-        }
-
-        public void stateChanged(ChangeEvent e) {
-            Point p = DiagramScene.this.getScrollPane().getViewport().getViewPosition();
-            if (oldPosition == null || !p.equals(oldPosition)) {
-                for (Widget w : relativePositions.keySet()) {
-                    Point curPoint = relativePositions.get(w);
-                    Point newPoint = new Point(p.x + curPoint.x, p.y + curPoint.y);
-                    w.setPreferredLocation(newPoint);
-                    DiagramScene.this.validate();
-                }
-                oldPosition = p;
-            }
-        }
-    }
 
     public Point getScrollPosition() {
         return getScrollPane().getViewport().getViewPosition();
@@ -341,42 +276,138 @@
         getScrollPane().getViewport().setViewPosition(p);
     }
 
-    public DiagramScene(Action[] actions, DiagramViewModel model) {
-        this.actions = actions;
-        selectedWidgets = new ArrayList<FigureWidget>();
-        content = new InstanceContent();
-        lookup = new AbstractLookup(content);
-        this.setCheckClipping(true);
-        this.getInputBindings().setZoomActionModifiers(0);
-
+    private JScrollPane createScrollPane() {
         JComponent comp = this.createView();
         comp.setDoubleBuffered(true);
         comp.setBackground(Color.WHITE);
         comp.setOpaque(true);
-
         this.setBackground(Color.WHITE);
         this.setOpaque(true);
-        scrollPane = new JScrollPane(comp);
-        scrollPane.setBackground(Color.WHITE);
-        scrollPane.getVerticalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
-        scrollPane.getVerticalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
-        scrollPane.getHorizontalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
-        scrollPane.getHorizontalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
-        scrollPane.getViewport().addChangeListener(scrollChangeListener);
-        hoverAction = this.createWidgetHoverAction();
+        JScrollPane result = new JScrollPane(comp);
+        result.setBackground(Color.WHITE);
+        result.getVerticalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
+        result.getVerticalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
+        result.getHorizontalScrollBar().setUnitIncrement(SCROLL_UNIT_INCREMENT);
+        result.getHorizontalScrollBar().setBlockIncrement(SCROLL_BLOCK_INCREMENT);
+        return result;
+    }
+    private ObjectSceneListener selectionChangedListener = new ObjectSceneListener() {
+
+        @Override
+        public void objectAdded(ObjectSceneEvent arg0, Object arg1) {
+        }
+
+        @Override
+        public void objectRemoved(ObjectSceneEvent arg0, Object arg1) {
+        }
+
+        @Override
+        public void objectStateChanged(ObjectSceneEvent e, Object o, ObjectState oldState, ObjectState newState) {
+        }
+
+        @Override
+        public void selectionChanged(ObjectSceneEvent e, Set<Object> oldSet, Set<Object> newSet) {
+            DiagramScene scene = (DiagramScene) e.getObjectScene();
+            if (scene.isRebuilding()) {
+                return;
+            }
+
+            content.set(newSet, null);
+
+            Set<Integer> nodeSelection = new HashSet<>();
+            for (Object o : newSet) {
+                if (o instanceof Properties.Provider) {
+                    final Properties.Provider provider = (Properties.Provider) o;
+                    AbstractNode node = new AbstractNode(Children.LEAF) {
+
+                        @Override
+                        protected Sheet createSheet() {
+                            Sheet s = super.createSheet();
+                            PropertiesSheet.initializeSheet(provider.getProperties(), s);
+                            return s;
+                        }
+                    };
+                    node.setDisplayName(provider.getProperties().get("name"));
+                    content.add(node);
+                }
+
+
+                if (o instanceof Figure) {
+                    nodeSelection.addAll(((Figure) o).getSource().getSourceNodesAsSet());
+                } else if (o instanceof Slot) {
+                    nodeSelection.addAll(((Slot) o).getSource().getSourceNodesAsSet());
+                }
+            }
+            getModel().setSelectedNodes(nodeSelection);
+
+            boolean b = selectedCoordinatorListener.isEnabled();
+            selectedCoordinatorListener.setEnabled(false);
+            SelectionCoordinator.getInstance().setSelectedObjects(nodeSelection);
+            selectedCoordinatorListener.setEnabled(b);
+
+        }
+
+        @Override
+        public void highlightingChanged(ObjectSceneEvent e, Set<Object> oldSet, Set<Object> newSet) {
+            Set<Integer> nodeHighlighting = new HashSet<>();
+            for (Object o : newSet) {
+                if (o instanceof Figure) {
+                    nodeHighlighting.addAll(((Figure) o).getSource().getSourceNodesAsSet());
+                } else if (o instanceof Slot) {
+                    nodeHighlighting.addAll(((Slot) o).getSource().getSourceNodesAsSet());
+                }
+            }
+            boolean b = highlightedCoordinatorListener.isEnabled();
+            highlightedCoordinatorListener.setEnabled(false);
+            SelectionCoordinator.getInstance().setHighlightedObjects(nodeHighlighting);
+            highlightedCoordinatorListener.setEnabled(true);
+        }
+
+        @Override
+        public void hoverChanged(ObjectSceneEvent e, Object oldObject, Object newObject) {
+            Set<Object> newHighlightedObjects = new HashSet<>(DiagramScene.this.getHighlightedObjects());
+            if (oldObject != null) {
+                newHighlightedObjects.remove(oldObject);
+            }
+            if (newObject != null) {
+                newHighlightedObjects.add(newObject);
+            }
+            DiagramScene.this.setHighlightedObjects(newHighlightedObjects);
+        }
+
+        @Override
+        public void focusChanged(ObjectSceneEvent arg0, Object arg1, Object arg2) {
+        }
+    };
+
+    public DiagramScene(Action[] actions, Action[] actionsWithSelection, DiagramViewModel model) {
+
+        this.actions = actions;
+        this.actionsWithSelection = actionsWithSelection;
+
+        content = new InstanceContent();
+        lookup = new AbstractLookup(content);
+
+        this.setCheckClipping(true);
+
+        scrollPane = createScrollPane();
+
+        hoverAction = createObjectHoverAction();
+
+        // This panAction handles the event only when the left mouse button is
+        // pressed without any modifier keys, otherwise it will not consume it
+        // and the selection action (below) will handle the event
+        panAction = new CustomizablePanAction(~0, MouseEvent.BUTTON1_DOWN_MASK);
+        this.getActions().addAction(panAction);
+
+        selectAction = createSelectAction();
+        this.getActions().addAction(selectAction);
 
         blockLayer = new LayerWidget(this);
         this.addChild(blockLayer);
 
-        startLayer = new LayerWidget(this);
-        this.addChild(startLayer);
-        // TODO: String startLabelString = "Loading graph with " + originalDiagram.getFigures().size() + " figures and " + originalDiagram.getConnections().size() + " connections...";
-        String startLabelString = "";
-        LabelWidget w = new LabelWidget(this, startLabelString);
-        scrollChangeListener.register(w, new Point(10, 10));
-        w.setAlignment(LabelWidget.Alignment.CENTER);
-        startLabel = w;
-        startLayer.addChild(w);
+        connectionLayer = new LayerWidget(this);
+        this.addChild(connectionLayer);
 
         mainLayer = new LayerWidget(this);
         this.addChild(mainLayer);
@@ -385,83 +416,53 @@
         topLeft.setPreferredLocation(new Point(-BORDER_SIZE, -BORDER_SIZE));
         this.addChild(topLeft);
 
-
         bottomRight = new Widget(this);
         bottomRight.setPreferredLocation(new Point(-BORDER_SIZE, -BORDER_SIZE));
         this.addChild(bottomRight);
 
-        slotLayer = new LayerWidget(this);
-        this.addChild(slotLayer);
-
-        connectionLayer = new LayerWidget(this);
-        this.addChild(connectionLayer);
-
         LayerWidget selectionLayer = new LayerWidget(this);
         this.addChild(selectionLayer);
 
         this.setLayout(LayoutFactory.createAbsoluteLayout());
 
-        this.getActions().addAction(hoverAction);
-        zoomAction = new BoundedZoomAction(1.1, false);
-        zoomAction.setMaxFactor(ZOOM_MAX_FACTOR);
-        zoomAction.setMinFactor(ZOOM_MIN_FACTOR);
-        this.getActions().addAction(ActionFactory.createMouseCenteredZoomAction(1.1));
-        panAction = new ExtendedPanAction();
-        this.getActions().addAction(panAction);
+        this.getInputBindings().setZoomActionModifiers(KeyEvent.CTRL_MASK);
+        zoomAction = ActionFactory.createMouseCenteredZoomAction(1.2);
+        this.getActions().addAction(zoomAction);
+        this.getView().addMouseWheelListener(mouseWheelListener);
         this.getActions().addAction(ActionFactory.createPopupMenuAction(popupMenuProvider));
 
+        this.getActions().addAction(ActionFactory.createWheelPanAction());
+
         LayerWidget selectLayer = new LayerWidget(this);
         this.addChild(selectLayer);
         this.getActions().addAction(ActionFactory.createRectangularSelectAction(rectangularSelectDecorator, selectLayer, rectangularSelectProvider));
 
-        blockWidgets = new HashMap<InputBlock, BlockWidget>();
-
         boolean b = this.getUndoRedoEnabled();
         this.setUndoRedoEnabled(false);
         this.setNewModel(model);
         this.setUndoRedoEnabled(b);
-    }
-
-    private void selectionUpdated() {
-        getModel().setSelectedNodes(this.getSelectedNodes());
-        addUndo();
+        this.addObjectSceneListener(selectionChangedListener, ObjectSceneEventType.OBJECT_SELECTION_CHANGED, ObjectSceneEventType.OBJECT_HIGHLIGHTING_CHANGED, ObjectSceneEventType.OBJECT_HOVER_CHANGED);
     }
 
     public DiagramViewModel getModel() {
         return model;
     }
 
-    public void setRealZoomFactor(double d) {
-        this.realZoomFactor = d;
-    }
-
-    public double getRealZoomFactor() {
-        if (realZoomFactor == 0.0) {
-            return getZoomFactor();
-        } else {
-            return realZoomFactor;
-        }
-    }
-
     public JScrollPane getScrollPane() {
         return scrollPane;
     }
 
+    @Override
+    public Component getComponent() {
+        return scrollPane;
+    }
+
     public boolean isAllVisible() {
-        return getModel().getHiddenNodes().size() == 0;
+        return getModel().getHiddenNodes().isEmpty();
     }
 
     public Action createGotoAction(final Figure f) {
         final DiagramScene diagramScene = this;
-        Action a = new AbstractAction() {
-
-            public void actionPerformed(ActionEvent e) {
-                diagramScene.gotoFigure(f);
-            }
-        };
-
-        a.setEnabled(true);
-        a.putValue(Action.SMALL_ICON, new ColorIcon(f.getColor()));
         String name = f.getLines()[0];
 
         name += " (";
@@ -469,112 +470,81 @@
         if (f.getCluster() != null) {
             name += "B" + f.getCluster().toString();
         }
-        if (!this.getFigureWidget(f).isVisible()) {
+        final boolean hidden = !this.getWidget(f, FigureWidget.class).isVisible();
+        if (hidden) {
             if (f.getCluster() != null) {
                 name += ", ";
             }
             name += "hidden";
         }
         name += ")";
-        a.putValue(Action.NAME, name);
+        Action a = new AbstractAction(name, new ColorIcon(f.getColor())) {
+
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                diagramScene.gotoFigure(f);
+            }
+        };
+
+        a.setEnabled(true);
         return a;
     }
 
     public void setNewModel(DiagramViewModel model) {
-        if (this.model != null) {
-            this.model.getDiagramChangedEvent().removeListener(this);
-            this.model.getViewPropertiesChangedEvent().removeListener(this);
-        }
+        assert this.model == null : "can set model only once!";
         this.model = model;
+        this.modelCopy = null;
 
-        if (this.model == null) {
-            this.modelCopy = null;
-        } else {
-            this.modelCopy = this.model.copy();
-        }
-
-        model.getDiagramChangedEvent().addListener(this);
-        model.getViewPropertiesChangedEvent().addListener(this);
-
+        model.getDiagramChangedEvent().addListener(fullChange);
+        model.getViewPropertiesChangedEvent().addListener(fullChange);
+        model.getViewChangedEvent().addListener(selectionChange);
+        model.getHiddenNodesChangedEvent().addListener(hiddenNodesChange);
         update();
     }
 
     private void update() {
-
-        /*if (startLabel != null) {
-        // Animate fade-out
-        final LabelWidget labelWidget = this.startLabel;
-        labelWidget.setVisible(true);
-        RequestProcessor.getDefault().post(new Runnable() {
-        public void run() {
-        final int Sleep = 200;
-        final int Progress = 10;
-        for (int i = 0; i < 255 / Progress + 1; i++) {
-        try {
-        SwingUtilities.invokeAndWait(new Runnable() {
-        public void run() {
-        Color c = labelWidget.getForeground();
-        int v = c.getRed();
-        v += Progress;
-        if (v > 255) {
-        v = 255;
-        }
-        labelWidget.setForeground(new Color(v, v, v, 255 - v));
-        labelWidget.getScene().validate();
-        }
-        });
-        } catch (InterruptedException ex) {
-        } catch (InvocationTargetException ex) {
-        }
-        try {
-        Thread.sleep(Sleep);
-        } catch (InterruptedException ex) {
-        }
-        }
-        labelWidget.setVisible(false);
-        DiagramScene.this.scrollChangeListener.unregister(labelWidget);
-        }
-        }, 1000);
-        startLabel = null;
-        }*/
-
-        slotLayer.removeChildren();
         mainLayer.removeChildren();
         blockLayer.removeChildren();
 
-        blockWidgets.clear();
-        figureWidgets = new HashMap<Figure, FigureWidget>();
-        slotWidgets = new HashMap<Slot, SlotWidget>();
-        connectionWidgets = new HashMap<Connection, ConnectionWidget>();
+        rebuilding = true;
 
-        WidgetAction selectAction = new ExtendedSelectAction(selectProvider);
+        Collection<Object> objects = new ArrayList<>(this.getObjects());
+        for (Object o : objects) {
+            this.removeObject(o);
+        }
+
         Diagram d = getModel().getDiagramToView();
 
-        if (getModel().getShowBlocks()) {
+        if (d.getGraph().getBlocks().isEmpty()) {
             Scheduler s = Lookup.getDefault().lookup(Scheduler.class);
-            Collection<InputBlock> newBlocks = new ArrayList<InputBlock>(s.schedule(d.getGraph()));
-            d.schedule(newBlocks);
+            d.getGraph().clearBlocks();
+            s.schedule(d.getGraph());
+            d.getGraph().ensureNodesInBlocks();
+            d.updateBlocks();
         }
 
         for (Figure f : d.getFigures()) {
-            FigureWidget w = new FigureWidget(f, this, mainLayer);
+            FigureWidget w = new FigureWidget(f, hoverAction, selectAction, this, mainLayer);
+            w.getActions().addAction(ActionFactory.createPopupMenuAction(w));
             w.getActions().addAction(selectAction);
             w.getActions().addAction(hoverAction);
-            w.getActions().addAction(ActionFactory.createPopupMenuAction(w));
-            w.getActions().addAction(new DoubleClickAction(w));
             w.setVisible(false);
 
-            figureWidgets.put(f, w);
+            this.addObject(f, w);
 
             for (InputSlot s : f.getInputSlots()) {
-                SlotWidget sw = new InputSlotWidget(s, this, slotLayer, w);
-                slotWidgets.put(s, sw);
+                SlotWidget sw = new InputSlotWidget(s, this, w, w);
+                addObject(s, sw);
+                sw.getActions().addAction(new DoubleClickAction(sw));
+                sw.getActions().addAction(hoverAction);
                 sw.getActions().addAction(selectAction);
             }
 
             for (OutputSlot s : f.getOutputSlots()) {
-                SlotWidget sw = new OutputSlotWidget(s, this, slotLayer, w);
-                slotWidgets.put(s, sw);
+                SlotWidget sw = new OutputSlotWidget(s, this, w, w);
+                addObject(s, sw);
+                sw.getActions().addAction(new DoubleClickAction(sw));
+                sw.getActions().addAction(hoverAction);
                 sw.getActions().addAction(selectAction);
             }
         }
@@ -583,28 +553,30 @@
             for (InputBlock bn : d.getGraph().getBlocks()) {
                 BlockWidget w = new BlockWidget(this, d, bn);
                 w.setVisible(false);
-                blockWidgets.put(bn, w);
+                this.addObject(bn, w);
                 blockLayer.addChild(w);
             }
         }
 
+        rebuilding = false;
         this.smallUpdate(true);
+    }
 
+    public boolean isRebuilding() {
+        return rebuilding;
     }
 
     private void smallUpdate(boolean relayout) {
-
         this.updateHiddenNodes(model.getHiddenNodes(), relayout);
         boolean b = this.getUndoRedoEnabled();
         this.setUndoRedoEnabled(false);
-        this.setSelection(getModel().getSelectedNodes());
         this.setUndoRedoEnabled(b);
         this.validate();
     }
 
     private boolean isVisible(Connection c) {
-        FigureWidget w1 = figureWidgets.get(c.getInputSlot().getFigure());
-        FigureWidget w2 = figureWidgets.get(c.getOutputSlot().getFigure());
+        FigureWidget w1 = getWidget(c.getInputSlot().getFigure());
+        FigureWidget w2 = getWidget(c.getOutputSlot().getFigure());
 
         if (w1.isVisible() && w2.isVisible()) {
             return true;
@@ -614,19 +586,18 @@
     }
 
     private void relayout(Set<Widget> oldVisibleWidgets) {
-
         Diagram diagram = getModel().getDiagramToView();
 
-        HashSet<Figure> figures = new HashSet<Figure>();
+        HashSet<Figure> figures = new HashSet<>();
 
         for (Figure f : diagram.getFigures()) {
-            FigureWidget w = figureWidgets.get(f);
+            FigureWidget w = getWidget(f);
             if (w.isVisible()) {
                 figures.add(f);
             }
         }
 
-        HashSet<Connection> edges = new HashSet<Connection>();
+        HashSet<Connection> edges = new HashSet<>();
 
         for (Connection c : diagram.getConnections()) {
             if (isVisible(c)) {
@@ -635,24 +606,31 @@
         }
 
         if (getModel().getShowBlocks()) {
-            HierarchicalClusterLayoutManager m = new HierarchicalClusterLayoutManager(OldHierarchicalLayoutManager.Combine.SAME_OUTPUTS);
+            HierarchicalClusterLayoutManager m = new HierarchicalClusterLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS);
             HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS);
             manager.setMaxLayerLength(9);
             manager.setMinLayerDifference(3);
             m.setManager(manager);
             m.setSubManager(new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS));
             m.doLayout(new LayoutGraph(edges, figures));
-
         } else {
             HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS);
             manager.setMaxLayerLength(10);
             manager.doLayout(new LayoutGraph(edges, figures));
         }
 
+        relayoutWithoutLayout(oldVisibleWidgets);
+    }
+    private Set<Pair<Point, Point>> lineCache = new HashSet<>();
+
+    private void relayoutWithoutLayout(Set<Widget> oldVisibleWidgets) {
+
+        Diagram diagram = getModel().getDiagramToView();
+
         int maxX = -BORDER_SIZE;
         int maxY = -BORDER_SIZE;
         for (Figure f : diagram.getFigures()) {
-            FigureWidget w = figureWidgets.get(f);
+            FigureWidget w = getWidget(f);
             if (w.isVisible()) {
                 Point p = f.getPosition();
                 Dimension d = f.getSize();
@@ -663,8 +641,8 @@
 
         for (Connection c : diagram.getConnections()) {
             List<Point> points = c.getControlPoints();
-            FigureWidget w1 = figureWidgets.get((Figure) c.getTo().getVertex());
-            FigureWidget w2 = figureWidgets.get((Figure) c.getFrom().getVertex());
+            FigureWidget w1 = getWidget((Figure) c.getTo().getVertex());
+            FigureWidget w2 = getWidget((Figure) c.getFrom().getVertex());
             if (w1.isVisible() && w2.isVisible()) {
                 for (Point p : points) {
                     if (p != null) {
@@ -677,7 +655,7 @@
 
         if (getModel().getShowBlocks()) {
             for (Block b : diagram.getBlocks()) {
-                BlockWidget w = blockWidgets.get(b.getInputBlock());
+                BlockWidget w = getWidget(b.getInputBlock());
                 if (w != null && w.isVisible()) {
                     Rectangle r = b.getBounds();
                     maxX = Math.max(maxX, r.x + r.width);
@@ -693,6 +671,8 @@
         int curHeight = maxY + 2 * BORDER_SIZE;
 
         Rectangle bounds = this.getScrollPane().getBounds();
+        bounds.width /= getZoomFactor();
+        bounds.height /= getZoomFactor();
         if (curWidth < bounds.width) {
             offx = (bounds.width - curWidth) / 2;
         }
@@ -708,62 +688,61 @@
         connectionLayer.removeChildren();
         int visibleFigureCount = 0;
         for (Figure f : diagram.getFigures()) {
-            if (figureWidgets.get(f).isVisible()) {
+            if (getWidget(f, FigureWidget.class).isVisible()) {
                 visibleFigureCount++;
             }
         }
 
+
+        Set<Pair<Point, Point>> lastLineCache = lineCache;
+        lineCache = new HashSet<>();
+        for (Figure f : diagram.getFigures()) {
+            for (OutputSlot s : f.getOutputSlots()) {
+                SceneAnimator anim = animator;
+                if (visibleFigureCount > ANIMATION_LIMIT || oldVisibleWidgets == null) {
+                    anim = null;
+                }
+                processOutputSlot(lastLineCache, s, s.getConnections(), 0, null, null, offx2, offy2, anim);
+            }
+        }
+
         for (Figure f : diagram.getFigures()) {
-            for (OutputSlot s : f.getOutputSlots()) {
-                SceneAnimator anim = animator;
-                if (visibleFigureCount > ANIMATION_LIMIT) {
-                    anim = null;
-                }
-                processOutputSlot(s, s.getConnections(), 0, null, null, offx2, offy2, anim);
-            }
-        }
-
-        for (Figure f : diagram.getFigures()) {
-            FigureWidget w = figureWidgets.get(f);
+            FigureWidget w = getWidget(f);
             if (w.isVisible()) {
                 Point p = f.getPosition();
                 Point p2 = new Point(p.x + offx2, p.y + offy2);
-                Rectangle r = new Rectangle(p.x + offx2, p.y + offy2, f.getSize().width, f.getSize().height);
-                if (oldVisibleWidgets.contains(w)) {
-                    if (visibleFigureCount > ANIMATION_LIMIT) {
-                        w.setPreferredLocation(p2);
-                    } else {
-                        animator.animatePreferredLocation(w, p2);
-                    }
+                if ((visibleFigureCount <= ANIMATION_LIMIT && oldVisibleWidgets != null && oldVisibleWidgets.contains(w))) {
+                    animator.animatePreferredLocation(w, p2);
                 } else {
                     w.setPreferredLocation(p2);
+                    animator.animatePreferredLocation(w, p2);
                 }
             }
         }
 
         if (getModel().getShowBlocks()) {
             for (Block b : diagram.getBlocks()) {
-                BlockWidget w = blockWidgets.get(b.getInputBlock());
+                BlockWidget w = getWidget(b.getInputBlock());
                 if (w != null && w.isVisible()) {
                     Point location = new Point(b.getBounds().x + offx2, b.getBounds().y + offy2);
                     Rectangle r = new Rectangle(location.x, location.y, b.getBounds().width, b.getBounds().height);
-                    if (oldVisibleWidgets.contains(w)) {
-                        if (visibleFigureCount > ANIMATION_LIMIT) {
-                            w.setPreferredBounds(r);
-                        } else {
-                            animator.animatePreferredBounds(w, r);
-                        }
+
+                    if ((visibleFigureCount <= ANIMATION_LIMIT && oldVisibleWidgets != null && oldVisibleWidgets.contains(w))) {
+                        animator.animatePreferredBounds(w, r);
                     } else {
                         w.setPreferredBounds(r);
+                        animator.animatePreferredBounds(w, r);
                     }
                 }
             }
         }
+
+        this.validate();
     }
     private final Point specialNullPoint = new Point(Integer.MAX_VALUE, Integer.MAX_VALUE);
 
-    private void processOutputSlot(OutputSlot s, List<Connection> connections, int controlPointIndex, Point lastPoint, LineWidget predecessor, int offx, int offy, SceneAnimator animator) {
-        Map<Point, List<Connection>> pointMap = new HashMap<Point, List<Connection>>();
+    private void processOutputSlot(Set<Pair<Point, Point>> lastLineCache, OutputSlot s, List<Connection> connections, int controlPointIndex, Point lastPoint, LineWidget predecessor, int offx, int offy, SceneAnimator animator) {
+        Map<Point, List<Connection>> pointMap = new HashMap<>(connections.size());
 
         for (Connection c : connections) {
 
@@ -779,16 +758,16 @@
             Point cur = controlPoints.get(controlPointIndex);
             if (cur == null) {
                 cur = specialNullPoint;
-            } else if (controlPointIndex == 0 && !s.getShowName()) {
+            } else if (controlPointIndex == 0 && !s.shouldShowName()) {
                 cur = new Point(cur.x, cur.y - SLOT_OFFSET);
-            } else if (controlPointIndex == controlPoints.size() - 1 && !c.getInputSlot().getShowName()) {
+            } else if (controlPointIndex == controlPoints.size() - 1 && !c.getInputSlot().shouldShowName()) {
                 cur = new Point(cur.x, cur.y + SLOT_OFFSET);
             }
 
             if (pointMap.containsKey(cur)) {
                 pointMap.get(cur).add(c);
             } else {
-                List<Connection> newList = new ArrayList<Connection>(2);
+                List<Connection> newList = new ArrayList<>(2);
                 newList.add(c);
                 pointMap.put(cur, newList);
             }
@@ -814,44 +793,70 @@
 
             LineWidget newPredecessor = predecessor;
             if (p == specialNullPoint) {
-
             } else if (lastPoint == specialNullPoint) {
-
             } else if (lastPoint != null) {
                 Point p1 = new Point(lastPoint.x + offx, lastPoint.y + offy);
                 Point p2 = new Point(p.x + offx, p.y + offy);
-                LineWidget w = new LineWidget(this, s, connectionList, p1, p2, predecessor, animator, isBold, isDashed);
+
+                Pair<Point, Point> curPair = new Pair<>(p1, p2);
+                SceneAnimator curAnimator = animator;
+                if (lastLineCache.contains(curPair)) {
+                    curAnimator = null;
+                }
+                LineWidget w = new LineWidget(this, s, connectionList, p1, p2, predecessor, curAnimator, isBold, isDashed);
+                lineCache.add(curPair);
+
                 newPredecessor = w;
                 connectionLayer.addChild(w);
+                this.addObject(new ConnectionSet(connectionList), w);
                 w.getActions().addAction(hoverAction);
             }
 
-            processOutputSlot(s, connectionList, controlPointIndex + 1, p, newPredecessor, offx, offy, animator);
+            processOutputSlot(lastLineCache, s, connectionList, controlPointIndex + 1, p, newPredecessor, offx, offy, animator);
         }
     }
 
-    private void clearSelection() {
-        if (selectedWidgets.size() == 0) {
-            return;
-        }
-        for (FigureWidget w : selectedWidgets) {
-            assert w.getState().isSelected();
-            w.setState(w.getState().deriveSelected(false));
-            content.remove(w.getNode());
-        }
-        selectedWidgets.clear();
+    @Override
+    public void setInteractionMode(InteractionMode mode) {
+        panAction.setEnabled(mode == InteractionMode.PANNING);
+        // When panAction is not enabled, it does not consume the event
+        // and the selection action handles it instead
     }
 
+    private class ConnectionSet {
+
+        private Set<Connection> connections;
+
+        public ConnectionSet(Collection<Connection> connections) {
+            connections = new HashSet<>(connections);
+        }
+
+        public Set<Connection> getConnectionSet() {
+            return Collections.unmodifiableSet(connections);
+        }
+    }
+
+    @Override
     public Lookup getLookup() {
         return lookup;
     }
 
+    @Override
+    public void initialize() {
+        Figure f = getModel().getDiagramToView().getRootFigure();
+        if (f != null) {
+            setUndoRedoEnabled(false);
+            gotoFigure(f);
+            setUndoRedoEnabled(true);
+        }
+    }
+
     public void gotoFigures(final List<Figure> figures) {
         Rectangle overall = null;
-        showFigures(figures);
+        getModel().showFigures(figures);
         for (Figure f : figures) {
 
-            FigureWidget fw = getFigureWidget(f);
+            FigureWidget fw = getWidget(f);
             if (fw != null) {
                 Rectangle r = fw.getBounds();
                 Point p = fw.getLocation();
@@ -869,6 +874,54 @@
         }
     }
 
+    private Set<Object> idSetToObjectSet(Set<Object> ids) {
+
+        Set<Object> result = new HashSet<>();
+        for (Figure f : getModel().getDiagramToView().getFigures()) {
+            if (DiagramScene.doesIntersect(f.getSource().getSourceNodesAsSet(), ids)) {
+                result.add(f);
+            }
+
+            for (Slot s : f.getSlots()) {
+                if (DiagramScene.doesIntersect(s.getSource().getSourceNodesAsSet(), ids)) {
+                    result.add(s);
+                }
+            }
+        }
+        return result;
+    }
+
+    public void gotoSelection(Set<Object> ids) {
+
+        Rectangle overall = null;
+        Set<Integer> hiddenNodes = new HashSet<>(this.getModel().getHiddenNodes());
+        hiddenNodes.removeAll(ids);
+        this.getModel().showNot(hiddenNodes);
+
+        Set<Object> objects = idSetToObjectSet(ids);
+        for (Object o : objects) {
+
+            Widget w = getWidget(o);
+            if (w != null) {
+                Rectangle r = w.getBounds();
+                Point p = w.convertLocalToScene(new Point(0, 0));
+
+                Rectangle r2 = new Rectangle(p.x, p.y, r.width, r.height);
+
+                if (overall == null) {
+                    overall = r2;
+                } else {
+                    overall = overall.union(r2);
+                }
+            }
+        }
+        if (overall != null) {
+            centerRectangle(overall);
+        }
+
+        setSelectedObjects(objects);
+    }
+
     private Point calcCenter(Rectangle r) {
 
         Point center = new Point((int) r.getCenterX(), (int) r.getCenterY());
@@ -909,63 +962,9 @@
         }
     }
 
-    private void addToSelection(Figure f) {
-        FigureWidget w = getFigureWidget(f);
-        addToSelection(w);
-    }
-
-    private void addToSelection(FigureWidget w) {
-        assert !selectedWidgets.contains(w);
-        selectedWidgets.add(w);
-        content.add(w.getNode());
-        w.setState(w.getState().deriveSelected(true));
-    }
-
-    private void setSelection(Set<Integer> nodes) {
-        clearSelection();
-        for (Figure f : getModel().getDiagramToView().getFigures()) {
-            if (doesIntersect(f.getSource().getSourceNodesAsSet(), nodes)) {
-                addToSelection(f);
-            }
-        }
-        selectionUpdated();
-        this.validate();
-    }
-
+    @Override
     public void setSelection(Collection<Figure> list) {
-        clearSelection();
-        for (Figure f : list) {
-            addToSelection(f);
-        }
-
-        selectionUpdated();
-        this.validate();
-    }
-
-    public Set<Figure> getSelectedFigures() {
-        Set<Figure> result = new HashSet<Figure>();
-        for (Widget w : selectedWidgets) {
-            if (w instanceof FigureWidget) {
-                FigureWidget fw = (FigureWidget) w;
-                if (fw.getState().isSelected()) {
-                    result.add(fw.getFigure());
-                }
-            }
-        }
-        return result;
-    }
-
-    public Set<Integer> getSelectedNodes() {
-        Set<Integer> result = new HashSet<Integer>();
-        for (Widget w : selectedWidgets) {
-            if (w instanceof FigureWidget) {
-                FigureWidget fw = (FigureWidget) w;
-                if (fw.getState().isSelected()) {
-                    result.addAll(fw.getFigure().getSource().getSourceNodesAsSet());
-                }
-            }
-        }
-        return result;
+        super.setSelectedObjects(new HashSet<>(list));
     }
 
     private UndoRedo.Manager getUndoRedoManager() {
@@ -977,6 +976,7 @@
         return undoRedoManager;
     }
 
+    @Override
     public UndoRedo getUndoRedo() {
         return getUndoRedoManager();
     }
@@ -990,9 +990,9 @@
         return true;
     }
 
-    private boolean doesIntersect(Set s1, Set s2) {
+    public static boolean doesIntersect(Set<?> s1, Set<?> s2) {
         if (s1.size() > s2.size()) {
-            Set tmp = s1;
+            Set<?> tmp = s1;
             s1 = s2;
             s2 = tmp;
         }
@@ -1006,35 +1006,36 @@
         return false;
     }
 
-    public void showNot(final Set<Integer> nodes) {
-        updateHiddenNodes(nodes, true);
+    @Override
+    public void componentHidden() {
+        SelectionCoordinator.getInstance().getHighlightedChangedEvent().removeListener(highlightedCoordinatorListener);
+        SelectionCoordinator.getInstance().getSelectedChangedEvent().removeListener(selectedCoordinatorListener);
     }
 
-    public void showOnly(final Set<Integer> nodes) {
-        HashSet<Integer> allNodes = new HashSet<Integer>(getModel().getGraphToView().getGroup().getAllNodes());
-        allNodes.removeAll(nodes);
-        updateHiddenNodes(allNodes, true);
+    @Override
+    public void componentShowing() {
+        SelectionCoordinator.getInstance().getHighlightedChangedEvent().addListener(highlightedCoordinatorListener);
+        SelectionCoordinator.getInstance().getSelectedChangedEvent().addListener(selectedCoordinatorListener);
     }
 
     private void updateHiddenNodes(Set<Integer> newHiddenNodes, boolean doRelayout) {
 
-        Set<InputBlock> visibleBlocks = new HashSet<InputBlock>();
-
         Diagram diagram = getModel().getDiagramToView();
         assert diagram != null;
 
-        Set<Widget> oldVisibleWidgets = new HashSet<Widget>();
+        Set<InputBlock> visibleBlocks = new HashSet<InputBlock>();
+        Set<Widget> oldVisibleWidgets = new HashSet<>();
 
         for (Figure f : diagram.getFigures()) {
-            FigureWidget w = figureWidgets.get(f);
-            if (w.isVisible()) {
+            FigureWidget w = getWidget(f);
+            if (w != null && w.isVisible()) {
                 oldVisibleWidgets.add(w);
             }
         }
 
         if (getModel().getShowBlocks()) {
             for (InputBlock b : diagram.getGraph().getBlocks()) {
-                BlockWidget w = blockWidgets.get(b);
+                BlockWidget w = getWidget(b);
                 if (w.isVisible()) {
                     oldVisibleWidgets.add(w);
                 }
@@ -1044,7 +1045,7 @@
         for (Figure f : diagram.getFigures()) {
             boolean hiddenAfter = doesIntersect(f.getSource().getSourceNodesAsSet(), newHiddenNodes);
 
-            FigureWidget w = this.figureWidgets.get(f);
+            FigureWidget w = getWidget(f);
             w.setBoundary(false);
             if (!hiddenAfter) {
                 // Figure is shown
@@ -1059,16 +1060,16 @@
         }
 
         if (getModel().getShowNodeHull()) {
-            List<FigureWidget> boundaries = new ArrayList<FigureWidget>();
+            List<FigureWidget> boundaries = new ArrayList<>();
             for (Figure f : diagram.getFigures()) {
-                FigureWidget w = this.figureWidgets.get(f);
+                FigureWidget w = getWidget(f);
                 if (!w.isVisible()) {
-                    Set<Figure> set = new HashSet<Figure>(f.getPredecessorSet());
+                    Set<Figure> set = new HashSet<>(f.getPredecessorSet());
                     set.addAll(f.getSuccessorSet());
 
                     boolean b = false;
                     for (Figure neighbor : set) {
-                        FigureWidget neighborWidget = figureWidgets.get(neighbor);
+                        FigureWidget neighborWidget = getWidget(neighbor);
                         if (neighborWidget.isVisible()) {
                             b = true;
                             break;
@@ -1097,7 +1098,7 @@
 
                 boolean visibleAfter = visibleBlocks.contains(b);
 
-                BlockWidget w = blockWidgets.get(b);
+                BlockWidget w = getWidget(b);
                 if (visibleAfter) {
                     // Block must be shown
                     w.setVisible(true);
@@ -1108,7 +1109,6 @@
             }
         }
 
-        getModel().setHiddenNodes(newHiddenNodes);
         if (doRelayout) {
             relayout(oldVisibleWidgets);
         }
@@ -1116,51 +1116,50 @@
         addUndo();
     }
 
-    private void showFigures(Collection<Figure> f) {
-        HashSet<Integer> newHiddenNodes = new HashSet<Integer>(getModel().getHiddenNodes());
-        for (Figure fig : f) {
-            newHiddenNodes.removeAll(fig.getSource().getSourceNodesAsSet());
-        }
-        updateHiddenNodes(newHiddenNodes, true);
-    }
-
     private void showFigure(Figure f) {
-        HashSet<Integer> newHiddenNodes = new HashSet<Integer>(getModel().getHiddenNodes());
+        HashSet<Integer> newHiddenNodes = new HashSet<>(getModel().getHiddenNodes());
         newHiddenNodes.removeAll(f.getSource().getSourceNodesAsSet());
-        updateHiddenNodes(newHiddenNodes, true);
-    }
-
-    public void showAll(final Collection<Figure> f) {
-        showFigures(f);
-
+        this.model.setHiddenNodes(newHiddenNodes);
     }
 
     public void show(final Figure f) {
         showFigure(f);
     }
 
+    public void setSelectedObjects(Object... args) {
+        Set<Object> set = new HashSet<>();
+        for (Object o : args) {
+            set.add(o);
+        }
+        super.setSelectedObjects(set);
+    }
+
+    private void centerWidget(Widget w) {
+        Rectangle r = w.getBounds();
+        Point p = w.getLocation();
+        centerRectangle(new Rectangle(p.x, p.y, r.width, r.height));
+    }
+
     public void gotoFigure(final Figure f) {
-
         if (!isVisible(f)) {
             showFigure(f);
         }
 
-        FigureWidget fw = getFigureWidget(f);
+        FigureWidget fw = getWidget(f);
         if (fw != null) {
-            Rectangle r = fw.getBounds();
-            Point p = fw.getLocation();
-            centerRectangle(new Rectangle(p.x, p.y, r.width, r.height));
-
-            // Select figure
-            clearSelection();
-            addToSelection(fw);
-            selectionUpdated();
+            centerWidget(fw);
+            setSelection(Arrays.asList(f));
         }
     }
 
     public JPopupMenu createPopupMenu() {
         JPopupMenu menu = new JPopupMenu();
-        for (Action a : actions) {
+
+        Action[] currentActions = actionsWithSelection;
+        if (this.getSelectedObjects().isEmpty()) {
+            currentActions = actions;
+        }
+        for (Action a : currentActions) {
             if (a == null) {
                 menu.addSeparator();
             } else {
@@ -1208,6 +1207,7 @@
 
             SwingUtilities.invokeLater(new Runnable() {
 
+                @Override
                 public void run() {
                     scene.setScrollPosition(oldScrollPosition);
                 }
@@ -1216,9 +1216,10 @@
             scene.setUndoRedoEnabled(b);
         }
 
+        @Override
         public void changed(DiagramViewModel source) {
             scene.getModel().getViewChangedEvent().removeListener(this);
-            if (oldModel.getSelectedNodes().equals(newModel.getHiddenNodes())) {
+            if (oldModel.getHiddenNodes().equals(newModel.getHiddenNodes())) {
                 scene.smallUpdate(false);
             } else {
                 scene.smallUpdate(true);
@@ -1235,11 +1236,33 @@
         return undoRedoEnabled;
     }
 
-    public void changed(DiagramViewModel source) {
-        assert source == model : "Receive only changed event from current model!";
-        assert source != null;
-        update();
-    }
+    private final ChangedListener<DiagramViewModel> fullChange = new ChangedListener<DiagramViewModel>() {
+        @Override
+        public void changed(DiagramViewModel source) {
+            assert source == model : "Receive only changed event from current model!";
+            assert source != null;
+            update();
+        }
+    };
+
+    private final ChangedListener<DiagramViewModel> hiddenNodesChange = new ChangedListener<DiagramViewModel>() {
+        @Override
+        public void changed(DiagramViewModel source) {
+            assert source == model : "Receive only changed event from current model!";
+            assert source != null;
+            smallUpdate(true);
+        }
+    };
+
+    private final ChangedListener<DiagramViewModel> selectionChange = new ChangedListener<DiagramViewModel>() {
+        @Override
+        public void changed(DiagramViewModel source) {
+            assert source == model : "Receive only changed event from current model!";
+            assert source != null;
+            smallUpdate(false);
+        }
+    };
+
 
     private void addUndo() {
 
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,22 +24,16 @@
  */
 package com.sun.hotspot.igv.view;
 
-import com.sun.hotspot.igv.data.Group;
-import com.sun.hotspot.igv.data.InputGraph;
-import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.*;
 import com.sun.hotspot.igv.difference.Difference;
+import com.sun.hotspot.igv.filter.CustomFilter;
 import com.sun.hotspot.igv.filter.FilterChain;
 import com.sun.hotspot.igv.graph.Diagram;
-import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.graph.Figure;
+import com.sun.hotspot.igv.settings.Settings;
 import com.sun.hotspot.igv.util.RangeSliderModel;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-import com.sun.hotspot.igv.data.ChangedListener;
-import com.sun.hotspot.igv.settings.Settings;
 import java.awt.Color;
+import java.util.*;
 
 /**
  *
@@ -49,20 +43,25 @@
 
     // Warning: Update setData method if fields are added
     private Group group;
+    private ArrayList<InputGraph> graphs;
     private Set<Integer> hiddenNodes;
     private Set<Integer> onScreenNodes;
     private Set<Integer> selectedNodes;
     private FilterChain filterChain;
     private FilterChain sequenceFilterChain;
     private Diagram diagram;
+    private InputGraph inputGraph;
     private ChangedEvent<DiagramViewModel> groupChangedEvent;
     private ChangedEvent<DiagramViewModel> diagramChangedEvent;
     private ChangedEvent<DiagramViewModel> viewChangedEvent;
+    private ChangedEvent<DiagramViewModel> hiddenNodesChangedEvent;
     private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
     private boolean showBlocks;
     private boolean showNodeHull;
+    private boolean hideDuplicates;
     private ChangedListener<FilterChain> filterChainChangedListener = new ChangedListener<FilterChain>() {
 
+        @Override
         public void changed(FilterChain source) {
             diagramChanged();
         }
@@ -75,6 +74,10 @@
         return result;
     }
 
+    public Group getGroup() {
+        return group;
+    }
+
     public void setData(DiagramViewModel newModel) {
         super.setData(newModel);
         boolean diagramChanged = false;
@@ -83,6 +86,10 @@
 
         boolean groupChanged = (group == newModel.group);
         this.group = newModel.group;
+        if (groupChanged) {
+            filterGraphs();
+        }
+
         diagramChanged |= (filterChain != newModel.filterChain);
         this.filterChain = newModel.filterChain;
         diagramChanged |= (sequenceFilterChain != newModel.sequenceFilterChain);
@@ -100,7 +107,7 @@
         viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull);
         this.showNodeHull = newModel.showNodeHull;
 
-        if(groupChanged) {
+        if (groupChanged) {
             groupChangedEvent.fire();
         }
 
@@ -133,53 +140,75 @@
         viewPropertiesChangedEvent.fire();
     }
 
-    public DiagramViewModel(Group g, FilterChain filterChain, FilterChain sequenceFilterChain) {
-        super(calculateStringList(g));
+    public boolean getHideDuplicates() {
+        return hideDuplicates;
+    }
 
+    public void setHideDuplicates(boolean b) {
+        System.err.println("setHideDuplicates: " + b);
+        hideDuplicates = b;
+        InputGraph currentGraph = getFirstGraph();
+        if (hideDuplicates) {
+            // Back up to the unhidden equivalent graph
+            int index = graphs.indexOf(currentGraph);
+            while (graphs.get(index).getProperties().get("_isDuplicate") != null) {
+                index--;
+            }
+            currentGraph = graphs.get(index);
+        }
+        filterGraphs();
+        selectGraph(currentGraph);
+        viewPropertiesChangedEvent.fire();
+    }
+
+    public DiagramViewModel(Group g, FilterChain filterChain, FilterChain sequenceFilterChain) {
+        super(Arrays.asList("default"));
+
+        this.showBlocks = false;
         this.showNodeHull = true;
-        this.showBlocks = true;
         this.group = g;
+        filterGraphs();
         assert filterChain != null;
         this.filterChain = filterChain;
         assert sequenceFilterChain != null;
         this.sequenceFilterChain = sequenceFilterChain;
-        hiddenNodes = new HashSet<Integer>();
-        onScreenNodes = new HashSet<Integer>();
-        selectedNodes = new HashSet<Integer>();
+        hiddenNodes = new HashSet<>();
+        onScreenNodes = new HashSet<>();
+        selectedNodes = new HashSet<>();
         super.getChangedEvent().addListener(this);
-        diagramChangedEvent = new ChangedEvent<DiagramViewModel>(this);
-        viewChangedEvent = new ChangedEvent<DiagramViewModel>(this);
-        viewPropertiesChangedEvent = new ChangedEvent<DiagramViewModel>(this);
-        groupChangedEvent = new ChangedEvent<DiagramViewModel>(this);
+        diagramChangedEvent = new ChangedEvent<>(this);
+        viewChangedEvent = new ChangedEvent<>(this);
+        hiddenNodesChangedEvent = new ChangedEvent<>(this);
+        viewPropertiesChangedEvent = new ChangedEvent<>(this);
+
+        groupChangedEvent = new ChangedEvent<>(this);
         groupChangedEvent.addListener(groupChangedListener);
         groupChangedEvent.fire();
 
         filterChain.getChangedEvent().addListener(filterChainChangedListener);
         sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
     }
-
     private final ChangedListener<DiagramViewModel> groupChangedListener = new ChangedListener<DiagramViewModel>() {
 
         private Group oldGroup;
 
+        @Override
         public void changed(DiagramViewModel source) {
-            if(oldGroup != null) {
+            if (oldGroup != null) {
                 oldGroup.getChangedEvent().removeListener(groupContentChangedListener);
             }
             group.getChangedEvent().addListener(groupContentChangedListener);
             oldGroup = group;
         }
     };
-
-
     private final ChangedListener<Group> groupContentChangedListener = new ChangedListener<Group>() {
 
+        @Override
         public void changed(Group source) {
             assert source == group;
-            setPositions(calculateStringList(source));
+            filterGraphs();
             setSelectedNodes(selectedNodes);
         }
-
     };
 
     public ChangedEvent<DiagramViewModel> getDiagramChangedEvent() {
@@ -190,25 +219,29 @@
         return viewChangedEvent;
     }
 
+    public ChangedEvent<DiagramViewModel> getHiddenNodesChangedEvent() {
+        return hiddenNodesChangedEvent;
+    }
+
     public ChangedEvent<DiagramViewModel> getViewPropertiesChangedEvent() {
         return viewPropertiesChangedEvent;
     }
 
     public Set<Integer> getSelectedNodes() {
-        return Collections.unmodifiableSet(selectedNodes);
+        return selectedNodes;
     }
 
     public Set<Integer> getHiddenNodes() {
-        return Collections.unmodifiableSet(hiddenNodes);
+        return hiddenNodes;
     }
 
     public Set<Integer> getOnScreenNodes() {
-        return Collections.unmodifiableSet(onScreenNodes);
+        return onScreenNodes;
     }
 
     public void setSelectedNodes(Set<Integer> nodes) {
         this.selectedNodes = nodes;
-        List<Color> colors = new ArrayList<Color>();
+        List<Color> colors = new ArrayList<>();
         for (String s : getPositions()) {
             colors.add(Color.black);
         }
@@ -219,14 +252,14 @@
                 }
                 InputNode last = null;
                 int index = 0;
-                for (InputGraph g : group.getGraphs()) {
+                for (InputGraph g : graphs) {
                     Color curColor = colors.get(index);
                     InputNode cur = g.getNode(id);
                     if (cur != null) {
                         if (last == null) {
                             curColor = Color.green;
                         } else {
-                            if (last.equals(cur)) {
+                            if (last.equals(cur) && last.getProperties().equals(cur.getProperties())) {
                                 if (curColor == Color.black) {
                                     curColor = Color.white;
                                 }
@@ -242,15 +275,49 @@
                     index++;
                 }
             }
-            this.setColors(colors);
         }
         setColors(colors);
         viewChangedEvent.fire();
     }
 
+    public void showNot(final Set<Integer> nodes) {
+        setHiddenNodes(nodes);
+    }
+
+    public void showFigures(Collection<Figure> f) {
+        HashSet<Integer> newHiddenNodes = new HashSet<>(getHiddenNodes());
+        for (Figure fig : f) {
+            newHiddenNodes.removeAll(fig.getSource().getSourceNodesAsSet());
+        }
+        setHiddenNodes(newHiddenNodes);
+    }
+
+
+    public Set<Figure> getSelectedFigures() {
+        Set<Figure> result = new HashSet<>();
+        for (Figure f : diagram.getFigures()) {
+            for (InputNode node : f.getSource().getSourceNodes()) {
+                if (getSelectedNodes().contains(node.getId())) {
+                    result.add(f);
+                }
+            }
+        }
+        return result;
+    }
+
+    public void showAll(final Collection<Figure> f) {
+        showFigures(f);
+    }
+
+    public void showOnly(final Set<Integer> nodes) {
+        final HashSet<Integer> allNodes = new HashSet<>(getGraphToView().getGroup().getAllNodes());
+        allNodes.removeAll(nodes);
+        setHiddenNodes(allNodes);
+    }
+
     public void setHiddenNodes(Set<Integer> nodes) {
         this.hiddenNodes = nodes;
-        viewChangedEvent.fire();
+        hiddenNodesChangedEvent.fire();
     }
 
     public void setOnScreenNodes(Set<Integer> onScreenNodes) {
@@ -289,27 +356,44 @@
         diagramChanged();
     }
 
-    private static List<String> calculateStringList(Group g) {
-        List<String> result = new ArrayList<String>();
-        for (InputGraph graph : g.getGraphs()) {
-            result.add(graph.getName());
+    /*
+     * Select the set of graphs to be presented.
+     */
+    private void filterGraphs() {
+        ArrayList<InputGraph> result = new ArrayList<>();
+        List<String> positions = new ArrayList<>();
+        for (InputGraph graph : group.getGraphs()) {
+            String duplicate = graph.getProperties().get("_isDuplicate");
+            if (duplicate == null || !hideDuplicates) {
+                result.add(graph);
+                positions.add(graph.getName());
+            }
         }
-        return result;
+        this.graphs = result;
+        setPositions(positions);
     }
 
     public InputGraph getFirstGraph() {
-        return group.getGraphs().get(getFirstPosition());
+        if (getFirstPosition() < graphs.size()) {
+            return graphs.get(getFirstPosition());
+        }
+        return graphs.get(graphs.size() - 1);
     }
 
     public InputGraph getSecondGraph() {
-        List<InputGraph> graphs = group.getGraphs();
-        if (graphs.size() >= getSecondPosition())
-            return group.getGraphs().get(getSecondPosition());
+        if (getSecondPosition() < graphs.size()) {
+            return graphs.get(getSecondPosition());
+        }
         return getFirstGraph();
     }
 
     public void selectGraph(InputGraph g) {
-        int index = group.getGraphs().indexOf(g);
+        int index = graphs.indexOf(g);
+        if (index == -1 && hideDuplicates) {
+            // A graph was selected that's currently hidden, so unhide and select it.
+            setHideDuplicates(false);
+            index = graphs.indexOf(g);
+        }
         assert index != -1;
         setPositions(index, index);
     }
@@ -319,22 +403,47 @@
         if (diagram == null) {
             diagram = Diagram.createDiagram(getGraphToView(), Settings.get().get(Settings.NODE_TEXT, Settings.NODE_TEXT_DEFAULT));
             getFilterChain().apply(diagram, getSequenceFilterChain());
+            if (getFirstPosition() != getSecondPosition()) {
+                CustomFilter f = new CustomFilter(
+                        "difference", "colorize('state', 'same', white);"
+                        + "colorize('state', 'changed', orange);"
+                        + "colorize('state', 'new', green);"
+                        + "colorize('state', 'deleted', red);");
+                f.apply(diagram);
+           }
         }
 
         return diagram;
     }
 
     public InputGraph getGraphToView() {
-        if (getFirstGraph() != getSecondGraph()) {
-            InputGraph inputGraph = Difference.createDiffGraph(getSecondGraph(), getFirstGraph());
-            return inputGraph;
-        } else {
-            InputGraph inputGraph = getFirstGraph();
-            return inputGraph;
+        if (inputGraph == null) {
+            if (getFirstGraph() != getSecondGraph()) {
+                inputGraph = Difference.createDiffGraph(getFirstGraph(), getSecondGraph());
+            } else {
+                inputGraph = getFirstGraph();
+            }
         }
+
+        return inputGraph;
     }
 
+    @Override
     public void changed(RangeSliderModel source) {
+        inputGraph = null;
         diagramChanged();
     }
+
+    void setSelectedFigures(List<Figure> list) {
+        Set<Integer> newSelectedNodes = new HashSet<>();
+        for (Figure f : list) {
+            newSelectedNodes.addAll(f.getSource().getSourceNodesAsSet());
+        }
+        this.setSelectedNodes(newSelectedNodes);
+    }
+
+    void close() {
+        filterChain.getChangedEvent().removeListener(filterChainChangedListener);
+        sequenceFilterChain.getChangedEvent().removeListener(filterChainChangedListener);
 }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewer.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package com.sun.hotspot.igv.view;
+
+import com.sun.hotspot.igv.graph.Figure;
+import java.awt.Component;
+import java.awt.Graphics2D;
+import java.util.Collection;
+import java.util.List;
+import javax.swing.JComponent;
+import org.openide.awt.UndoRedo;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+interface DiagramViewer {
+
+    enum InteractionMode {
+        SELECTION,
+        PANNING,
+    }
+
+    public void paint(Graphics2D svgGenerator);
+
+    public Lookup getLookup();
+
+    public JComponent createSatelliteView();
+
+    public Component getComponent();
+
+    public void zoomOut();
+
+    public void zoomIn();
+
+    public UndoRedo getUndoRedo();
+
+    public void componentHidden();
+
+    public void componentShowing();
+
+    public void initialize();
+
+    public void setSelection(Collection<Figure> list);
+
+    public void centerFigures(List<Figure> list);
+
+    public void setInteractionMode(InteractionMode mode);
+
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,8 +25,8 @@
 package com.sun.hotspot.igv.view;
 
 import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputNode;
 import com.sun.hotspot.igv.data.services.InputGraphProvider;
-import com.sun.hotspot.igv.data.InputNode;
 import java.util.Set;
 
 /**
@@ -35,18 +35,19 @@
  */
 public class EditorInputGraphProvider implements InputGraphProvider {
 
-    public InputGraph getGraph() {
-        EditorTopComponent e = EditorTopComponent.getActive();
-        if (e == null) {
-            return null;
-        }
-        return e.getDiagramModel().getGraphToView();
+    private EditorTopComponent editor;
+
+    public EditorInputGraphProvider(EditorTopComponent editor) {
+        this.editor = editor;
     }
 
+    @Override
+    public InputGraph getGraph() {
+        return editor.getDiagramModel().getGraphToView();
+    }
+
+    @Override
     public void setSelectedNodes(Set<InputNode> nodes) {
-        EditorTopComponent e = EditorTopComponent.getActive();
-        if (e != null) {
-            e.setSelectedNodes(nodes);
-        }
+        editor.setSelectedNodes(nodes);
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.form	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.form	Tue May 05 19:27:08 2015 +0200
@@ -18,6 +18,8 @@
   </NonVisualComponents>
   <AuxValues>
     <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="true"/>
     <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
     <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,62 +23,35 @@
  */
 package com.sun.hotspot.igv.view;
 
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
 import com.sun.hotspot.igv.filter.FilterChain;
+import com.sun.hotspot.igv.filter.FilterChainProvider;
 import com.sun.hotspot.igv.graph.Diagram;
 import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.view.actions.EnableBlockLayoutAction;
-import com.sun.hotspot.igv.view.actions.ExpandPredecessorsAction;
-import com.sun.hotspot.igv.view.actions.ExpandSuccessorsAction;
-import com.sun.hotspot.igv.view.actions.ExtractAction;
-import com.sun.hotspot.igv.view.actions.HideAction;
-import com.sun.hotspot.igv.view.actions.NextDiagramAction;
-import com.sun.hotspot.igv.view.actions.NodeFindAction;
-import com.sun.hotspot.igv.view.actions.OverviewAction;
-import com.sun.hotspot.igv.view.actions.PredSuccAction;
-import com.sun.hotspot.igv.view.actions.PrevDiagramAction;
-import com.sun.hotspot.igv.view.actions.ShowAllAction;
-import com.sun.hotspot.igv.view.actions.ZoomInAction;
-import com.sun.hotspot.igv.view.actions.ZoomOutAction;
-import com.sun.hotspot.igv.data.ChangedListener;
-import com.sun.hotspot.igv.data.Properties;
-import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
-import com.sun.hotspot.igv.filter.FilterChainProvider;
+import com.sun.hotspot.igv.graph.services.DiagramProvider;
+import com.sun.hotspot.igv.svg.BatikSVG;
+import com.sun.hotspot.igv.util.LookupHistory;
 import com.sun.hotspot.igv.util.RangeSlider;
-import com.sun.hotspot.igv.util.RangeSliderModel;
-import com.sun.hotspot.igv.svg.BatikSVG;
-import java.awt.BorderLayout;
-import java.awt.CardLayout;
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics2D;
-import java.awt.Point;
+import com.sun.hotspot.igv.view.actions.*;
+import java.awt.*;
 import java.awt.event.HierarchyBoundsListener;
 import java.awt.event.HierarchyEvent;
 import java.awt.event.KeyEvent;
 import java.awt.event.KeyListener;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.UnsupportedEncodingException;
-import java.io.Writer;
-import java.util.ArrayList;
-import java.util.HashSet;
+import java.io.*;
 import java.util.List;
-import java.util.Set;
-import javax.swing.Action;
-import javax.swing.ActionMap;
-import javax.swing.JPanel;
-import javax.swing.JToggleButton;
-import javax.swing.SwingUtilities;
-import javax.swing.UIManager;
+import java.util.*;
+import javax.swing.*;
 import javax.swing.border.Border;
 import org.openide.DialogDisplayer;
-import org.openide.actions.FindAction;
+import org.openide.NotifyDescriptor;
 import org.openide.actions.RedoAction;
 import org.openide.actions.UndoAction;
 import org.openide.awt.Toolbar;
@@ -86,40 +59,44 @@
 import org.openide.awt.UndoRedo;
 import org.openide.util.Lookup;
 import org.openide.util.NbBundle;
-import org.openide.util.actions.CallbackSystemAction;
-import org.openide.util.actions.SystemAction;
+import org.openide.util.Utilities;
+import org.openide.util.actions.Presenter;
 import org.openide.util.lookup.AbstractLookup;
 import org.openide.util.lookup.InstanceContent;
 import org.openide.util.lookup.ProxyLookup;
 import org.openide.windows.Mode;
 import org.openide.windows.TopComponent;
 import org.openide.windows.WindowManager;
-import org.openide.NotifyDescriptor;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public final class EditorTopComponent extends TopComponent implements ChangedListener<RangeSliderModel>, PropertyChangeListener {
+public final class EditorTopComponent extends TopComponent implements PropertyChangeListener {
 
-    private DiagramScene scene;
+    private DiagramViewer scene;
     private InstanceContent content;
-    private FindPanel findPanel;
+    private InstanceContent graphContent;
     private EnableBlockLayoutAction blockLayoutAction;
     private OverviewAction overviewAction;
+    private HideDuplicatesAction hideDuplicatesAction;
     private PredSuccAction predSuccAction;
+    private SelectionModeAction selectionModeAction;
+    private PanModeAction panModeAction;
     private boolean notFirstTime;
-    private ExtendedSatelliteComponent satelliteComponent;
+    private JComponent satelliteComponent;
     private JPanel centerPanel;
     private CardLayout cardLayout;
     private RangeSlider rangeSlider;
     private JToggleButton overviewButton;
+    private JToggleButton hideDuplicatesButton;
     private static final String PREFERRED_ID = "EditorTopComponent";
     private static final String SATELLITE_STRING = "satellite";
     private static final String SCENE_STRING = "scene";
     private DiagramViewModel rangeSliderModel;
     private ExportCookie exportCookie = new ExportCookie() {
 
+        @Override
         public void export(File f) {
 
             Graphics2D svgGenerator = BatikSVG.createGraphicsObject();
@@ -152,12 +129,32 @@
         }
     };
 
+    private DiagramProvider diagramProvider = new DiagramProvider() {
+
+        @Override
+        public Diagram getDiagram() {
+            return getModel().getDiagramToView();
+        }
+
+        @Override
+        public ChangedEvent<DiagramProvider> getChangedEvent() {
+            return diagramChangedEvent;
+        }
+    };
+
+    private ChangedEvent<DiagramProvider> diagramChangedEvent = new ChangedEvent<>(diagramProvider);
+
+
     private void updateDisplayName() {
         setDisplayName(getDiagram().getName());
+        setToolTipText(getDiagram().getGraph().getGroup().getName());
     }
 
     public EditorTopComponent(Diagram diagram) {
 
+        LookupHistory.init(InputGraphProvider.class);
+        LookupHistory.init(DiagramProvider.class);
+        this.setFocusable(true);
         FilterChain filterChain = null;
         FilterChain sequence = null;
         FilterChainProvider provider = Lookup.getDefault().lookup(FilterChainProvider.class);
@@ -182,16 +179,19 @@
             null,
             ZoomInAction.get(ZoomInAction.class),
             ZoomOutAction.get(ZoomOutAction.class),
+        };
+
+
+        Action[] actionsWithSelection = new Action[]{
+            ExtractAction.get(ExtractAction.class),
+            ShowAllAction.get(HideAction.class),
             null,
             ExpandPredecessorsAction.get(ExpandPredecessorsAction.class),
             ExpandSuccessorsAction.get(ExpandSuccessorsAction.class)
         };
 
-
         initComponents();
 
-        ActionMap actionMap = getActionMap();
-
         ToolbarPool.getDefault().setPreferredIconSize(16);
         Toolbar toolBar = new Toolbar();
         Border b = (Border) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N
@@ -202,24 +202,30 @@
         container.add(BorderLayout.NORTH, toolBar);
 
         rangeSliderModel = new DiagramViewModel(diagram.getGraph().getGroup(), filterChain, sequence);
-        rangeSliderModel.selectGraph(diagram.getGraph());
         rangeSlider = new RangeSlider();
         rangeSlider.setModel(rangeSliderModel);
-        rangeSliderModel.getChangedEvent().addListener(this);
-        container.add(BorderLayout.CENTER, rangeSlider);
+        JScrollPane pane = new JScrollPane(rangeSlider, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+        container.add(BorderLayout.CENTER, pane);
 
-        scene = new DiagramScene(actions, rangeSliderModel);
+        scene = new DiagramScene(actions, actionsWithSelection, rangeSliderModel);
         content = new InstanceContent();
-        this.associateLookup(new ProxyLookup(new Lookup[]{scene.getLookup(), new AbstractLookup(content)}));
+        graphContent = new InstanceContent();
+        this.associateLookup(new ProxyLookup(new Lookup[]{scene.getLookup(), new AbstractLookup(graphContent), new AbstractLookup(content)}));
         content.add(exportCookie);
         content.add(rangeSliderModel);
+        content.add(diagramProvider);
+
+        rangeSliderModel.getDiagramChangedEvent().addListener(diagramChangedListener);
+        rangeSliderModel.selectGraph(diagram.getGraph());
+        rangeSliderModel.getViewPropertiesChangedEvent().addListener(new ChangedListener<DiagramViewModel>() {
+                @Override
+                public void changed(DiagramViewModel source) {
+                    hideDuplicatesButton.setSelected(getModel().getHideDuplicates());
+                    hideDuplicatesAction.setState(getModel().getHideDuplicates());
+                }
+            });
 
 
-        findPanel = new FindPanel(diagram.getFigures());
-        findPanel.setMaximumSize(new Dimension(200, 50));
-        toolBar.add(findPanel);
-        toolBar.add(NodeFindAction.get(NodeFindAction.class));
-        toolBar.addSeparator();
         toolBar.add(NextDiagramAction.get(NextDiagramAction.class));
         toolBar.add(PrevDiagramAction.get(PrevDiagramAction.class));
         toolBar.addSeparator();
@@ -232,7 +238,7 @@
 
         blockLayoutAction = new EnableBlockLayoutAction();
         JToggleButton button = new JToggleButton(blockLayoutAction);
-        button.setSelected(true);
+        button.setSelected(false);
         toolBar.add(button);
         blockLayoutAction.addPropertyChangeListener(this);
 
@@ -248,59 +254,91 @@
         toolBar.add(button);
         predSuccAction.addPropertyChangeListener(this);
 
+        hideDuplicatesAction = new HideDuplicatesAction();
+        hideDuplicatesButton = new JToggleButton(hideDuplicatesAction);
+        hideDuplicatesButton.setSelected(false);
+        toolBar.add(hideDuplicatesButton);
+        hideDuplicatesAction.addPropertyChangeListener(this);
+
         toolBar.addSeparator();
         toolBar.add(UndoAction.get(UndoAction.class));
         toolBar.add(RedoAction.get(RedoAction.class));
 
+        toolBar.addSeparator();
+        ButtonGroup interactionButtons = new ButtonGroup();
+
+        panModeAction = new PanModeAction();
+        panModeAction.setSelected(true);
+        button = new JToggleButton(panModeAction);
+        button.setSelected(true);
+        interactionButtons.add(button);
+        toolBar.add(button);
+        panModeAction.addPropertyChangeListener(this);
+
+        selectionModeAction = new SelectionModeAction();
+        button = new JToggleButton(selectionModeAction);
+        interactionButtons.add(button);
+        toolBar.add(button);
+        selectionModeAction.addPropertyChangeListener(this);
+
+        toolBar.add(Box.createHorizontalGlue());
+        Action action = Utilities.actionsForPath("QuickSearchShadow").get(0);
+        Component quicksearch = ((Presenter.Toolbar) action).getToolbarPresenter();
+        try {
+            // (aw) workaround for disappearing search bar due to reparenting one shared component instance.
+            quicksearch = (Component) quicksearch.getClass().getConstructor(KeyStroke.class).newInstance(new Object[]{null});
+        } catch (ReflectiveOperationException | IllegalArgumentException | SecurityException e) {
+        }
+        quicksearch.setMinimumSize(quicksearch.getPreferredSize()); // necessary for GTK LAF
+        toolBar.add(quicksearch);
+
         centerPanel = new JPanel();
         this.add(centerPanel, BorderLayout.CENTER);
         cardLayout = new CardLayout();
         centerPanel.setLayout(cardLayout);
-        centerPanel.add(SCENE_STRING, scene.getScrollPane());
+        centerPanel.add(SCENE_STRING, scene.getComponent());
         centerPanel.setBackground(Color.WHITE);
-        satelliteComponent = new ExtendedSatelliteComponent(scene);
+        satelliteComponent = scene.createSatelliteView();
         satelliteComponent.setSize(200, 200);
         centerPanel.add(SATELLITE_STRING, satelliteComponent);
 
-        CallbackSystemAction callFindAction = (CallbackSystemAction) SystemAction.get(FindAction.class);
-        NodeFindAction findAction = NodeFindAction.get(NodeFindAction.class);
-        Object key = callFindAction.getActionMapKey();
-        actionMap.put(key, findAction);
+        // TODO: Fix the hot key for entering the satellite view
+        this.addKeyListener(keyListener);
 
-        scene.getScrollPane().addKeyListener(keyListener);
-        scene.getView().addKeyListener(keyListener);
-        satelliteComponent.addKeyListener(keyListener);
+        scene.getComponent().addHierarchyBoundsListener(new HierarchyBoundsListener() {
 
-        scene.getScrollPane().addHierarchyBoundsListener(new HierarchyBoundsListener() {
-
+            @Override
             public void ancestorMoved(HierarchyEvent e) {
             }
 
+            @Override
             public void ancestorResized(HierarchyEvent e) {
-                if (!notFirstTime && scene.getScrollPane().getBounds().width > 0) {
+                if (!notFirstTime && scene.getComponent().getBounds().width > 0) {
                     notFirstTime = true;
                     SwingUtilities.invokeLater(new Runnable() {
 
+                        @Override
                         public void run() {
-                            Figure f = EditorTopComponent.this.scene.getModel().getDiagramToView().getRootFigure();
-                            if (f != null) {
-                                scene.setUndoRedoEnabled(false);
-                                scene.gotoFigure(f);
-                                scene.setUndoRedoEnabled(true);
-                            }
+                            EditorTopComponent.this.scene.initialize();
                         }
                     });
                 }
             }
         });
 
+        if (diagram.getGraph().getGroup().getGraphsCount() == 1) {
+            rangeSlider.setVisible(false);
+        }
+
         updateDisplayName();
     }
     private KeyListener keyListener = new KeyListener() {
 
+        @Override
         public void keyTyped(KeyEvent e) {
         }
 
+        @Override
         public void keyPressed(KeyEvent e) {
             if (e.getKeyCode() == KeyEvent.VK_S) {
                 EditorTopComponent.this.overviewButton.setSelected(true);
@@ -308,6 +346,7 @@
             }
         }
 
+        @Override
         public void keyReleased(KeyEvent e) {
             if (e.getKeyCode() == KeyEvent.VK_S) {
                 EditorTopComponent.this.overviewButton.setSelected(false);
@@ -317,7 +356,7 @@
     };
 
     public DiagramViewModel getDiagramModel() {
-        return scene.getModel();
+        return rangeSliderModel;
     }
 
     private void showSatellite() {
@@ -328,35 +367,15 @@
 
     private void showScene() {
         cardLayout.show(centerPanel, SCENE_STRING);
-        scene.getView().requestFocus();
-    }
-
-    public void findNode() {
-        findPanel.find();
+        scene.getComponent().requestFocus();
     }
 
     public void zoomOut() {
-        double zoom = scene.getZoomFactor();
-        Point viewPosition = scene.getScrollPane().getViewport().getViewPosition();
-        double newZoom = zoom / DiagramScene.ZOOM_INCREMENT;
-        if (newZoom > DiagramScene.ZOOM_MIN_FACTOR) {
-            scene.setZoomFactor(newZoom);
-            scene.validate();
-            scene.getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x / DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y / DiagramScene.ZOOM_INCREMENT)));
-            this.satelliteComponent.update();
-        }
+        scene.zoomOut();
     }
 
     public void zoomIn() {
-        double zoom = scene.getZoomFactor();
-        Point viewPosition = scene.getScrollPane().getViewport().getViewPosition();
-        double newZoom = zoom * DiagramScene.ZOOM_INCREMENT;
-        if (newZoom < DiagramScene.ZOOM_MAX_FACTOR) {
-            scene.setZoomFactor(newZoom);
-            scene.validate();
-            scene.getScrollPane().getViewport().setViewPosition(new Point((int) (viewPosition.x * DiagramScene.ZOOM_INCREMENT), (int) (viewPosition.y * DiagramScene.ZOOM_INCREMENT)));
-            this.satelliteComponent.update();
-        }
+        scene.zoomIn();
     }
 
     public void showPrevDiagram() {
@@ -370,11 +389,11 @@
     }
 
     public DiagramViewModel getModel() {
-        return scene.getModel();
+        return rangeSliderModel;
     }
 
     public FilterChain getFilterChain() {
-        return this.scene.getModel().getFilterChain();
+        return getModel().getFilterChain();
     }
 
     public static EditorTopComponent getActive() {
@@ -407,6 +426,7 @@
         // Variables declaration - do not modify//GEN-BEGIN:variables
         private javax.swing.JCheckBox jCheckBox1;
         // End of variables declaration//GEN-END:variables
+
     @Override
     public int getPersistenceType() {
         return TopComponent.PERSISTENCE_NEVER;
@@ -418,6 +438,7 @@
 
     @Override
     public void componentClosed() {
+        rangeSliderModel.close();
     }
 
     @Override
@@ -425,9 +446,18 @@
         return PREFERRED_ID;
     }
 
-    public void changed(RangeSliderModel model) {
-        updateDisplayName();
-    }
+    private ChangedListener<DiagramViewModel> diagramChangedListener = new ChangedListener<DiagramViewModel>() {
+
+        @Override
+        public void changed(DiagramViewModel source) {
+            updateDisplayName();
+            Collection<Object> list = new ArrayList<>();
+            list.add(new EditorInputGraphProvider(EditorTopComponent.this));
+            graphContent.set(list, null);
+            diagramProvider.getChangedEvent().fire();
+        }
+
+    };
 
     public boolean showPredSucc() {
         return (Boolean) predSuccAction.getValue(PredSuccAction.STATE);
@@ -435,24 +465,25 @@
 
     public void setSelection(PropertyMatcher matcher) {
 
-        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(scene.getModel().getDiagramToView().getFigures());
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<>(getModel().getDiagramToView().getFigures());
         List<Figure> list = selector.selectMultiple(matcher);
-        boolean b = scene.getUndoRedoEnabled();
-        scene.setUndoRedoEnabled(false);
-        scene.gotoFigures(list);
-        scene.setUndoRedoEnabled(b);
+        setSelectedFigures(list);
+    }
+
+    public void setSelectedFigures(List<Figure> list) {
         scene.setSelection(list);
+        scene.centerFigures(list);
     }
 
     public void setSelectedNodes(Set<InputNode> nodes) {
 
-        List<Figure> list = new ArrayList<Figure>();
-        Set<Integer> ids = new HashSet<Integer>();
+        List<Figure> list = new ArrayList<>();
+        Set<Integer> ids = new HashSet<>();
         for (InputNode n : nodes) {
             ids.add(n.getId());
         }
 
-        for (Figure f : scene.getModel().getDiagramToView().getFigures()) {
+        for (Figure f : getModel().getDiagramToView().getFigures()) {
             for (InputNode n : f.getSource().getSourceNodes()) {
                 if (ids.contains(n.getId())) {
                     list.add(f);
@@ -461,10 +492,10 @@
             }
         }
 
-        scene.gotoFigures(list);
-        scene.setSelection(list);
+        setSelectedFigures(list);
     }
 
+    @Override
     public void propertyChange(PropertyChangeEvent evt) {
         if (evt.getSource() == this.predSuccAction) {
             boolean b = (Boolean) predSuccAction.getValue(PredSuccAction.STATE);
@@ -478,27 +509,35 @@
             }
         } else if (evt.getSource() == this.blockLayoutAction) {
             boolean b = (Boolean) blockLayoutAction.getValue(EnableBlockLayoutAction.STATE);
-            System.out.println("Showblocks = " + b);
             this.getModel().setShowBlocks(b);
+        } else if (evt.getSource() == this.hideDuplicatesAction) {
+            boolean b = (Boolean) hideDuplicatesAction.getValue(HideDuplicatesAction.STATE);
+            this.getModel().setHideDuplicates(b);
+        } else if (evt.getSource() == this.selectionModeAction || evt.getSource() == this.panModeAction) {
+            if (panModeAction.isSelected()) {
+                scene.setInteractionMode(DiagramViewer.InteractionMode.PANNING);
+            } else if (selectionModeAction.isSelected()) {
+                scene.setInteractionMode(DiagramViewer.InteractionMode.SELECTION);
+            }
         } else {
             assert false : "Unknown event source";
         }
     }
 
     public void extract() {
-        scene.showOnly(scene.getSelectedNodes());
+        getModel().showOnly(getModel().getSelectedNodes());
     }
 
     public void hideNodes() {
-        Set<Integer> selectedNodes = this.scene.getSelectedNodes();
-        HashSet<Integer> nodes = new HashSet<Integer>(scene.getModel().getHiddenNodes());
+        Set<Integer> selectedNodes = this.getModel().getSelectedNodes();
+        HashSet<Integer> nodes = new HashSet<>(getModel().getHiddenNodes());
         nodes.addAll(selectedNodes);
-        this.scene.showNot(nodes);
+        this.getModel().showNot(nodes);
     }
 
     public void expandPredecessors() {
-        Set<Figure> oldSelection = scene.getSelectedFigures();
-        Set<Figure> figures = new HashSet<Figure>();
+        Set<Figure> oldSelection = getModel().getSelectedFigures();
+        Set<Figure> figures = new HashSet<>();
 
         for (Figure f : this.getDiagramModel().getDiagramToView().getFigures()) {
             boolean ok = false;
@@ -518,12 +557,12 @@
             }
         }
 
-        scene.showAll(figures);
+        getModel().showAll(figures);
     }
 
     public void expandSuccessors() {
-        Set<Figure> oldSelection = scene.getSelectedFigures();
-        Set<Figure> figures = new HashSet<Figure>();
+        Set<Figure> oldSelection = getModel().getSelectedFigures();
+        Set<Figure> figures = new HashSet<>();
 
         for (Figure f : this.getDiagramModel().getDiagramToView().getFigures()) {
             boolean ok = false;
@@ -543,11 +582,11 @@
             }
         }
 
-        scene.showAll(figures);
+        getModel().showAll(figures);
     }
 
     public void showAll() {
-        scene.showNot(new HashSet<Integer>());
+        getModel().showNot(new HashSet<Integer>());
     }
 
     public Diagram getDiagram() {
@@ -555,23 +594,31 @@
     }
 
     @Override
-    protected void componentActivated() {
+    protected void componentHidden() {
+        super.componentHidden();
+        scene.componentHidden();
+
     }
 
     @Override
-    public void requestFocus() {
-        super.requestFocus();
-        scene.getView().requestFocus();
+    protected void componentShowing() {
+        super.componentShowing();
+        scene.componentShowing();
     }
 
     @Override
-    public boolean requestFocusInWindow() {
-        super.requestFocusInWindow();
-        return scene.getView().requestFocusInWindow();
+    public void requestActive() {
+        super.requestActive();
+        scene.getComponent().requestFocus();
     }
 
     @Override
     public UndoRedo getUndoRedo() {
         return scene.getUndoRedo();
     }
+
+    @Override
+    protected Object writeReplace() throws ObjectStreamException {
+        throw new NotSerializableException();
 }
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExportCookie.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExportCookie.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedPanAction.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,131 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view;
-
-import java.awt.Container;
-import java.awt.Dimension;
-import java.awt.Point;
-import org.netbeans.api.visual.widget.Scene;
-import org.netbeans.api.visual.widget.Widget;
-import org.netbeans.api.visual.action.WidgetAction;
-
-import java.awt.event.MouseEvent;
-import javax.swing.JComponent;
-import javax.swing.JScrollPane;
-import javax.swing.SwingUtilities;
-
-/**
- * @author David Kaspar
- * @author Thomas Wuerthinger
- */
-public class ExtendedPanAction extends WidgetAction.LockedAdapter {
-
-    private Scene scene;
-    private JScrollPane scrollPane;
-    private Point lastLocation;
-
-    protected boolean isLocked() {
-        return scrollPane != null;
-    }
-
-    @Override
-    public State mousePressed(Widget widget, WidgetMouseEvent event) {
-        if (event.getButton() == MouseEvent.BUTTON2 || event.getButton() == MouseEvent.BUTTON1 && ((event.getModifiers() & MouseEvent.CTRL_MASK) != 0)) {
-            scene = widget.getScene();
-            scrollPane = findScrollPane(scene.getView());
-            if (scrollPane != null) {
-                lastLocation = scene.convertSceneToView(widget.convertLocalToScene(event.getPoint()));
-                SwingUtilities.convertPointToScreen(lastLocation, scrollPane.getViewport().getView());
-                return State.createLocked(widget, this);
-            }
-        }
-        return State.REJECTED;
-    }
-
-    private JScrollPane findScrollPane(JComponent component) {
-        for (;;) {
-            if (component == null) {
-                return null;
-            }
-            if (component instanceof JScrollPane) {
-                return ((JScrollPane) component);
-            }
-            Container parent = component.getParent();
-            if (!(parent instanceof JComponent)) {
-                return null;
-            }
-            component = (JComponent) parent;
-        }
-    }
-
-    @Override
-    public State mouseReleased(Widget widget, WidgetMouseEvent event) {
-        boolean state = pan(widget, event.getPoint());
-        if (state) {
-            scrollPane = null;
-        }
-        return state ? State.createLocked(widget, this) : State.REJECTED;
-    }
-
-    @Override
-    public State mouseDragged(Widget widget, WidgetMouseEvent event) {
-        return pan(widget, event.getPoint()) ? State.createLocked(widget, this) : State.REJECTED;
-    }
-
-    private boolean pan(Widget widget, Point newLocation) {
-        if (scrollPane == null || scene != widget.getScene()) {
-            return false;
-        }
-        newLocation = scene.convertSceneToView(widget.convertLocalToScene(newLocation));
-        SwingUtilities.convertPointToScreen(newLocation, scrollPane.getViewport().getView());
-        Point viewPosition = scrollPane.getViewport().getViewPosition();
-        Dimension viewSize = scrollPane.getViewport().getViewSize();
-        Dimension viewPortSize = scrollPane.getViewport().getSize();
-
-        int xOffset = lastLocation.x - newLocation.x;
-        int yOffset = lastLocation.y - newLocation.y;
-
-        if (viewPortSize.height == viewSize.height) {
-            yOffset = 0;
-        }
-
-        if (viewPortSize.width == viewSize.width) {
-            xOffset = 0;
-        }
-
-        if (xOffset == 0 && yOffset == 0) {
-            return true;
-        }
-        viewPosition = new Point(viewPosition.x + xOffset, viewPosition.y + yOffset);
-        viewPosition.x = Math.max(viewPosition.x, 0);
-        viewPosition.y = Math.max(viewPosition.y, 0);
-        viewPosition.x = Math.min(viewPosition.x, scrollPane.getViewport().getView().getSize().width - scrollPane.getViewport().getSize().width);
-        viewPosition.y = Math.min(viewPosition.y, scrollPane.getViewport().getView().getSize().height - scrollPane.getViewport().getSize().height);
-
-        scrollPane.getViewport().setViewPosition(viewPosition);
-        scrollPane.getViewport().getView().repaint();
-        lastLocation = newLocation;
-        return true;
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedSatelliteComponent.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedSatelliteComponent.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,11 +23,10 @@
  */
 package com.sun.hotspot.igv.view;
 
-import org.netbeans.api.visual.widget.Scene;
-
-import javax.swing.*;
 import java.awt.*;
 import java.awt.event.*;
+import javax.swing.JComponent;
+import org.netbeans.api.visual.widget.Scene;
 
 /**
  * @author David Kaspar
@@ -48,6 +47,7 @@
         addMouseMotionListener(this);
     }
 
+    @Override
     public void addNotify() {
         super.addNotify();
         scene.addSceneListener(this);
@@ -59,6 +59,7 @@
         repaint();
     }
 
+    @Override
     public void removeNotify() {
         scene.getView().removeComponentListener(this);
         scene.removeSceneListener(this);
@@ -74,6 +75,7 @@
         }
     }
 
+    @Override
     public void paint(Graphics g) {
         Graphics2D gr = (Graphics2D) g;
         super.paint(g);
@@ -91,15 +93,15 @@
 
 
         if (image == null || vw != imageWidth || vh != imageHeight) {
-
             imageWidth = vw;
             imageHeight = vh;
             image = this.createImage(imageWidth, imageHeight);
             Graphics2D ig = (Graphics2D) image.getGraphics();
             ig.scale(scale, scale);
-            scene.setRealZoomFactor(scale);
+            double oldFactor = scene.getZoomFactor();
+            scene.setZoomFactor(scale);
             scene.paint(ig);
-            scene.setRealZoomFactor(0.0);
+            scene.setZoomFactor(oldFactor);
         }
 
         gr.drawImage(image, vx, vy, this);
@@ -121,27 +123,34 @@
         }
     }
 
+    @Override
     public void mouseClicked(MouseEvent e) {
     }
 
+    @Override
     public void mousePressed(MouseEvent e) {
         moveVisibleRect(e.getPoint());
     }
 
+    @Override
     public void mouseReleased(MouseEvent e) {
         moveVisibleRect(e.getPoint());
     }
 
+    @Override
     public void mouseEntered(MouseEvent e) {
     }
 
+    @Override
     public void mouseExited(MouseEvent e) {
     }
 
+    @Override
     public void mouseDragged(MouseEvent e) {
         moveVisibleRect(e.getPoint());
     }
 
+    @Override
     public void mouseMoved(MouseEvent e) {
     }
 
@@ -174,27 +183,34 @@
         this.repaint();
     }
 
+    @Override
     public void sceneRepaint() {
     //repaint ();
     }
 
+    @Override
     public void sceneValidating() {
     }
 
+    @Override
     public void sceneValidated() {
     }
 
+    @Override
     public void componentResized(ComponentEvent e) {
         repaint();
     }
 
+    @Override
     public void componentMoved(ComponentEvent e) {
         repaint();
     }
 
+    @Override
     public void componentShown(ComponentEvent e) {
     }
 
+    @Override
     public void componentHidden(ComponentEvent e) {
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/FindPanel.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,111 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view;
-
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.data.Properties;
-import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
-import com.sun.hotspot.igv.data.Property;
-import java.awt.GridLayout;
-import java.awt.event.KeyEvent;
-import java.awt.event.KeyListener;
-import java.util.List;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import javax.swing.JComboBox;
-import javax.swing.JPanel;
-import javax.swing.JTextField;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-class FindPanel extends JPanel implements KeyListener {
-
-    private JComboBox nameComboBox;
-    private JTextField valueTextField;
-
-    public FindPanel(List<Figure> figures) {
-        createDesign();
-        updateComboBox(figures);
-    }
-
-    protected void createDesign() {
-        setLayout(new GridLayout());
-        nameComboBox = new JComboBox();
-        valueTextField = new JTextField();
-        add(nameComboBox);
-        add(valueTextField);
-        valueTextField.addKeyListener(this);
-    }
-
-    public void updateComboBox(List<Figure> figures) {
-
-        String sel = (String) nameComboBox.getSelectedItem();
-        SortedSet<String> propertyNames = new TreeSet<String>();
-
-        for (Figure f : figures) {
-            Properties prop = f.getProperties();
-            for (Property p : prop) {
-                if (!propertyNames.contains(p.getName())) {
-                    propertyNames.add(p.getName());
-                }
-            }
-        }
-
-        for (String s : propertyNames) {
-            nameComboBox.addItem(s);
-        }
-        nameComboBox.setSelectedItem(sel);
-    }
-
-    public String getNameText() {
-        return (String) nameComboBox.getSelectedItem();
-    }
-
-    public String getValueText() {
-        return valueTextField.getText();
-    }
-
-    public void keyTyped(KeyEvent e) {
-    }
-
-    public void keyPressed(KeyEvent e) {
-        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
-            find();
-        }
-    }
-
-    public void find() {
-        EditorTopComponent comp = EditorTopComponent.getActive();
-        if (comp != null) {
-            RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(getNameText(), getValueText());
-            comp.setSelection(matcher);
-        }
-    }
-
-    public void keyReleased(KeyEvent e) {
-
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/GraphViewerImplementation.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/GraphViewerImplementation.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,9 @@
 import com.sun.hotspot.igv.data.services.GraphViewer;
 import com.sun.hotspot.igv.graph.Diagram;
 import com.sun.hotspot.igv.settings.Settings;
+import org.openide.windows.Mode;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
 
 /**
  *
@@ -34,7 +37,25 @@
  */
 public class GraphViewerImplementation implements GraphViewer {
 
-    public void view(InputGraph graph) {
+    @Override
+    public void view(InputGraph graph, boolean clone) {
+
+        if (!clone) {
+            WindowManager manager = WindowManager.getDefault();
+            for (Mode m : manager.getModes()) {
+                for (TopComponent t : manager.getOpenedTopComponents(m)) {
+                    if (t instanceof EditorTopComponent) {
+                        EditorTopComponent etc = (EditorTopComponent) t;
+                        if (etc.getModel().getGroup().getGraphs().contains(graph)) {
+                            etc.getModel().selectGraph(graph);
+                            t.requestActive();
+                            return;
+                        }
+                    }
+                }
+            }
+        }
+
         Diagram diagram = Diagram.createDiagram(graph, Settings.get().get(Settings.NODE_TEXT, Settings.NODE_TEXT_DEFAULT));
         EditorTopComponent tc = new EditorTopComponent(diagram);
         tc.open();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/NodeQuickSearch.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.view;
+
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.util.LookupHistory;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Pattern;
+import org.netbeans.spi.quicksearch.SearchProvider;
+import org.netbeans.spi.quicksearch.SearchRequest;
+import org.netbeans.spi.quicksearch.SearchResponse;
+import org.openide.DialogDisplayer;
+import org.openide.NotifyDescriptor;
+import org.openide.NotifyDescriptor.Message;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class NodeQuickSearch implements SearchProvider {
+
+    private static final String DEFAULT_PROPERTY = "name";
+
+    /**
+     * Method is called by infrastructure when search operation was requested.
+     * Implementors should evaluate given request and fill response object with
+     * apropriate results
+     *
+     * @param request Search request object that contains information what to search for
+     * @param response Search response object that stores search results. Note that it's important to react to return value of SearchResponse.addResult(...) method and stop computation if false value is returned.
+     */
+    @Override
+    public void evaluate(SearchRequest request, SearchResponse response) {
+        String query = request.getText();
+        if (query.trim().isEmpty()) {
+            return;
+        }
+
+        final String[] parts = query.split("=", 2);
+
+        String name;
+        String value;
+
+        if (parts.length == 1) {
+            name = DEFAULT_PROPERTY;
+            value = ".*" + Pattern.quote(parts[0]) + ".*";
+        } else {
+            name = parts[0];
+            value = parts[1];
+        }
+
+        if (value.isEmpty()) {
+            value = ".*";
+        }
+
+        final InputGraphProvider p = LookupHistory.getLast(InputGraphProvider.class);
+        if (p != null && p.getGraph() != null) {
+            List<InputNode> matches = null;
+            try {
+                RegexpPropertyMatcher matcher = new RegexpPropertyMatcher(name, value, Pattern.CASE_INSENSITIVE);
+                Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<>(p.getGraph().getNodes());
+
+                matches = selector.selectMultiple(matcher);
+            } catch (Exception e) {
+                final String msg = e.getMessage();
+                response.addResult(new Runnable() {
+                    @Override
+                        public void run() {
+                            Message desc = new NotifyDescriptor.Message("An exception occurred during the search, "
+                                    + "perhaps due to a malformed query string:\n" + msg,
+                                    NotifyDescriptor.WARNING_MESSAGE);
+                            DialogDisplayer.getDefault().notify(desc);
+                        }
+                    },
+                    "(Error during search)"
+                );
+            }
+
+            if (matches != null) {
+                final Set<InputNode> set = new HashSet<>(matches);
+                response.addResult(new Runnable() {
+                    @Override
+                        public void run() {
+                            final EditorTopComponent comp = EditorTopComponent.getActive();
+                            if (comp != null) {
+                                comp.setSelectedNodes(set);
+                                comp.requestActive();
+                            }
+                        }
+                    },
+                    "All " + matches.size() + " matching nodes (" + name + "=" + value + ")"
+                );
+
+                // Single matches
+                for (final InputNode n : matches) {
+                    response.addResult(new Runnable() {
+                        @Override
+                            public void run() {
+                                final EditorTopComponent comp = EditorTopComponent.getActive();
+                                if (comp != null) {
+                                    final Set<InputNode> tmpSet = new HashSet<>();
+                                    tmpSet.add(n);
+                                    comp.setSelectedNodes(tmpSet);
+                                    comp.requestActive();
+                                }
+                            }
+                        },
+                        n.getProperties().get(name) + " (" + n.getId() + " " + n.getProperties().get("name") + ")"
+                    );
+                }
+            }
+        } else {
+            System.out.println("no input graph provider!");
+        }
+    }
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/PreferenceConstants.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class PreferenceConstants {
-
-    public static final String KEY_LINE_GENERATOR = "lineGenerator";
-    public static final String DEFAULT_LINE_GENERATOR = "com.sun.hotspot.igv.positioning.BasicLineGenerator";
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/SlotLayout.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,171 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view;
-
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.util.Collection;
-import java.util.List;
-import org.netbeans.api.visual.layout.Layout;
-import org.netbeans.api.visual.layout.LayoutFactory;
-import org.netbeans.api.visual.widget.Widget;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class SlotLayout implements Layout {
-
-    public enum HorizontalAlignment {
-
-        Left,
-        Center,
-        Right
-    }
-    private Layout baseLayout;
-    private HorizontalAlignment alignment;
-    private boolean vertical;
-
-    public SlotLayout() {
-        this(HorizontalAlignment.Center, false);
-    }
-
-    public SlotLayout(HorizontalAlignment alignment, boolean vertical) {
-        this.alignment = alignment;
-        baseLayout = LayoutFactory.createVerticalFlowLayout();
-        this.vertical = vertical;
-    }
-
-    public void layout(Widget widget) {
-        if (!vertical) {
-            Collection<Widget> children = widget.getChildren();
-            int gap = 0;
-            int max = 0;
-            for (Widget child : children) {
-                Rectangle preferredBounds = child.getPreferredBounds();
-                int i = preferredBounds.width;
-                if (i > max) {
-                    max = i;
-                }
-            }
-            int pos = 0;
-            for (Widget child : children) {
-                Rectangle preferredBounds = child.getPreferredBounds();
-                int x = preferredBounds.x;
-                int y = preferredBounds.y;
-                int width = preferredBounds.width;
-                int height = preferredBounds.height;
-                if (pos == 0) {
-                    pos += height / 2;
-                }
-                int lx = -x;
-                int ly = pos - y;
-                switch (alignment) {
-                    case Center:
-                        lx += (max - width) / 2;
-                        break;
-                    case Left:
-                        break;
-                    case Right:
-                        lx += max - width;
-                        break;
-                }
-                child.resolveBounds(new Point(lx, ly), new Rectangle(x, y, width, height));
-                pos += height + gap;
-            }
-        } else {
-
-            Collection<Widget> children = widget.getChildren();
-            int gap = 0;
-            int max = 0;
-            for (Widget child : children) {
-                Rectangle preferredBounds = child.getPreferredBounds();
-                int i = preferredBounds.height;
-                if (i > max) {
-                    max = i;
-                }
-            }
-            int pos = 0;
-            for (Widget child : children) {
-                Rectangle preferredBounds = child.getPreferredBounds();
-                int x = preferredBounds.x;
-                int y = preferredBounds.y;
-                int width = preferredBounds.width;
-                int height = preferredBounds.height;
-                if (pos == 0) {
-                    pos += width / 2;
-                }
-                int lx = pos - x;
-                int ly = -y;
-                switch (alignment) {
-                    case Center:
-                        ly += (max - height) / 2;
-                        break;
-                    case Left:
-                        break;
-                    case Right:
-                        ly += max - height;
-                        break;
-                }
-                child.resolveBounds(new Point(lx, ly), new Rectangle(x, y, width, height));
-                pos += width + gap;
-            }
-
-        }
-    }
-
-    public boolean requiresJustification(Widget widget) {
-        return true;
-    }
-
-    public void justify(Widget widget) {
-        baseLayout.justify(widget);
-
-        Rectangle client = widget.getClientArea();
-        List<Widget> children = widget.getChildren();
-
-        int count = children.size();
-        int z = 0;
-
-        int maxWidth = 0;
-        for (Widget c : children) {
-            if (c.getPreferredBounds().width > maxWidth) {
-                maxWidth = c.getPreferredBounds().width;
-            }
-        }
-
-        for (Widget c : children) {
-            z++;
-            Point curLocation = c.getLocation();
-            Rectangle curBounds = c.getBounds();
-
-
-            Point location = new Point(curLocation.x, client.y + client.height * z / (count + 1) - curBounds.height / 2);
-            if (vertical) {
-                location = new Point(client.x + client.width * z / (count + 1) - maxWidth / 2, curLocation.y);
-            }
-            c.resolveBounds(location, null);
-        }
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/Bundle.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/Bundle.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,7 +1,6 @@
 CTL_EditorAction=Open Editor Window
-CTL_LineGeneratorAction=Line Generator
 CTL_NextDiagramAction=Show next graph
 CTL_EnableBlockLayoutAction=Enable block layout
 CTL_NodeFindAction=Find
 CTL_PrevDiagramAction=Show previous graph
-CTL_ExportAction=Export...
+CTL_ExportAction=Export current graph...
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/CustomizablePanAction.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,146 @@
+/*
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
+ *
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
+ * Other names may be trademarks of their respective owners.
+ *
+ * The contents of this file are subject to the terms of either the GNU
+ * General Public License Version 2 only ("GPL") or the Common
+ * Development and Distribution License("CDDL") (collectively, the
+ * "License"). You may not use this file except in compliance with the
+ * License. You can obtain a copy of the License at
+ * http://www.netbeans.org/cddl-gplv2.html
+ * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
+ * specific language governing permissions and limitations under the
+ * License.  When distributing the software, include this License Header
+ * Notice in each file and include the License file at
+ * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the GPL Version 2 section of the License file that
+ * accompanied this code. If applicable, add the following below the
+ * License Header, with the fields enclosed by brackets [] replaced by
+ * your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * Contributor(s):
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ *
+ * If you wish your version of this file to be governed by only the CDDL
+ * or only the GPL Version 2, indicate your decision by adding
+ * "[Contributor] elects to include this software in this distribution
+ * under the [CDDL or GPL Version 2] license." If you do not indicate a
+ * single choice of license, a recipient has the option to distribute
+ * your version of this file under either the CDDL, the GPL Version 2 or
+ * to extend the choice of license to its licensees as provided above.
+ * However, if you add GPL Version 2 code and therefore, elected the GPL
+ * Version 2 license, then the option applies only if the new code is
+ * made subject to such option by the copyright holder.
+ */
+package com.sun.hotspot.igv.view.actions;
+
+import java.awt.Container;
+import java.awt.Point;
+import java.awt.Rectangle;
+import javax.swing.JComponent;
+import javax.swing.JScrollPane;
+import javax.swing.SwingUtilities;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.action.WidgetAction.State;
+import org.netbeans.api.visual.action.WidgetAction.WidgetMouseEvent;
+import org.netbeans.api.visual.widget.Scene;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ * @author David Kaspar
+ * @author Peter Hofer
+ */
+public class CustomizablePanAction extends WidgetAction.LockedAdapter {
+    private boolean enabled = true;
+
+    private Scene scene;
+    private JScrollPane scrollPane;
+    private Point lastLocation;
+
+    private final int modifiersExMask;
+    private final int modifiersEx;
+
+    public CustomizablePanAction(int modifiersExMask, int modifiersEx) {
+        this.modifiersExMask = modifiersExMask;
+        this.modifiersEx = modifiersEx;
+    }
+
+    @Override
+    protected boolean isLocked() {
+        return scrollPane != null;
+    }
+
+    public void setEnabled(boolean enabled) {
+        if (this.enabled != enabled) {
+            if (isLocked())
+                throw new IllegalStateException();
+
+            this.enabled = enabled;
+        }
+    }
+
+    @Override
+    public State mousePressed (Widget widget, WidgetMouseEvent event) {
+        if (isLocked ())
+            return State.createLocked (widget, this);
+        if (enabled && (event.getModifiersEx() & modifiersExMask) == modifiersEx) {
+            scene = widget.getScene ();
+            scrollPane = findScrollPane (scene.getView ());
+            if (scrollPane != null) {
+                lastLocation = scene.convertSceneToView (widget.convertLocalToScene (event.getPoint ()));
+                SwingUtilities.convertPointToScreen (lastLocation, scene.getView ());
+                return State.createLocked (widget, this);
+            }
+        }
+        return State.REJECTED;
+    }
+
+    private JScrollPane findScrollPane (JComponent component) {
+        for (;;) {
+            if (component == null)
+                return null;
+            if (component instanceof JScrollPane)
+                return ((JScrollPane) component);
+            Container parent = component.getParent ();
+            if (! (parent instanceof JComponent))
+                return null;
+            component = (JComponent) parent;
+        }
+    }
+
+    @Override
+    public State mouseReleased (Widget widget, WidgetMouseEvent event) {
+        boolean state = pan (widget, event.getPoint ());
+        if (state)
+            scrollPane = null;
+        return state ? State.createLocked (widget, this) : State.REJECTED;
+    }
+
+    @Override
+    public State mouseDragged (Widget widget, WidgetMouseEvent event) {
+        return pan (widget, event.getPoint ()) ? State.createLocked (widget, this) : State.REJECTED;
+    }
+
+    private boolean pan (Widget widget, Point newLocation) {
+        if (scrollPane == null  ||  scene != widget.getScene ())
+            return false;
+        newLocation = scene.convertSceneToView (widget.convertLocalToScene (newLocation));
+        SwingUtilities.convertPointToScreen (newLocation, scene.getView ());
+        JComponent view = scene.getView ();
+        Rectangle rectangle = view.getVisibleRect ();
+        rectangle.x += lastLocation.x - newLocation.x;
+        rectangle.y += lastLocation.y - newLocation.y;
+        view.scrollRectToVisible (rectangle);
+        lastLocation = newLocation;
+        return true;
+    }
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/EnableBlockLayoutAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/EnableBlockLayoutAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 import javax.swing.AbstractAction;
 import javax.swing.Action;
 import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
 
 /**
  *
@@ -38,9 +39,9 @@
     public static final String STATE = "state";
 
     public EnableBlockLayoutAction() {
-        state = true;
-        putValue(AbstractAction.SMALL_ICON, new ImageIcon(org.openide.util.Utilities.loadImage(iconResource())));
-        putValue(STATE, true);
+        state = false;
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
+        putValue(STATE, state);
         putValue(Action.SHORT_DESCRIPTION, "Cluster nodes into blocks");
     }
 
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
  */
 public final class ExpandPredecessorsAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -40,8 +41,9 @@
         }
     }
 
+    @Override
     public String getName() {
-        return "Expand Predecessors";
+        return "Expand Above";
     }
 
     @Override
@@ -49,6 +51,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
  */
 public final class ExpandSuccessorsAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -40,8 +41,9 @@
         }
     }
 
+    @Override
     public String getName() {
-        return "Expand Successors";
+        return "Expand Below";
     }
 
     @Override
@@ -49,6 +51,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExportAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExportAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,12 +32,7 @@
 import javax.swing.JFileChooser;
 import javax.swing.KeyStroke;
 import javax.swing.filechooser.FileFilter;
-import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
-import org.openide.util.LookupEvent;
-import org.openide.util.LookupListener;
-import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
+import org.openide.util.*;
 import org.openide.util.actions.CallableSystemAction;
 
 /**
@@ -50,27 +45,31 @@
     private final Lookup.Result<ExportCookie> result;
 
     public ExportAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Export current graph as an SVG file");
+        putValue(Action.SHORT_DESCRIPTION, "Export current graph as SVG file");
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.CTRL_MASK));
         lookup = Utilities.actionsGlobalContext();
-        result = lookup.lookup(new Lookup.Template<ExportCookie>(ExportCookie.class));
+        result = lookup.lookup(new Lookup.Template<>(ExportCookie.class));
         result.addLookupListener(this);
         resultChanged(null);
     }
 
+    @Override
     public void resultChanged(LookupEvent e) {
         super.setEnabled(result.allInstances().size() > 0);
     }
 
+    @Override
     public void performAction() {
 
         JFileChooser fc = new JFileChooser();
         fc.setFileFilter(new FileFilter() {
 
+            @Override
             public boolean accept(File f) {
                 return true;
             }
 
+            @Override
             public String getDescription() {
                 return "SVG files (*.svg)";
             }
@@ -97,15 +96,17 @@
         }
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(ExportAction.class, "CTL_ExportAction");
     }
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/view/images/export.gif";
+        return "com/sun/hotspot/igv/view/images/export.png";
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExtractAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExtractAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
  */
 public final class ExtractAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -49,6 +50,7 @@
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_X, Event.CTRL_MASK, false));
     }
 
+    @Override
     public String getName() {
         return "Extract action";
     }
@@ -58,6 +60,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/HideAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/HideAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
  */
 public final class HideAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -49,6 +50,7 @@
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_H, Event.CTRL_MASK, false));
     }
 
+    @Override
     public String getName() {
         return "Hide";
     }
@@ -58,6 +60,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/HideDuplicatesAction.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2014, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.view.actions;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
+
+/**
+ *
+ * @author Tom Rodriguez
+ */
+public class HideDuplicatesAction extends AbstractAction {
+
+    private boolean state;
+    public static final String STATE = "state";
+
+    public HideDuplicatesAction() {
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
+        putValue(Action.SHORT_DESCRIPTION, "Hide graphs which are the same as the previous graph");
+        setState(false);
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent ev) {
+        setState(!state);
+    }
+
+    public void setState(boolean b) {
+        this.putValue(STATE, b);
+        this.state = b;
+    }
+
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/hideDuplicates.png";
+    }
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/MouseOverAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/MouseOverAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/NextDiagramAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/NextDiagramAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,15 +23,12 @@
  */
 package com.sun.hotspot.igv.view.actions;
 
-import com.sun.hotspot.igv.view.DiagramViewModel;
 import com.sun.hotspot.igv.data.ChangedListener;
 import com.sun.hotspot.igv.util.ContextAction;
+import com.sun.hotspot.igv.view.DiagramViewModel;
 import javax.swing.Action;
 import javax.swing.ImageIcon;
-import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
-import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
+import org.openide.util.*;
 
 /**
  *
@@ -47,13 +44,15 @@
 
     public NextDiagramAction(Lookup lookup) {
         putValue(Action.SHORT_DESCRIPTION, "Show next graph of current group");
-        putValue(Action.SMALL_ICON, new ImageIcon(Utilities.loadImage("com/sun/hotspot/igv/view/images/next_diagram.png")));
+        putValue(Action.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage("com/sun/hotspot/igv/view/images/next_diagram.png")));
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(NextDiagramAction.class, "CTL_NextDiagramAction");
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -95,10 +94,12 @@
         return model.getSecondPosition() != model.getPositions().size() - 1;
     }
 
+    @Override
     public Action createContextAwareInstance(Lookup arg0) {
         return new NextDiagramAction(arg0);
     }
 
+    @Override
     public void changed(DiagramViewModel source) {
         update(source);
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/NodeFindAction.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view.actions;
-
-import com.sun.hotspot.igv.view.EditorTopComponent;
-import javax.swing.Action;
-import org.openide.util.HelpCtx;
-import org.openide.util.NbBundle;
-import org.openide.util.actions.CallableSystemAction;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public final class NodeFindAction extends CallableSystemAction {
-
-    public void performAction() {
-        EditorTopComponent comp = EditorTopComponent.getActive();
-        if (comp != null) {
-            comp.findNode();
-        }
-    }
-
-    public NodeFindAction() {
-        putValue(Action.SHORT_DESCRIPTION, "Find nodes");
-    }
-
-    public String getName() {
-        return NbBundle.getMessage(NodeFindAction.class, "CTL_NodeFindAction");
-    }
-
-    public HelpCtx getHelpCtx() {
-        return HelpCtx.DEFAULT_HELP;
-    }
-
-    @Override
-    protected boolean asynchronous() {
-        return false;
-    }
-
-    @Override
-    public boolean isEnabled() {
-        return true;
-    }
-
-    @Override
-    protected String iconResource() {
-        return "com/sun/hotspot/igv/view/images/search.gif";
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/OverviewAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/OverviewAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 import javax.swing.AbstractAction;
 import javax.swing.Action;
 import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
 
 /**
  *
@@ -38,11 +39,12 @@
     public static final String STATE = "state";
 
     public OverviewAction() {
-        putValue(AbstractAction.SMALL_ICON, new ImageIcon(org.openide.util.Utilities.loadImage(iconResource())));
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
         putValue(Action.SHORT_DESCRIPTION, "Show satellite view of whole graph");
         setState(false);
     }
 
+    @Override
     public void actionPerformed(ActionEvent ev) {
         setState(!state);
     }
@@ -53,6 +55,6 @@
     }
 
     protected String iconResource() {
-        return "com/sun/hotspot/igv/view/images/overview.gif";
+        return "com/sun/hotspot/igv/view/images/overview.png";
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PanModeAction.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.view.actions;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
+
+public class PanModeAction extends AbstractAction {
+
+    private boolean state;
+
+    public PanModeAction() {
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
+        putValue(SELECTED_KEY, false);
+        putValue(Action.SHORT_DESCRIPTION, "Panning mode");
+    }
+
+    public boolean isSelected() {
+        return (Boolean)getValue(SELECTED_KEY);
+    }
+
+    public void setSelected(boolean b) {
+        if (isSelected() != b) {
+            this.putValue(SELECTED_KEY, b);
+        }
+    }
+
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/pan_mode.png";
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+    }
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PredSuccAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PredSuccAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 import javax.swing.AbstractAction;
 import javax.swing.Action;
 import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
 
 /**
  *
@@ -39,11 +40,12 @@
 
     public PredSuccAction() {
         state = true;
-        putValue(AbstractAction.SMALL_ICON, new ImageIcon(org.openide.util.Utilities.loadImage(iconResource())));
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
         putValue(STATE, true);
         putValue(Action.SHORT_DESCRIPTION, "Show neighboring nodes of fully visible nodes semi-transparent");
     }
 
+    @Override
     public void actionPerformed(ActionEvent ev) {
         this.state = !state;
         this.putValue(STATE, state);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PrevDiagramAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PrevDiagramAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,14 +24,11 @@
 package com.sun.hotspot.igv.view.actions;
 
 import com.sun.hotspot.igv.data.ChangedListener;
+import com.sun.hotspot.igv.util.ContextAction;
 import com.sun.hotspot.igv.view.DiagramViewModel;
-import com.sun.hotspot.igv.util.ContextAction;
 import javax.swing.Action;
 import javax.swing.ImageIcon;
-import org.openide.util.HelpCtx;
-import org.openide.util.Lookup;
-import org.openide.util.NbBundle;
-import org.openide.util.Utilities;
+import org.openide.util.*;
 
 /**
  *
@@ -47,13 +44,15 @@
 
     public PrevDiagramAction(Lookup lookup) {
         putValue(Action.SHORT_DESCRIPTION, "Show previous graph of current group");
-        putValue(Action.SMALL_ICON, new ImageIcon(Utilities.loadImage("com/sun/hotspot/igv/view/images/prev_diagram.png")));
+        putValue(Action.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage("com/sun/hotspot/igv/view/images/prev_diagram.png")));
     }
 
+    @Override
     public String getName() {
         return NbBundle.getMessage(PrevDiagramAction.class, "CTL_PrevDiagramAction");
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -95,10 +94,12 @@
         return model.getFirstPosition() != 0;
     }
 
+    @Override
     public Action createContextAwareInstance(Lookup arg0) {
         return new PrevDiagramAction(arg0);
     }
 
+    @Override
     public void changed(DiagramViewModel source) {
         update(source);
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/SelectionModeAction.java	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+package com.sun.hotspot.igv.view.actions;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import org.openide.util.ImageUtilities;
+
+public class SelectionModeAction extends AbstractAction {
+
+    public SelectionModeAction() {
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource())));
+        putValue(SELECTED_KEY, false);
+        putValue(Action.SHORT_DESCRIPTION, "Selection mode");
+    }
+
+    public boolean isSelected() {
+        return (Boolean)getValue(SELECTED_KEY);
+    }
+
+    public void setSelected(boolean b) {
+        if (isSelected() != b) {
+            this.putValue(SELECTED_KEY, b);
+        }
+    }
+
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/selection_mode.png";
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+    }
+}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ShowAllAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ShowAllAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
  */
 package com.sun.hotspot.igv.view.actions;
 
-import com.sun.hotspot.igv.view.*;
+import com.sun.hotspot.igv.view.EditorTopComponent;
 import java.awt.event.InputEvent;
 import java.awt.event.KeyEvent;
 import javax.swing.Action;
@@ -37,6 +37,7 @@
  */
 public final class ShowAllAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -49,6 +50,7 @@
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK));
     }
 
+    @Override
     public String getName() {
         return "Show all";
     }
@@ -58,6 +60,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ZoomInAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ZoomInAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
  */
 public final class ZoomInAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -44,6 +45,7 @@
         }
     }
 
+    @Override
     public String getName() {
         return "Zoom in";
     }
@@ -53,6 +55,7 @@
         putValue(Action.SHORT_DESCRIPTION, "Zoom in");
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -64,6 +67,6 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/view/images/zoomin.gif";
+        return "com/sun/hotspot/igv/view/images/zoom_in.png";
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ZoomOutAction.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ZoomOutAction.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -37,6 +37,7 @@
  */
 public final class ZoomOutAction extends CallableSystemAction {
 
+    @Override
     public void performAction() {
         EditorTopComponent editor = EditorTopComponent.getActive();
         if (editor != null) {
@@ -50,6 +51,7 @@
         putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, Event.CTRL_MASK, false));
     }
 
+    @Override
     public String getName() {
         return "Zoom out";
     }
@@ -59,6 +61,7 @@
         super.initialize();
     }
 
+    @Override
     public HelpCtx getHelpCtx() {
         return HelpCtx.DEFAULT_HELP;
     }
@@ -70,6 +73,6 @@
 
     @Override
     protected String iconResource() {
-        return "com/sun/hotspot/igv/view/images/zoomout.gif";
+        return "com/sun/hotspot/igv/view/images/zoom_out.png";
     }
 }
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/export.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/export.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/hideDuplicates.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/overview.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/overview.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/pan_mode.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/search.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/selection_mode.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoom_in.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoom_out.png has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoomin.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoomout.gif has changed
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml	Tue May 05 19:27:08 2015 +0200
@@ -24,36 +24,65 @@
         <folder name="View">
             <file name="com-sun-hotspot-igv-view-actions-PrevDiagramAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-PrevDiagramAction.instance"/>
+                <attr name="position" intvalue="100"/>
             </file>
             <file name="com-sun-hotspot-igv-view-actions-NextDiagramAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-NextDiagramAction.instance"/>
+                <attr name="position" intvalue="150"/>
             </file>
             <file name="com-sun-hotspot-igv-view-actions-ShowAllAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-ShowAllAction.instance"/>
+                <attr name="position" intvalue="200"/>
             </file>
             <file name="com-sun-hotspot-igv-view-actions-ExtractAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-ExtractAction.instance"/>
+                <attr name="position" intvalue="300"/>
             </file>
             <file name="com-sun-hotspot-igv-view-actions-HideAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-HideAction.instance"/>
+                <attr name="position" intvalue="400"/>
             </file>
             <file name="com-sun-hotspot-igv-view-actions-ZoomInAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-ZoomInAction.instance"/>
+                <attr name="position" intvalue="500"/>
             </file>
             <file name="com-sun-hotspot-igv-view-actions-ZoomOutAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/View/com-sun-hotspot-igv-view-actions-ZoomOutAction.instance"/>
+                <attr name="position" intvalue="550"/>
             </file>
         </folder>
         <folder name="File">
+            <file name="ExportActionSeparator.instance">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="700"/>
+            </file>
             <file name="com-sun-hotspot-igv-view-actions-ExportAction.shadow">
                 <attr name="originalFile" stringvalue="Actions/File/com-sun-hotspot-igv-view-actions-ExportAction.instance"/>
-                <attr name="position" intvalue="600"/>
+                <attr name="position" intvalue="710"/>
             </file>
         </folder>
     </folder>
-    <folder name="Toolbars">
-        <folder name="Edit">
-            <attr name="com-sun-hotspot-igv-view-actions-LineGeneratorAction.shadow/com-sun-hotspot-igv-coordinator-actions-OpenGraphAction.shadow" boolvalue="true"/>
+
+    <folder name="QuickSearch">
+        <folder name="Nodes">
+            <attr name="command" stringvalue="n"/>
+            <attr name="position" intvalue="0"/>
+            <file name="com-sun-hotspot-igv-view-NodeQuickSearch.instance"/>
+        </folder>
+    </folder>
+    
+    <folder name="QuickSearchShadow">
+        <file name="org-netbeans-modules-quicksearch-QuickSearchAction.shadow">
+            <attr name="originalFile" stringvalue="Actions/Edit/org-netbeans-modules-quicksearch-QuickSearchAction.instance"/>
+            
+        </file>    
+    </folder>
+    <folder name="Windows2">
+        <folder name="Modes">
+            <folder name="properties">
+                <file name="properties.wstcref" url="propertiesWstcref.xml"/>
+            </folder>
+            <file name="properties.wsmode" url="propertiesWsmode.xml"/>
         </folder>
     </folder>
 </filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/propertiesWsmode.xml	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE mode PUBLIC
+          "-//NetBeans//DTD Mode Properties 2.0//EN"
+          "http://www.netbeans.org/dtds/mode-properties2_0.dtd">
+
+<mode version="2.0">
+    <name unique="properties" />
+    <kind type="view" />
+    <state type="joined" />
+    <constraints>
+        <path orientation="horizontal" number="90" weight="0.2"/>
+        <path orientation="vertical" number="1" weight="0.50"/>
+    </constraints>
+    <relative-bounds x="75" y="56" width="15" height="32" />
+    <active-tc id="properties" />
+    <empty-behavior permanent="true" />
+</mode>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/propertiesWstcref.xml	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE tc-ref PUBLIC
+          "-//NetBeans//DTD Top Component in Mode Properties 2.0//EN"
+          "http://www.netbeans.org/dtds/tc-ref2_0.dtd">
+
+<tc-ref version="2.0">
+    <module name="org.netbeans.core.ui/1" spec="1.2" />
+    <tc-id id="properties" />
+    <state opened="true" />
+</tc-ref>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/BlockWidget.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/BlockWidget.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -74,7 +74,7 @@
         g.setColor(titleColor);
         g.setFont(titleFont);
 
-        String s = "B" + blockNode.toString();
+        String s = "B" + blockNode.getName();
         Rectangle2D r1 = g.getFontMetrics().getStringBounds(s, g);
         g.drawString(s, r.x + 5, r.y + (int) r1.getHeight());
         g.setStroke(old);
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/DiagramConnectionWidget.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,251 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view.widgets;
-
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.view.DiagramScene;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Stroke;
-import java.util.ArrayList;
-import java.util.List;
-import org.netbeans.api.visual.anchor.AnchorShape;
-import org.netbeans.api.visual.model.ObjectState;
-import org.netbeans.api.visual.widget.ConnectionWidget;
-import org.netbeans.api.visual.widget.Scene;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class DiagramConnectionWidget extends ConnectionWidget {
-
-    private static Stroke DASHED_STROKE = new BasicStroke(
-            1,
-            BasicStroke.CAP_BUTT,
-            BasicStroke.JOIN_ROUND,
-            0,
-            new float[]{2},
-            0);
-    private static Stroke NORMAL_STROKE = new BasicStroke(1);
-    private static Stroke BOLD_STROKE = new BasicStroke(3);
-    public static int WHITE_FACTOR = 5;
-    private Connection connection;
-    private Color color;
-    private Point lastSourceAnchor;
-    private Point lastTargetAnchor;
-    private List<Point> controlPoints;
-    private Rectangle clientArea;
-    private boolean split;
-    private int[] xPoints;
-    private int[] yPoints;
-    private int pointCount;
-
-    /** Creates a new instance of ConnectionWidget */
-    public DiagramConnectionWidget(Connection connection, Scene scene) {
-        super(scene);
-        this.connection = connection;
-        color = connection.getColor();
-        if (connection.getStyle() == Connection.ConnectionStyle.DASHED) {
-            this.setStroke(DASHED_STROKE);
-        } else if (connection.getStyle() == Connection.ConnectionStyle.BOLD) {
-            this.setStroke(BOLD_STROKE);
-        } else {
-            this.setStroke(NORMAL_STROKE);
-        }
-        this.setCheckClipping(true);
-        clientArea = new Rectangle();
-        updateControlPoints();
-    }
-
-    public Connection getConnection() {
-        return connection;
-    }
-
-    public void updateControlPoints() {
-        List<Point> newControlPoints = connection.getControlPoints();
-        Connection c = connection;
-        Figure f = c.getInputSlot().getFigure();
-        Point p = new Point(f.getPosition());
-        p.translate(c.getInputSlot().getRelativePosition().x, f.getSize().height / 2);
-        Point p4 = new Point(f.getPosition());
-        p4.translate(c.getInputSlot().getRelativePosition().x, c.getInputSlot().getRelativePosition().y);
-
-        Figure f2 = c.getOutputSlot().getFigure();
-        Point p2 = new Point(f2.getPosition());
-        p2.translate(c.getOutputSlot().getRelativePosition().x, f2.getSize().height / 2);
-        Point p3 = new Point(f2.getPosition());
-        p3.translate(c.getOutputSlot().getRelativePosition().x, c.getOutputSlot().getRelativePosition().y);
-
-        /*if(controlPoints.size() >= 2) {
-        String className = Preferences.userNodeForPackage(PreferenceConstants.class).get(PreferenceConstants.KEY_LINE_GENERATOR, PreferenceConstants.DEFAULT_LINE_GENERATOR);
-        try {
-        LineGenerator lg = (LineGenerator)Class.forName(className).newInstance();
-        controlPoints = lg.createLine(controlPoints, p2, p);
-        } catch (InstantiationException ex) {
-        } catch (IllegalAccessException ex) {
-        } catch (ClassNotFoundException ex) {
-        }
-        }*/
-
-        this.controlPoints = newControlPoints;
-        pointCount = newControlPoints.size();
-        xPoints = new int[pointCount];
-        yPoints = new int[pointCount];
-        int minX = Integer.MAX_VALUE;
-        int maxX = Integer.MIN_VALUE;
-        int minY = Integer.MAX_VALUE;
-        int maxY = Integer.MIN_VALUE;
-        split = false;
-        for (int i = 0; i < pointCount; i++) {
-            if (newControlPoints.get(i) == null) {
-                split = true;
-            } else {
-                int curX = newControlPoints.get(i).x;
-                int curY = newControlPoints.get(i).y;
-                this.xPoints[i] = curX;
-                this.yPoints[i] = curY;
-                minX = Math.min(minX, curX);
-                maxX = Math.max(maxX, curX);
-                minY = Math.min(minY, curY);
-                maxY = Math.max(maxY, curY);
-            }
-        }
-
-        this.clientArea = new Rectangle(minX, minY, maxX - minX, maxY - minY);
-    }
-
-    @Override
-    protected void paintWidget() {
-        Graphics2D g = this.getGraphics();
-
-        if (xPoints.length == 0 || Math.abs(xPoints[0] - xPoints[xPoints.length - 1]) > 2000) {
-            return;
-        }
-
-        //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
-        //g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);
-        //g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
-
-        DiagramScene ds = (DiagramScene) this.getScene();
-        boolean shouldHide = false;//ds.getShouldHide(this);
-
-        Composite oldComposite = null;
-        if (shouldHide) {
-            Color c = new Color(255 - (255 - color.getRed()) / WHITE_FACTOR, 255 - (255 - color.getGreen()) / WHITE_FACTOR, 255 - (255 - color.getBlue()) / WHITE_FACTOR);
-            g.setPaint(c);
-        } else {
-            g.setPaint(color);
-        }
-
-        if (split) {
-            for (int i = 1; i < controlPoints.size(); i++) {
-                Point prev = controlPoints.get(i - 1);
-                Point cur = controlPoints.get(i);
-                if (cur == null || prev == null) {
-                    continue;
-                }
-
-                g.drawLine(prev.x, prev.y, cur.x, cur.y);
-            }
-        } else {
-            g.drawPolyline(xPoints, yPoints, pointCount);
-        }
-
-        /*for(int i=0; i<xPoints.length; i++) {
-        int x = xPoints[i];
-        int y = yPoints[i];
-        g.fillOval(x - 2, y - 2, 4, 4);
-        }*/
-
-        if (xPoints.length >= 2) {
-            Graphics2D g2 = (Graphics2D) g.create();
-            int xOff = xPoints[xPoints.length - 2] - xPoints[xPoints.length - 1];
-            int yOff = yPoints[yPoints.length - 2] - yPoints[yPoints.length - 1];
-            if (xOff == 0 && yOff == 0 && yPoints.length >= 3) {
-                xOff = xPoints[xPoints.length - 3] - xPoints[xPoints.length - 1];
-                yOff = yPoints[yPoints.length - 3] - yPoints[yPoints.length - 1];
-            }
-            g2.translate(xPoints[xPoints.length - 1], yPoints[yPoints.length - 1]);
-            g2.rotate(Math.atan2(yOff, xOff));
-
-            g2.scale(0.55, 0.80);
-            AnchorShape.TRIANGLE_FILLED.paint(g2, false);
-        }
-    }
-
-    @Override
-    public void notifyStateChanged(ObjectState previousState, ObjectState state) {
-
-        if (previousState.isHovered() != state.isHovered()) {
-            color = connection.getColor();
-            if (state.isHovered()) {
-                this.setStroke(BOLD_STROKE);
-            } else {
-                this.setStroke(NORMAL_STROKE);
-            }
-
-            if (state.isHovered()) {
-                this.setStroke(BOLD_STROKE);
-            } else {
-                this.setStroke(NORMAL_STROKE);
-            }
-
-            repaint();
-        }
-        super.notifyStateChanged(previousState, state);
-    }
-
-    @Override
-    public List<Point> getControlPoints() {
-        if (split) {
-            ArrayList<Point> result = new ArrayList<Point>();
-            for (Point p : controlPoints) {
-                if (p != null) {
-                    result.add(p);
-                }
-            }
-            return result;
-        } else {
-            return controlPoints;
-        }
-    }
-
-    @Override
-    public String toString() {
-        return "ConnectionWidget[" + connection + "]";
-    }
-
-    @Override
-    protected Rectangle calculateClientArea() {
-        Rectangle result = new Rectangle(clientArea);
-        result.grow(10, 10);
-        return result;
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/FigureWidget.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/FigureWidget.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,36 +23,37 @@
  */
 package com.sun.hotspot.igv.view.widgets;
 
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.services.GraphViewer;
 import com.sun.hotspot.igv.graph.Figure;
-import com.sun.hotspot.igv.view.DiagramScene;
-import com.sun.hotspot.igv.view.SlotLayout;
+import com.sun.hotspot.igv.util.DoubleClickAction;
 import com.sun.hotspot.igv.util.DoubleClickHandler;
-import com.sun.hotspot.igv.data.Properties;
 import com.sun.hotspot.igv.util.PropertiesSheet;
-import java.awt.AlphaComposite;
-import java.awt.Color;
-import java.awt.Composite;
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.Graphics;
-import java.awt.Point;
+import com.sun.hotspot.igv.view.DiagramScene;
+import java.awt.*;
+import java.awt.event.ActionEvent;
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.Set;
+import javax.swing.AbstractAction;
 import javax.swing.Action;
 import javax.swing.BorderFactory;
 import javax.swing.JMenu;
 import javax.swing.JPopupMenu;
+import javax.swing.event.MenuEvent;
+import javax.swing.event.MenuListener;
 import org.netbeans.api.visual.action.PopupMenuProvider;
 import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.layout.LayoutFactory;
 import org.netbeans.api.visual.model.ObjectState;
+import org.netbeans.api.visual.widget.LabelWidget;
 import org.netbeans.api.visual.widget.Widget;
-import org.netbeans.api.visual.layout.LayoutFactory;
-import org.netbeans.api.visual.widget.LabelWidget;
 import org.openide.nodes.AbstractNode;
 import org.openide.nodes.Children;
 import org.openide.nodes.Node;
 import org.openide.nodes.Sheet;
+import org.openide.util.Lookup;
 
 /**
  *
@@ -61,12 +62,7 @@
 public class FigureWidget extends Widget implements Properties.Provider, PopupMenuProvider, DoubleClickHandler {
 
     public static final boolean VERTICAL_LAYOUT = true;
-    public static final int DEPTH = 5;
-    public static final int MAX_STRING_LENGTH = 20;
     private static final double LABEL_ZOOM_FACTOR = 0.3;
-    private static final double ZOOM_FACTOR = 0.1;
-    private Font font;
-    private Font boldFont;
     private Figure figure;
     private Widget leftWidget;
     private Widget rightWidget;
@@ -74,7 +70,8 @@
     private ArrayList<LabelWidget> labelWidgets;
     private DiagramScene diagramScene;
     private boolean boundary;
-    private Node node;
+    private final Node node;
+    private Widget dummyTop;
 
     public void setBoundary(boolean b) {
         boundary = b;
@@ -88,80 +85,58 @@
         return node;
     }
 
-    private String shortenString(String string) {
-        if (string.length() > MAX_STRING_LENGTH) {
-            StringBuilder sb = new StringBuilder();
-            for (int i = 0; i < string.length(); i++) {
-                char c = string.charAt(i);
-                if (!Character.isLetter(c) || Character.isUpperCase(c)) {
-                    sb.append(c);
-                }
-            }
-            string = sb.toString();
-        }
-        return string;
+    @Override
+    public boolean isHitAt(Point localLocation) {
+        return middleWidget.isHitAt(localLocation);
     }
 
-    public FigureWidget(final Figure f, DiagramScene s, Widget parent) {
-
-        super(s);
-
+    public FigureWidget(final Figure f, WidgetAction hoverAction, WidgetAction selectAction, DiagramScene scene, Widget parent) {
+        super(scene);
 
-        font = f.getDiagram().getFont();
-        boldFont = f.getDiagram().getFont().deriveFont(Font.BOLD);
-        this.setCheckClipping(true);
-        this.diagramScene = s;
-
-        parent.addChild(this);
-        this.figure = f;
-        this.resolveBounds(null, calculateClientArea());
+        assert this.getScene() != null;
+        assert this.getScene().getView() != null;
 
-        leftWidget = new Widget(s);
-        this.addChild(leftWidget);
-        leftWidget.setLayout(new SlotLayout(SlotLayout.HorizontalAlignment.Right, VERTICAL_LAYOUT));//LayoutFactory.createVerticalFlowLayout(LayoutFactory.SerialAlignment.JUSTIFY, 0));
-
-        middleWidget = new Widget(s);
-        this.addChild(middleWidget);
+        this.figure = f;
+        this.setCheckClipping(true);
+        this.diagramScene = scene;
+        parent.addChild(this);
 
-        if (VERTICAL_LAYOUT) {
-            this.setLayout(LayoutFactory.createVerticalFlowLayout());
-        } else {
-            this.setLayout(LayoutFactory.createHorizontalFlowLayout());
-        }
+        Widget outer = new Widget(scene);
+        outer.setBackground(f.getColor());
+        outer.setLayout(LayoutFactory.createOverlayLayout());
 
-        middleWidget.setLayout(LayoutFactory.createVerticalFlowLayout());
-
+        middleWidget = new Widget(scene);
+        middleWidget.setLayout(LayoutFactory.createVerticalFlowLayout(LayoutFactory.SerialAlignment.CENTER, 0));
         middleWidget.setBackground(f.getColor());
         middleWidget.setOpaque(true);
-        assert this.getScene() != null;
-        assert this.getScene().getView() != null;
-        middleWidget.setBorder(BorderFactory.createLineBorder(Color.BLACK));
+        middleWidget.getActions().addAction(new DoubleClickAction(this));
+        middleWidget.setCheckClipping(true);
 
-
-        labelWidgets = new ArrayList<LabelWidget>();
+        dummyTop = new Widget(scene);
+        dummyTop.setMinimumSize(new Dimension(Figure.INSET / 2, 1));
+        middleWidget.addChild(dummyTop);
 
         String[] strings = figure.getLines();
-
-        for (String cur : strings) {
+        labelWidgets = new ArrayList<>(strings.length);
 
-            String displayString = cur;
-
-            LabelWidget lw = new LabelWidget(s);
+        for (String displayString : strings) {
+            LabelWidget lw = new LabelWidget(scene);
             labelWidgets.add(lw);
             middleWidget.addChild(lw);
             lw.setLabel(displayString);
-
-            lw.setFont(font);
-            lw.setForeground(Color.BLACK);
+            lw.setFont(figure.getDiagram().getFont());
+            lw.setForeground(getTextColor());
             lw.setAlignment(LabelWidget.Alignment.CENTER);
             lw.setVerticalAlignment(LabelWidget.VerticalAlignment.CENTER);
-            lw.setMaximumSize(new Dimension(f.getWidth(), 20000));
-            lw.setMinimumSize(new Dimension(f.getWidth(), 20));
+            lw.setBorder(BorderFactory.createEmptyBorder());
         }
 
-        rightWidget = new Widget(s);
-        this.addChild(rightWidget);
-        rightWidget.setLayout(new SlotLayout(SlotLayout.HorizontalAlignment.Left, VERTICAL_LAYOUT));//LayoutFactory.createVerticalLayout(LayoutFactory.SerialAlignment.JUSTIFY, 0));
+        Widget dummyBottom = new Widget(scene);
+        dummyBottom.setMinimumSize(new Dimension(Figure.INSET / 2, 1));
+        middleWidget.addChild(dummyBottom);
+
+        middleWidget.setPreferredBounds(new Rectangle(0, Figure.SLOT_WIDTH - Figure.OVERLAPPING, f.getWidth(), f.getHeight()));
+        this.addChild(middleWidget);
 
         // Initialize node for property sheet
         node = new AbstractNode(Children.LEAF) {
@@ -175,22 +150,6 @@
         };
         node.setDisplayName(getName());
     }
-    private boolean firstTime = true;
-
-    @Override
-    protected void paintWidget() {
-        if (firstTime) {
-            firstTime = false;
-            for (LabelWidget w : labelWidgets) {
-                String cur = w.getLabel();
-                Graphics graphics = this.getGraphics();
-                if (graphics.getFontMetrics().stringWidth(cur) > figure.getWidth()) {
-                    w.setLabel(shortenString(cur));
-                }
-            }
-        }
-        super.paintWidget();
-    }
 
     public Widget getLeftWidget() {
         return leftWidget;
@@ -204,40 +163,29 @@
     protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
         super.notifyStateChanged(previousState, state);
 
-        Color borderColor = Color.BLACK;
-        int thickness = 1;
-        boolean repaint = false;
-        Font f = font;
+        Font font = this.figure.getDiagram().getFont();
         if (state.isSelected()) {
-            thickness = 1;
-            f = boldFont;
-        }
-
-        if (state.isHovered()) {
-            borderColor = Color.BLUE;
+            font = this.figure.getDiagram().getBoldFont();
         }
 
-        if (state.isHovered() != previousState.isHovered()) {
-            repaint = true;
-        }
-
-        if (state.isSelected() != previousState.isSelected()) {
-            repaint = true;
+        Color borderColor = Color.BLACK;
+        Color innerBorderColor = getFigure().getColor();
+        if (state.isHighlighted()) {
+            innerBorderColor = borderColor = Color.BLUE;
         }
 
-        if (repaint) {
-            middleWidget.setBorder(BorderFactory.createLineBorder(borderColor, thickness));
-            for (LabelWidget labelWidget : labelWidgets) {
-                labelWidget.setFont(f);
-            }
-            repaint();
+        middleWidget.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLineBorder(borderColor, 1), BorderFactory.createLineBorder(innerBorderColor, 1)));
+        for (LabelWidget labelWidget : labelWidgets) {
+            labelWidget.setFont(font);
         }
+        repaint();
     }
 
     public String getName() {
         return getProperties().get("name");
     }
 
+    @Override
     public Properties getProperties() {
         return figure.getProperties();
     }
@@ -246,13 +194,18 @@
         return figure;
     }
 
+    private Color getTextColor() {
+        Color bg = figure.getColor();
+        double brightness = bg.getRed() * 0.21 + bg.getGreen() * 0.72 + bg.getBlue() * 0.07;
+        if (brightness < 150) {
+            return Color.WHITE;
+        } else {
+            return Color.BLACK;
+        }
+    }
+
     @Override
     protected void paintChildren() {
-
-        if (diagramScene.getRealZoomFactor() < ZOOM_FACTOR && diagramScene.getModel().getShowBlocks()) {
-            return;
-        }
-
         Composite oldComposite = null;
         if (boundary) {
             oldComposite = getScene().getGraphics().getComposite();
@@ -260,8 +213,7 @@
             this.getScene().getGraphics().setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
         }
 
-        if (diagramScene.getRealZoomFactor() < LABEL_ZOOM_FACTOR) {
-
+        if (diagramScene.getZoomFactor() < LABEL_ZOOM_FACTOR) {
             for (LabelWidget labelWidget : labelWidgets) {
                 labelWidget.setVisible(false);
             }
@@ -269,9 +221,20 @@
             for (LabelWidget labelWidget : labelWidgets) {
                 labelWidget.setVisible(true);
             }
-
         } else {
+            Color oldColor = null;
+            if (boundary) {
+                for (LabelWidget labelWidget : labelWidgets) {
+                    oldColor = labelWidget.getForeground();
+                    labelWidget.setForeground(Color.BLACK);
+                }
+            }
             super.paintChildren();
+            if (boundary) {
+                for (LabelWidget labelWidget : labelWidgets) {
+                    labelWidget.setForeground(oldColor);
+                }
+            }
         }
 
         if (boundary) {
@@ -279,80 +242,126 @@
         }
     }
 
+    @Override
     public JPopupMenu getPopupMenu(Widget widget, Point point) {
-        JPopupMenu m = diagramScene.createPopupMenu();
+        JPopupMenu menu = diagramScene.createPopupMenu();
+        menu.addSeparator();
 
-        JMenu predecessors = new JMenu("Predecessors");
-        addFigureToSubMenu(predecessors, getFigure(), false, DEPTH);
+        build(menu, getFigure(), this, false, diagramScene);
+        menu.addSeparator();
+        build(menu, getFigure(), this, true, diagramScene);
+
+        if (getFigure().getSubgraphs() != null) {
+            menu.addSeparator();
+            JMenu subgraphs = new JMenu("Subgraphs");
+            menu.add(subgraphs);
 
-        JMenu successors = new JMenu("Successors");
-        addFigureToSubMenu(successors, getFigure(), true, DEPTH);
+            final GraphViewer viewer = Lookup.getDefault().lookup(GraphViewer.class);
+            for (final InputGraph subgraph : getFigure().getSubgraphs()) {
+                Action a = new AbstractAction() {
 
-        m.addSeparator();
-        m.add(predecessors);
-        m.add(successors);
-        return m;
+                    @Override
+                    public void actionPerformed(ActionEvent e) {
+                        viewer.view(subgraph, true);
+                    }
+                };
+
+                a.setEnabled(true);
+                a.putValue(Action.NAME, subgraph.getName());
+                subgraphs.add(a);
+            }
+        }
+
+        return menu;
     }
 
-    public void addFigureToSubMenu(JMenu subMenu, final Figure f, boolean successor, int depth) {
-        Set<Figure> set = f.getPredecessorSet();
-        if (successor) {
-            set = f.getSuccessorSet();
+    public static void build(JPopupMenu menu, Figure figure, FigureWidget figureWidget, boolean successors, DiagramScene diagramScene) {
+        Set<Figure> set = figure.getPredecessorSet();
+        if (successors) {
+            set = figure.getSuccessorSet();
         }
 
-        int count = set.size();
-        if (set.contains(f)) {
-            count--;
-        }
-
-        for (Figure f2 : set) {
-            if (f2 == f) {
+        boolean first = true;
+        for (Figure f : set) {
+            if (f == figure) {
                 continue;
             }
 
-            count--;
-            addFigureToMenu(subMenu, f2, successor, depth - 1);
-            if (count > 0) {
-                subMenu.addSeparator();
+            if (first) {
+                first = false;
+            } else {
+                menu.addSeparator();
             }
+
+            Action go = diagramScene.createGotoAction(f);
+            menu.add(go);
+
+            JMenu preds = new JMenu("Nodes Above");
+            preds.addMenuListener(figureWidget.new NeighborMenuListener(preds, f, false));
+            menu.add(preds);
+
+            JMenu succs = new JMenu("Nodes Below");
+            succs.addMenuListener(figureWidget.new NeighborMenuListener(succs, f, true));
+            menu.add(succs);
+        }
+
+        if (figure.getPredecessorSet().isEmpty() && figure.getSuccessorSet().isEmpty()) {
+            menu.add("(none)");
         }
     }
 
-    public void addFigureToMenu(JMenu m, final Figure f, boolean successor, int depth) {
+    /**
+     * Builds the submenu for a figure's neighbors on demand.
+     */
+    public class NeighborMenuListener implements MenuListener {
 
-        Action a = diagramScene.createGotoAction(f);
-
+        private final JMenu menu;
+        private final Figure figure;
+        private final boolean successors;
 
-        m.add(a);
+        public NeighborMenuListener(JMenu menu, Figure figure, boolean successors) {
+            this.menu = menu;
+            this.figure = figure;
+            this.successors = successors;
+        }
 
-        if (depth > 0) {
-            String name = "Predecessors";
-            if (successor) {
-                name = "Successors";
+        @Override
+        public void menuSelected(MenuEvent e) {
+            if (menu.getItemCount() > 0) {
+                // already built before
+                return;
             }
 
-            JMenu subMenu = new JMenu(name);
-            addFigureToSubMenu(subMenu, f, successor, depth);
-            m.add(subMenu);
+            build(menu.getPopupMenu(), figure, FigureWidget.this, successors, diagramScene);
+        }
+
+        @Override
+        public void menuDeselected(MenuEvent e) {
+            // ignore
         }
 
+        @Override
+        public void menuCanceled(MenuEvent e) {
+            // ignore
+        }
     }
 
+    @Override
     public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) {
 
         if (diagramScene.isAllVisible()) {
-            Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes());
+            final Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes());
             hiddenNodes.removeAll(this.getFigure().getSource().getSourceNodesAsSet());
-            this.diagramScene.showNot(hiddenNodes);
+            this.diagramScene.getModel().showNot(hiddenNodes);
         } else if (isBoundary()) {
 
-            Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getHiddenNodes());
+            final Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getHiddenNodes());
             hiddenNodes.removeAll(this.getFigure().getSource().getSourceNodesAsSet());
-            this.diagramScene.showNot(hiddenNodes);
+            this.diagramScene.getModel().showNot(hiddenNodes);
         } else {
-            Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getHiddenNodes());
+            final Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getHiddenNodes());
             hiddenNodes.addAll(this.getFigure().getSource().getSourceNodesAsSet());
-            this.diagramScene.showNot(hiddenNodes);
+            this.diagramScene.getModel().showNot(hiddenNodes);
         }
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/InputSlotWidget.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/InputSlotWidget.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
  */
 package com.sun.hotspot.igv.view.widgets;
 
+import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.graph.InputSlot;
 import com.sun.hotspot.igv.view.DiagramScene;
 import java.awt.Point;
@@ -40,14 +41,25 @@
     public InputSlotWidget(InputSlot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
         super(slot, scene, parent, fw);
         inputSlot = slot;
-        init();
-        getFigureWidget().getLeftWidget().addChild(this);
+        //init();
+        //getFigureWidget().getLeftWidget().addChild(this);
+        Point p = inputSlot.getRelativePosition();
+        p.x -= this.calculateClientArea().width / 2;
+        p.y += Figure.SLOT_START;
+        this.setPreferredLocation(p);
     }
 
     public InputSlot getInputSlot() {
         return inputSlot;
     }
 
+    @Override
+    protected int calculateSlotWidth() {
+        List<InputSlot> slots = getSlot().getFigure().getInputSlots();
+        assert slots.contains(getSlot());
+        return calculateWidth(slots.size());
+    }
+/*
     protected Point calculateRelativeLocation() {
         if (getFigureWidget().getBounds() == null) {
             return new Point(0, 0);
@@ -57,5 +69,5 @@
         List<InputSlot> slots = inputSlot.getFigure().getInputSlots();
         assert slots.contains(inputSlot);
         return new Point((int) x, (int) (calculateRelativeY(slots.size(), slots.indexOf(inputSlot))));
-    }
+    }*/
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -24,23 +24,22 @@
 package com.sun.hotspot.igv.view.widgets;
 
 import com.sun.hotspot.igv.graph.Connection;
+import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.graph.InputSlot;
 import com.sun.hotspot.igv.graph.OutputSlot;
 import com.sun.hotspot.igv.view.DiagramScene;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Stroke;
+import java.awt.*;
 import java.awt.geom.Line2D;
 import java.util.ArrayList;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import javax.swing.JPopupMenu;
 import javax.swing.event.PopupMenuEvent;
 import javax.swing.event.PopupMenuListener;
 import org.netbeans.api.visual.action.ActionFactory;
 import org.netbeans.api.visual.action.PopupMenuProvider;
+import org.netbeans.api.visual.action.SelectProvider;
 import org.netbeans.api.visual.animator.SceneAnimator;
 import org.netbeans.api.visual.model.ObjectState;
 import org.netbeans.api.visual.widget.Widget;
@@ -51,7 +50,7 @@
  */
 public class LineWidget extends Widget implements PopupMenuProvider {
 
-    public final int BORDER = 8;
+    public final int BORDER = 5;
     public final int ARROW_SIZE = 6;
     public final int BOLD_ARROW_SIZE = 7;
     public final int HOVER_ARROW_SIZE = 8;
@@ -80,7 +79,7 @@
         this.from = from;
         this.to = to;
         this.predecessor = predecessor;
-        this.successors = new ArrayList<LineWidget>();
+        this.successors = new ArrayList<>();
         if (predecessor != null) {
             predecessor.addSuccessor(this);
         }
@@ -110,6 +109,7 @@
         if (connections.size() > 0) {
             color = connections.get(0).getColor();
         }
+        this.setToolTipText("<HTML>" + generateToolTipText(this.connections) + "</HTML>");
 
         this.setCheckClipping(true);
 
@@ -120,6 +120,38 @@
             this.setBackground(Color.WHITE);
             animator.animateBackgroundColor(this, color);
         }
+
+        this.getActions().addAction(ActionFactory.createSelectAction(new SelectProvider() {
+
+            @Override
+            public boolean isAimingAllowed(Widget arg0, Point arg1, boolean arg2) {
+                return true;
+            }
+
+            @Override
+            public boolean isSelectionAllowed(Widget arg0, Point arg1, boolean arg2) {
+                return true;
+            }
+
+            @Override
+            public void select(Widget arg0, Point arg1, boolean arg2) {
+                Set<Figure> set = new HashSet<>();
+                for (Connection c : LineWidget.this.connections) {
+                    set.add(c.getInputSlot().getFigure());
+                    set.add(c.getOutputSlot().getFigure());
+                }
+                LineWidget.this.scene.setSelectedObjects(set);
+            }
+        }));
+    }
+
+    private String generateToolTipText(List<Connection> conn) {
+        StringBuilder sb = new StringBuilder();
+        for (Connection c : conn) {
+            sb.append(c.getToolTipText());
+            sb.append("<br>");
+        }
+        return sb.toString();
     }
 
     public Point getFrom() {
@@ -141,13 +173,12 @@
 
     @Override
     protected void paintWidget() {
-        if (scene.getRealZoomFactor() < ZOOM_FACTOR) {
+        if (scene.getZoomFactor() < ZOOM_FACTOR) {
             return;
         }
 
         Graphics2D g = getScene().getGraphics();
         g.setPaint(this.getBackground());
-        ObjectState state = this.getState();
         float width = 1.0f;
 
         if (isBold) {
@@ -171,7 +202,7 @@
         g.drawLine(from.x, from.y, to.x, to.y);
 
         boolean sameFrom = false;
-        boolean sameTo = successors.size() == 0;
+        boolean sameTo = successors.isEmpty();
         for (LineWidget w : successors) {
             if (w.getFrom().equals(getTo())) {
                 sameTo = true;
@@ -207,6 +238,20 @@
 
     private void setHighlighted(boolean b) {
         this.highlighted = b;
+        Set<Object> highlightedObjects = new HashSet<>(scene.getHighlightedObjects());
+        Set<Object> highlightedObjectsChange = new HashSet<>();
+        for (Connection c : connections) {
+            highlightedObjectsChange.add(c.getInputSlot().getFigure());
+            highlightedObjectsChange.add(c.getInputSlot());
+            highlightedObjectsChange.add(c.getOutputSlot().getFigure());
+            highlightedObjectsChange.add(c.getOutputSlot());
+        }
+        if(b) {
+            highlightedObjects.addAll(highlightedObjectsChange);
+        } else {
+            highlightedObjects.removeAll(highlightedObjectsChange);
+        }
+        scene.setHighlightedObjects(highlightedObjects);
         this.revalidate(true);
     }
 
@@ -263,6 +308,7 @@
         }
     }
 
+    @Override
     public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
         JPopupMenu menu = new JPopupMenu();
         menu.add(scene.createGotoAction(outputSlot.getFigure()));
@@ -276,14 +322,17 @@
         final LineWidget w = this;
         menu.addPopupMenuListener(new PopupMenuListener() {
 
+            @Override
             public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                 w.setRecursivePopupVisible(true);
             }
 
+            @Override
             public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                 w.setRecursivePopupVisible(false);
             }
 
+            @Override
             public void popupMenuCanceled(PopupMenuEvent e) {
             }
         });
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/MultiConnectionWidget.java	Tue May 05 16:50:25 2015 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,281 +0,0 @@
-/*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-package com.sun.hotspot.igv.view.widgets;
-
-import com.sun.hotspot.igv.graph.Connection;
-import com.sun.hotspot.igv.graph.InputSlot;
-import com.sun.hotspot.igv.graph.OutputSlot;
-import com.sun.hotspot.igv.graph.Slot;
-import com.sun.hotspot.igv.view.DiagramScene;
-import java.awt.BasicStroke;
-import java.awt.Color;
-import java.awt.Graphics2D;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Stroke;
-import java.awt.geom.Line2D;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.SortedSet;
-import java.util.TreeSet;
-import javax.swing.JPopupMenu;
-import javax.swing.event.PopupMenuEvent;
-import javax.swing.event.PopupMenuListener;
-import org.netbeans.api.visual.action.PopupMenuProvider;
-import org.netbeans.api.visual.model.ObjectState;
-import org.netbeans.api.visual.widget.Widget;
-
-/**
- *
- * @author Thomas Wuerthinger
- */
-public class MultiConnectionWidget extends Widget implements PopupMenuProvider {
-
-    public final int BORDER = 4;
-    public final int HOVER_STROKE_WIDTH = 3;
-
-    private static class Route {
-
-        public Point from;
-        public Point to;
-        public SortedSet<InputSlot> inputSlots;
-        public boolean decorateStart;
-        public boolean decorateEnd;
-
-        public Route(Point from, Point to) {
-            assert from != null;
-            assert to != null;
-            this.from = from;
-            this.to = to;
-            this.inputSlots = new TreeSet<InputSlot>();
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-
-            if (obj instanceof Route) {
-                Route r = (Route) obj;
-                return r.from.equals(from) && r.to.equals(to);
-            }
-
-            return super.equals(obj);
-        }
-
-        @Override
-        public int hashCode() {
-            return ((((from.x * 1711) + from.y) * 1711 + to.x) * 1711 + to.y);
-        }
-    }
-    private Rectangle clientArea;
-    private OutputSlot outputSlot;
-    private Map<Route, SortedSet<InputSlot>> routeMap;
-    private List<Route> routeList;
-    private Color color;
-    private DiagramScene diagramScene;
-    private boolean popupVisible;
-
-    /** Creates a new instance of MultiConnectionWidget */
-    public MultiConnectionWidget(OutputSlot outputSlot, DiagramScene scene) {
-        super(scene);
-
-        this.diagramScene = scene;
-        this.outputSlot = outputSlot;
-        this.setCheckClipping(true);
-
-        routeMap = new HashMap<Route, SortedSet<InputSlot>>();
-        routeList = new ArrayList<Route>();
-        color = Color.BLACK;
-
-        for (Connection c : outputSlot.getConnections()) {
-            List<Point> controlPoints = c.getControlPoints();
-            InputSlot inputSlot = (InputSlot) c.getTo();
-            color = c.getColor();
-
-            for (int i = 1; i < controlPoints.size(); i++) {
-                Point prev = controlPoints.get(i - 1);
-                Point cur = controlPoints.get(i);
-
-                if (prev != null && cur != null) {
-                    Route r = new Route(prev, cur);
-                    if (routeMap.containsKey(r)) {
-                        SortedSet<InputSlot> set = routeMap.get(r);
-                        set.add(inputSlot);
-                    } else {
-                        SortedSet<InputSlot> set = new TreeSet<InputSlot>(Slot.slotFigureComparator);
-                        set.add(inputSlot);
-                        routeMap.put(r, set);
-                        routeList.add(r);
-                    }
-                }
-            }
-        }
-
-        if (routeList.size() == 0) {
-            clientArea = new Rectangle();
-        } else {
-            for (Route r : routeList) {
-
-                int x = r.from.x;
-                int y = r.from.y;
-
-                int x2 = r.to.x;
-                int y2 = r.to.y;
-
-                if (x > x2) {
-                    int tmp = x;
-                    x = x2;
-                    x2 = tmp;
-                }
-
-                if (y > y2) {
-                    int tmp = y;
-                    y = y2;
-                    y2 = tmp;
-                }
-
-                int width = x2 - x + 1;
-                int height = y2 - y + 1;
-
-                Rectangle rect = new Rectangle(x, y, width, height);
-                if (clientArea == null) {
-                    clientArea = rect;
-                } else {
-                    clientArea = clientArea.union(rect);
-                }
-            }
-
-            clientArea.grow(BORDER, BORDER);
-        }
-    }
-
-    private void setHoverPosition(Point location) {
-        Route r = getNearest(location);
-    }
-
-    private Route getNearest(Point localLocation) {
-
-        double minDist = Double.MAX_VALUE;
-        Route result = null;
-        for (Route r : routeList) {
-            double dist = Line2D.ptSegDistSq((double) r.from.x, (double) r.from.y, (double) r.to.x, (double) r.to.y, (double) localLocation.x, (double) localLocation.y);
-            if (dist < minDist) {
-                result = r;
-                minDist = dist;
-            }
-        }
-
-        assert result != null;
-
-        return result;
-    }
-
-    @Override
-    public boolean isHitAt(Point localLocation) {
-        if (!super.isHitAt(localLocation)) {
-            return false;
-        }
-
-        for (Route r : routeList) {
-            double dist = Line2D.ptSegDistSq((double) r.from.x, (double) r.from.y, (double) r.to.x, (double) r.to.y, (double) localLocation.x, (double) localLocation.y);
-            if (dist < BORDER * BORDER) {
-                setHoverPosition(localLocation);
-                return true;
-            }
-        }
-
-        return false;
-    }
-
-    @Override
-    protected Rectangle calculateClientArea() {
-        return clientArea;
-    }
-
-    @Override
-    protected void paintWidget() {
-        Graphics2D g = getScene().getGraphics();
-        //g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
-        g.setColor(this.color);
-        ObjectState state = this.getState();
-        float width = 1.0f;
-        if (state.isHovered() || this.popupVisible) {
-            width = HOVER_STROKE_WIDTH;
-        }
-
-        Stroke oldStroke = g.getStroke();
-        g.setStroke(new BasicStroke(width));
-        for (Route r : routeList) {
-            g.drawLine(r.from.x, r.from.y, r.to.x, r.to.y);
-        }
-        g.setStroke(oldStroke);
-    }
-
-    @Override
-    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
-
-        boolean repaint = false;
-
-        if (state.isHovered() != previousState.isHovered()) {
-            repaint = true;
-        }
-
-        repaint();
-    }
-
-    public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
-        JPopupMenu menu = new JPopupMenu();
-        Route r = getNearest(localLocation);
-        assert r != null;
-        assert routeMap.containsKey(r);
-
-        menu.add(diagramScene.createGotoAction(outputSlot.getFigure()));
-        menu.addSeparator();
-
-        SortedSet<InputSlot> set = this.routeMap.get(r);
-        for (InputSlot s : set) {
-            menu.add(diagramScene.createGotoAction(s.getFigure()));
-        }
-
-        final MultiConnectionWidget w = this;
-        menu.addPopupMenuListener(new PopupMenuListener() {
-
-            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
-                w.popupVisible = true;
-                w.repaint();
-            }
-
-            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
-                w.popupVisible = false;
-                w.repaint();
-            }
-
-            public void popupMenuCanceled(PopupMenuEvent e) {
-            }
-        });
-
-        return menu;
-    }
-}
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/OutputSlotWidget.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/OutputSlotWidget.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,6 +23,7 @@
  */
 package com.sun.hotspot.igv.view.widgets;
 
+import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.graph.OutputSlot;
 import com.sun.hotspot.igv.view.DiagramScene;
 import java.awt.Point;
@@ -40,22 +41,21 @@
     public OutputSlotWidget(OutputSlot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
         super(slot, scene, parent, fw);
         outputSlot = slot;
-        init();
-        getFigureWidget().getRightWidget().addChild(this);
+        Point p = outputSlot.getRelativePosition();
+        p.y += getSlot().getFigure().getHeight() - Figure.SLOT_START;
+        p.x -= this.calculateClientArea().width / 2;
+        this.setPreferredLocation(p);
     }
 
     public OutputSlot getOutputSlot() {
         return outputSlot;
     }
 
-    protected Point calculateRelativeLocation() {
-        if (getFigureWidget().getBounds() == null) {
-            return new Point(0, 0);
-        }
+    @Override
+    protected int calculateSlotWidth() {
+        List<OutputSlot> slots = getSlot().getFigure().getOutputSlots();
+        assert slots.contains(getSlot());
+        return calculateWidth(slots.size());
 
-        double x = this.getFigureWidget().getBounds().width;
-        List<OutputSlot> slots = outputSlot.getFigure().getOutputSlots();
-        assert slots.contains(outputSlot);
-        return new Point((int) x, (int) (calculateRelativeY(slots.size(), slots.indexOf(outputSlot))));
     }
 }
--- a/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/SlotWidget.java	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/SlotWidget.java	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,51 +26,47 @@
 import com.sun.hotspot.igv.graph.Figure;
 import com.sun.hotspot.igv.graph.OutputSlot;
 import com.sun.hotspot.igv.graph.Slot;
-import com.sun.hotspot.igv.view.*;
+import com.sun.hotspot.igv.util.DoubleClickHandler;
+import com.sun.hotspot.igv.view.DiagramScene;
 import java.awt.Color;
 import java.awt.Font;
 import java.awt.Graphics2D;
-import java.awt.Image;
-import java.awt.Point;
 import java.awt.Rectangle;
 import java.awt.geom.Rectangle2D;
+import java.util.HashSet;
+import java.util.Set;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.model.ObjectState;
 import org.netbeans.api.visual.widget.Widget;
 
 /**
  *
  * @author Thomas Wuerthinger
  */
-public abstract class SlotWidget extends Widget {
+public abstract class SlotWidget extends Widget implements DoubleClickHandler {
 
     private Slot slot;
     private FigureWidget figureWidget;
-    private Image bufferImage;
     private static double TEXT_ZOOM_FACTOR = 0.9;
     private static double ZOOM_FACTOR = 0.6;
-    private DiagramScene scene;
+    private DiagramScene diagramScene;
 
     public SlotWidget(Slot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
         super(scene);
-        this.scene = scene;
+        this.diagramScene = scene;
         this.slot = slot;
         figureWidget = fw;
-        this.setToolTipText("<HTML>" + slot.getName() + "</HTML>");
+        this.setToolTipText("<HTML>" + slot.getToolTipText() + "</HTML>");
         this.setCheckClipping(true);
+        parent.addChild(this);
+
+        //this.setPreferredBounds(this.calculateClientArea());
     }
 
-    public Point getAnchorPosition() {
-        Point p = new Point(figureWidget.getFigure().getPosition());
-        Point p2 = slot.getRelativePosition();
-        p.translate(p2.x, p2.y);
-        return p;
-    }
-
-    protected void init() {
-
-        Point p = calculateRelativeLocation();
-        Rectangle r = calculateClientArea();
-        p = new Point(p.x, p.y - r.height / 2);
-        this.setPreferredLocation(p);
+    @Override
+    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
+        super.notifyStateChanged(previousState, state);
+        repaint();
     }
 
     public Slot getSlot() {
@@ -84,43 +80,98 @@
     @Override
     protected void paintWidget() {
 
-        if (scene.getRealZoomFactor() < ZOOM_FACTOR) {
+        if (getScene().getZoomFactor() < ZOOM_FACTOR) {
             return;
         }
 
-        if (bufferImage == null) {
-            Graphics2D g = this.getGraphics();
-            g.setColor(Color.DARK_GRAY);
-            int w = this.getBounds().width;
-            int h = this.getBounds().height;
+        Graphics2D g = this.getGraphics();
+        // g.setColor(Color.DARK_GRAY);
+        int w = this.getBounds().width;
+        int h = this.getBounds().height;
+
+        if (getSlot().getSource().getSourceNodes().size() > 0) {
+            final int SMALLER = 0;
+            g.setColor(getSlot().getColor());
+
+            int FONT_OFFSET = 2;
+
+            int s = h - SMALLER;
+            int rectW = s;
+
+            Font font = this.getSlot().getFigure().getDiagram().getSlotFont();
+            if (this.getState().isSelected()) {
+                font = font.deriveFont(Font.BOLD);
+            }
+
+            if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0) {
+                g.setFont(font);
+                Rectangle2D r1 = g.getFontMetrics().getStringBounds(getSlot().getShortName(), g);
+                rectW = (int) r1.getWidth() + FONT_OFFSET * 2;
+            }
+            g.fillRect(w / 2 - rectW / 2, 0, rectW - 1, s - 1);
 
-            if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0 && scene.getRealZoomFactor() >= TEXT_ZOOM_FACTOR) {
-                Font f = new Font("Arial", Font.PLAIN, 8);
-                g.setFont(f.deriveFont(7.5f));
-                Rectangle2D r1 = g.getFontMetrics().getStringBounds(getSlot().getShortName(), g);
-                g.drawString(getSlot().getShortName(), (int) (this.getBounds().width - r1.getWidth()) / 2, (int) (this.getBounds().height + r1.getHeight()) / 2);
+            if (this.getState().isHighlighted()) {
+                g.setColor(Color.BLUE);
             } else {
+                g.setColor(Color.BLACK);
+            }
+            g.drawRect(w / 2 - rectW / 2, 0, rectW - 1, s - 1);
 
+            if (getSlot().getShortName() != null && getSlot().getShortName().length() > 0 && getScene().getZoomFactor() >= TEXT_ZOOM_FACTOR) {
+                Rectangle2D r1 = g.getFontMetrics().getStringBounds(getSlot().getShortName(), g);
+                g.drawString(getSlot().getShortName(), (int) (w - r1.getWidth()) / 2, g.getFontMetrics().getAscent() - 1);//(int) (r1.getHeight()));
+            }
+
+        } else {
+
+            if (this.getSlot().getConnections().isEmpty()) {
+                if (this.getState().isHighlighted()) {
+                    g.setColor(Color.BLUE);
+                } else {
+                    g.setColor(Color.BLACK);
+                }
+                int r = 2;
                 if (slot instanceof OutputSlot) {
-                    g.fillArc(w / 4, -h / 4 - 1, w / 2, h / 2, 180, 180);
+                    g.fillOval(w / 2 - r, Figure.SLOT_WIDTH - Figure.SLOT_START - r, 2 * r, 2 * r);
                 } else {
-                    g.fillArc(w / 4, 3 * h / 4, w / 2, h / 2, 0, 180);
+                    g.fillOval(w / 2 - r, Figure.SLOT_START - r, 2 * r, 2 * r);
                 }
+            } else {
+                // Do not paint a slot with connections.
             }
         }
     }
 
     @Override
     protected Rectangle calculateClientArea() {
-        return new Rectangle(0, 0, Figure.SLOT_WIDTH, Figure.SLOT_WIDTH);
+        return new Rectangle(0, 0, slot.getWidth(), Figure.SLOT_WIDTH);
+    }
+
+    protected abstract int calculateSlotWidth();
+
+    protected int calculateWidth(int count) {
+        return getFigureWidget().getFigure().getWidth() / count;
     }
 
-    protected abstract Point calculateRelativeLocation();
+    @Override
+    public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) {
+        Set<Integer> hiddenNodes = new HashSet<>(diagramScene.getModel().getHiddenNodes());
+        if (diagramScene.isAllVisible()) {
+            hiddenNodes = new HashSet<>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes());
+        }
 
-    protected double calculateRelativeY(int size, int index) {
-        assert index >= 0 && index < size;
-        assert size > 0;
-        double height = getFigureWidget().getBounds().getHeight();
-        return height * (index + 1) / (size + 1);
+        boolean progress = false;
+        for (Figure f : diagramScene.getModel().getDiagramToView().getFigures()) {
+            for (Slot s : f.getSlots()) {
+                if (DiagramScene.doesIntersect(s.getSource().getSourceNodesAsSet(), slot.getSource().getSourceNodesAsSet())) {
+                    progress = true;
+                    hiddenNodes.removeAll(f.getSource().getSourceNodesAsSet());
+                }
+            }
+        }
+
+        if (progress) {
+            this.diagramScene.getModel().showNot(hiddenNodes);
+        }
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/branding.jnlp	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE jnlp PUBLIC "-//Sun Microsystems, Inc//DTD JNLP Descriptor 6.0//EN" "http://java.sun.com/dtd/JNLP-6.0.dtd">
+<jnlp spec="1.0+" codebase="$$codebase">
+  <information>
+      <title>${app.title}</title>
+      <vendor>${app.title} vendor</vendor>
+      <description>${app.name} application</description>
+      <icon href="${app.icon}"/>
+  </information>
+  ${jnlp.permissions}
+  <resources>
+    ${jnlp.branding.jars}
+  </resources>
+  <component-desc/>
+</jnlp>  
--- a/hotspot/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,7 +1,7 @@
 currentVersion=IdealGraphVisualizer {0}
 LBL_splash_window_title=Starting IdealGraphVisualizer
 SPLASH_WIDTH=475
-SplashProgressBarBounds=0,268,473,6
+SplashProgressBarBounds=0,273,475,6
 SplashProgressBarColor=0xFFFFFF
-SplashRunningTextBounds=269,253,205,12
+SplashRunningTextBounds=10,283,460,12
 SplashRunningTextColor=0xFFFFFF
Binary file hotspot/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/frame.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/frame32.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/frame48.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/splash.gif has changed
--- a/hotspot/src/share/tools/IdealGraphVisualizer/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,2 +1,2 @@
-CTL_MainWindow_Title=IdealGraphVisualizer {0}
-CTL_MainWindow_Title_No_Project=IdealGraphVisualizer {0}
+CTL_MainWindow_Title=IdealGraphVisualizer
+CTL_MainWindow_Title_No_Project=IdealGraphVisualizer
--- a/hotspot/src/share/tools/IdealGraphVisualizer/build.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/build.xml	Tue May 05 19:27:08 2015 +0200
@@ -5,4 +5,12 @@
 <project name="IdealGraphVisualizer" basedir=".">
     <description>Builds the module suite IdealGraphVisualizer.</description>
     <import file="nbproject/build-impl.xml"/>
+    
+    <target name="build-launchers" depends="suite.build-launchers">
+        <!-- Drop memory presets (-Xms, -Xmx) from default_options of packaged builds and let the executing VM choose reasonable defaults -->
+        <replaceregexp file="${build.launcher.dir}/etc/${app.name}.conf" byline="true" match="^default_options=.*" replace='default_options="--branding idealgraphvisualizer"' />
+    </target>
+    
+    <!-- Local (environment-specific) extensions/modifications to the build -->
+    <import file="build-local.xml" optional="true" />
 </project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/igv.sh	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,23 @@
+#!/bin/sh
+# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# This code is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License version 2 only, as
+# published by the Free Software Foundation.
+#
+# This code is distributed in the hope that it will be useful, but WITHOUT
+# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+# version 2 for more details (a copy is included in the LICENSE file that
+# accompanied this code).
+#
+# You should have received a copy of the GNU General Public License version
+# 2 along with this work; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+# or visit www.oracle.com if you need additional information or have any
+# questions.
+ant run >.igv.log 2>&1
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/master.jnlp	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE jnlp PUBLIC "-//Sun Microsystems, Inc//DTD JNLP Descriptor 6.0//EN" "http://java.sun.com/dtd/JNLP-6.0.dtd">
+<jnlp spec="1.0+" codebase="$$codebase" href="master.jnlp">
+  <information>
+      <title>Ideal Graph Visualizer</title>
+      <vendor>Ideal Graph Visualizer Team</vendor>
+      <description>A graph visualization tool designed for analyzing evolving compiler graphs. It was originally designed for the ideal graph in the HotSpot server compiler, but can be used to visualize arbitrary graph data structures.</description>
+      <icon href="${app.icon}"/>
+  </information>
+  <security><all-permissions/></security>
+  <resources>
+    <!-- The following property is needed when running with unsigned jars: -->
+    <property name="netbeans.jnlp.fixPolicy" value="${netbeans.jnlp.fixPolicy}"/>
+    <extension name='branding' href='branding.jnlp' />
+<!-- The following line will be replaced with an automatically generated list of resources: -->
+<!--${jnlp.resources}-->
+  </resources>
+  <resources os="Mac OS X">
+      <property name="netbeans.user" value="${user.home}/Library/Application Support/${app.name}"/>
+  </resources>
+  <application-desc>
+    <argument>--branding</argument>
+    <argument>${branding.token}</argument>
+  </application-desc>
+</jnlp>  
--- a/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/build-impl.xml	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/build-impl.xml	Tue May 05 19:27:08 2015 +0200
@@ -4,6 +4,13 @@
 ***         EDIT ../build.xml INSTEAD         ***
 -->
 <project name="IdealGraphVisualizer-impl" basedir=".." xmlns:sproject="http://www.netbeans.org/ns/nb-module-suite-project/1">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
     <property file="nbproject/private/platform-private.properties"/>
     <property file="nbproject/platform.properties"/>
     <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
@@ -13,13 +20,29 @@
             <property name="@{name}" value="${@{value}}"/>
         </sequential>
     </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-suite-project/1">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
     <property file="${user.properties.file}"/>
     <sproject:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir"/>
-    <sproject:property name="netbeans.dest.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/>
-    <fail message="You must define 'nbplatform.${nbplatform.active}.harness.dir'">
+    <sproject:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir"/>
+    <sproject:evalprops property="cluster.path.evaluated" value="${cluster.path}"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
         <condition>
             <not>
-                <available file="${harness.dir}" type="dir"/>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <ant antfile="nbproject/platform.xml"/>
+    <fail message="Cannot find NetBeans build harness. ${line.separator}Check that nbplatform.${nbplatform.active}.netbeans.dest.dir and nbplatform.${nbplatform.active}.harness.dir are defined. ${line.separator}On a developer machine these are normally defined in ${user.properties.file}=${netbeans.user}/build.properties ${line.separator}but for automated builds you should pass these properties to Ant explicitly. ${line.separator}You may instead download the harness and platform: -Dbootstrap.url=.../tasks.jar -Dautoupdate.catalog.url=.../updates.xml">
+        <condition>
+            <not>
+                <available file="${harness.dir}/suite.xml"/>
             </not>
         </condition>
     </fail>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/genfiles.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/genfiles.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,8 +1,11 @@
-build.xml.data.CRC32=72833581
-build.xml.script.CRC32=e9c757c5
-build.xml.stylesheet.CRC32=531c622b
+build.xml.data.CRC32=3c2c6126
+build.xml.script.CRC32=48934e60
+build.xml.stylesheet.CRC32=eaf9f76a@1.45.1
 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
 # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
-nbproject/build-impl.xml.data.CRC32=72833581
-nbproject/build-impl.xml.script.CRC32=1b6f3648
-nbproject/build-impl.xml.stylesheet.CRC32=196c7090
+nbproject/build-impl.xml.data.CRC32=3c2c6126
+nbproject/build-impl.xml.script.CRC32=b26e57e5
+nbproject/build-impl.xml.stylesheet.CRC32=0f381476@2.62.1
+nbproject/platform.xml.data.CRC32=3c2c6126
+nbproject/platform.xml.script.CRC32=6dcbd131
+nbproject/platform.xml.stylesheet.CRC32=4e1f53d4@2.62.1
--- a/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,29 +1,18 @@
-# Deprecated since 5.0u1; for compatibility with 5.0:
-disabled.clusters=\
-    apisupport1,\
-    gsf1,\
-    harness,\
-    ide9,\
-    java2,\
-    nb6.1,\
-    profiler3
-disabled.modules=\
-    org.netbeans.core.execution,\
-    org.netbeans.core.multiview,\
-    org.netbeans.core.output2,\
-    org.netbeans.modules.autoupdate.services,\
-    org.netbeans.modules.autoupdate.ui,\
-    org.netbeans.modules.core.kit,\
-    org.netbeans.modules.favorites,\
-    org.netbeans.modules.javahelp,\
-    org.netbeans.modules.masterfs,\
-    org.netbeans.modules.options.keymap,\
-    org.netbeans.modules.sendopts,\
-    org.netbeans.modules.templates,\
-    org.openide.compat,\
-    org.openide.execution,\
-    org.openide.util.enumerations
-enabled.clusters=\
-    platform8
-nbjdk.active=default
+branding.token=idealgraphvisualizer
+cluster.path=\
+    ${nbplatform.active.dir}/ide:\
+    ${nbplatform.active.dir}/platform
+disabled.modules=
+nbplatform.active.dir=${suite.dir}/nbplatform
+nbplatform.default.netbeans.dest.dir=${suite.dir}/nbplatform
+nbplatform.default.harness.dir=${nbplatform.default.netbeans.dest.dir}/harness
+bootstrap.url=http://deadlock.netbeans.org/hudson/job/nbms-and-javadoc/lastSuccessfulBuild/artifact/nbbuild/netbeans/harness/tasks.jar
+autoupdate.catalog.url=http://updates.netbeans.org/netbeans/updates/7.4/uc/final/distribution/catalog.xml.gz
+suite.dir=${basedir}
 nbplatform.active=default
+## Not disabled because of NetBeans bug 206347:
+## Applications not using OSGi don't start on NbP 7.1
+#   org.netbeans.core.netigso,\
+#   org.netbeans.libs.felix,\
+#   org.netbeans.libs.osgi,\
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/platform.xml	Tue May 05 19:27:08 2015 +0200
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project name="platform" default="download" basedir="..">
+    <condition property="download.required">
+        <and>
+            <not>
+                <available file="${harness.dir}/suite.xml"/>
+            </not>
+            <isset property="bootstrap.url"/>
+            <isset property="autoupdate.catalog.url"/>
+        </and>
+    </condition>
+    <target name="download" if="download.required">
+        <mkdir dir="${harness.dir}"/>
+        <pathconvert pathsep="|" property="download.clusters">
+            <mapper type="flatten"/>
+            <path path="${cluster.path}"/>
+        </pathconvert>
+        <property name="disabled.modules" value=""/>
+        <pathconvert property="module.includes" pathsep="">
+            <mapper type="glob" from="${basedir}${file.separator}*" to="(?!^\Q*\E$)"/>
+            <path>
+                <filelist files="${disabled.modules}" dir="."/>
+            </path>
+        </pathconvert>
+        <echo message="Downloading clusters ${download.clusters}"/>
+        <property name="tasks.jar" location="${java.io.tmpdir}/tasks.jar"/>
+        <get src="${bootstrap.url}" dest="${tasks.jar}" usetimestamp="true" verbose="true"/>
+        <taskdef name="autoupdate" classname="org.netbeans.nbbuild.AutoUpdate" classpath="${tasks.jar}"/>
+        <autoupdate installdir="${nbplatform.active.dir}" updatecenter="${autoupdate.catalog.url}">
+            <modules includes="${module.includes}.*" clusters="${download.clusters}"/>
+            <modules includes="org[.]netbeans[.]modules[.]apisupport[.]harness" clusters="harness"/>
+        </autoupdate>
+    </target>
+</project>
--- a/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Tue May 05 19:27:08 2015 +0200
@@ -1,7 +1,13 @@
 app.icon=branding/core/core.jar/org/netbeans/core/startup/frame48.gif
-app.name=idealgraphvisualizer
+app.name=${branding.token}
 app.title=IdealGraphVisualizer
-branding.token=${app.name}
+auxiliary.org-netbeans-modules-apisupport-installer.license-type=no
+auxiliary.org-netbeans-modules-apisupport-installer.os-linux=false
+auxiliary.org-netbeans-modules-apisupport-installer.os-macosx=true
+auxiliary.org-netbeans-modules-apisupport-installer.os-solaris=false
+auxiliary.org-netbeans-modules-apisupport-installer.os-windows=false
+auxiliary.org-netbeans-modules-apisupport-installer.pack200-enabled=false
+auxiliary.org-netbeans-spi-editor-hints-projects.perProjectHintSettingsFile=nbproject/cfg_hints.xml
 modules=\
     ${project.com.sun.hotspot.igv.graph}:\
     ${project.com.sun.hotspot.igv.coordinator}:\
@@ -18,7 +24,9 @@
     ${project.com.sun.hotspot.igv.svg}:\
     ${project.com.sun.hotspot.connection}:\
     ${project.com.sun.hotspot.igv.servercompilerscheduler}:\
-    ${project.com.sun.hotspot.igv.filterwindow}
+    ${project.com.sun.hotspot.igv.filterwindow}:\
+    ${project.com.sun.hotspot.igv.selectioncoordinator}:\
+    ${project.com.sun.hotspot.igv.graal}
 project.com.sun.hotspot.connection=NetworkConnection
 project.com.sun.hotspot.igv.bytecodes=Bytecodes
 project.com.sun.hotspot.igv.controlflow=ControlFlow
@@ -27,13 +35,18 @@
 project.com.sun.hotspot.igv.difference=Difference
 project.com.sun.hotspot.igv.filter=Filter
 project.com.sun.hotspot.igv.filterwindow=FilterWindow
+project.com.sun.hotspot.igv.graal=Graal
 project.com.sun.hotspot.igv.graph=Graph
 project.com.sun.hotspot.igv.hierarchicallayout=HierarchicalLayout
 project.com.sun.hotspot.igv.layout=Layout
+project.com.sun.hotspot.igv.selectioncoordinator=SelectionCoordinator
 project.com.sun.hotspot.igv.servercompilerscheduler=ServerCompiler
 project.com.sun.hotspot.igv.settings=Settings
 project.com.sun.hotspot.igv.svg=BatikSVGProxy
 project.com.sun.hotspot.igv.view=View
 project.com.sun.hotspot.igv.util=Util
-run.args = -J-server -J-Xms64m -J-Xmx1g -J-da
-run.args.extra = -J-server -J-Xms64m -J-Xmx1g -J-da
+
+# Disable assertions for RequestProcessor to prevent annoying messages in case
+# of multiple SceneAnimator update tasks in the default RequestProcessor.
+run.args.extra = -J-server -J-da:org.openide.util.RequestProcessor -J-Xms2g -J-Xmx8g -J-Djava.lang.Integer.IntegerCache.high=20000
+debug.args.extra = -J-server -J-da:org.openide.util.RequestProcessor
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -58,7 +58,7 @@
 const char *IdealGraphPrinter::GRAPH_NAME_PROPERTY = "name";
 const char *IdealGraphPrinter::INDEX_PROPERTY = "index";
 const char *IdealGraphPrinter::METHOD_ELEMENT = "method";
-const char *IdealGraphPrinter::INLINE_ELEMENT = "inline";
+const char *IdealGraphPrinter::INLINE_ELEMENT = "inlined";
 const char *IdealGraphPrinter::BYTECODES_ELEMENT = "bytecodes";
 const char *IdealGraphPrinter::METHOD_BCI_PROPERTY = "bci";
 const char *IdealGraphPrinter::METHOD_SHORT_NAME_PROPERTY = "shortName";
@@ -236,7 +236,6 @@
 }
 
 void IdealGraphPrinter::print_prop(const char *name, int val) {
-
   stringStream stream;
   stream.print("%d", val);
   print_prop(name, stream.as_string());
@@ -266,22 +265,22 @@
   end_head();
 
   head(BYTECODES_ELEMENT);
-  output()->print_cr("<![CDATA[");
-  method->print_codes_on(output());
-  output()->print_cr("]]>");
+  _xml->print_cr("<![CDATA[");
+  method->print_codes_on(_xml);
+  _xml->print_cr("]]>");
   tail(BYTECODES_ELEMENT);
 
-  head(INLINE_ELEMENT);
-  if (tree != NULL) {
+  if (tree != NULL && tree->subtrees().length() > 0) {
+    head(INLINE_ELEMENT);
     GrowableArray<InlineTree *> subtrees = tree->subtrees();
     for (int i = 0; i < subtrees.length(); i++) {
       print_inline_tree(subtrees.at(i));
     }
+    tail(INLINE_ELEMENT);
   }
-  tail(INLINE_ELEMENT);
 
   tail(METHOD_ELEMENT);
-  output()->flush();
+  _xml->flush();
 }
 
 void IdealGraphPrinter::print_inline_tree(InlineTree *tree) {
@@ -334,13 +333,7 @@
 
   tail(PROPERTIES_ELEMENT);
 
-  if (_stream) {
-    char answer = 0;
-    _xml->flush();
-    int result = _stream->read(&answer, 1);
-    _should_send_method = (answer == 'y');
-  }
-
+  _should_send_method = true;
   this->_current_method = method;
 
   _xml->flush();
@@ -358,7 +351,7 @@
 
 // Print indent
 void IdealGraphPrinter::print_indent() {
-  tty->print_cr("printing ident %d", _depth);
+  tty->print_cr("printing indent %d", _depth);
   for (int i = 0; i < _depth; i++) {
     _xml->print("%s", INDENT);
   }
@@ -372,22 +365,17 @@
   _traverse_outs = b;
 }
 
-intptr_t IdealGraphPrinter::get_node_id(Node *n) {
-  return (intptr_t)(n);
-}
-
 void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) {
 
   if (edges) {
 
     // Output edge
-    intptr_t dest_id = get_node_id(n);
+    node_idx_t dest_id = n->_idx;
     for ( uint i = 0; i < n->len(); i++ ) {
       if ( n->in(i) ) {
         Node *source = n->in(i);
         begin_elem(EDGE_ELEMENT);
-        intptr_t source_id = get_node_id(source);
-        print_attr(FROM_PROPERTY, source_id);
+        print_attr(FROM_PROPERTY, source->_idx);
         print_attr(TO_PROPERTY, dest_id);
         print_attr(INDEX_PROPERTY, i);
         end_elem();
@@ -398,7 +386,7 @@
 
     // Output node
     begin_head(NODE_ELEMENT);
-    print_attr(NODE_ID_PROPERTY, get_node_id(n));
+    print_attr(NODE_ID_PROPERTY, n->_idx);
     end_head();
 
     head(PROPERTIES_ELEMENT);
@@ -720,7 +708,7 @@
       head(NODES_ELEMENT);
       for (uint s = 0; s < block->number_of_nodes(); s++) {
         begin_elem(NODE_ELEMENT);
-        print_attr(NODE_ID_PROPERTY, get_node_id(block->get_node(s)));
+        print_attr(NODE_ID_PROPERTY, block->get_node(s)->_idx);
         end_elem();
       }
       tail(NODES_ELEMENT);
@@ -730,7 +718,7 @@
     tail(CONTROL_FLOW_ELEMENT);
   }
   tail(GRAPH_ELEMENT);
-  output()->flush();
+  _xml->flush();
 }
 
 // Should method be printed?
@@ -742,8 +730,4 @@
 
 extern const char *NodeClassNames[];
 
-outputStream *IdealGraphPrinter::output() {
-  return _xml;
-}
-
 #endif
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.hpp	Tue May 05 16:50:25 2015 +0200
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.hpp	Tue May 05 19:27:08 2015 +0200
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -127,7 +127,6 @@
 
   bool traverse_outs();
   void set_traverse_outs(bool b);
-  outputStream *output();
   void print_inlining(Compile* compile);
   void begin_method(Compile* compile);
   void end_method();