Merge
authorduke
Wed, 05 Jul 2017 16:38:46 +0200
changeset 801 9849c0c0d518
parent 800 9a19b12225f4 (current diff)
parent 782 f2e6591ff695 (diff)
child 803 99c469a305d2
Merge
hotspot/make/linux/Queens.class
hotspot/make/solaris/Queens.class
--- a/.hgtags-top-repo	Wed Jul 09 10:04:09 2008 -0700
+++ b/.hgtags-top-repo	Wed Jul 05 16:38:46 2017 +0200
@@ -4,3 +4,4 @@
 11b4dc9f2be3523ef989a0db8459eb56b3045c3a jdk7-b27
 56652b46f328937f6b9b5130f1e4cd80f48868ef jdk7-b28
 31e08f70e88d77c2053f91c21b49a04296bdc59a jdk7-b29
+2dab2f712e1832c92acfa63ec0337048b9422c20 jdk7-b30
--- a/hotspot/.hgignore	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/.hgignore	Wed Jul 05 16:38:46 2017 +0200
@@ -2,3 +2,6 @@
 ^dist/
 ^nbproject/private/
 ^src/share/tools/hsdis/bin/
+^src/share/tools/IdealGraphVisualizer/[a-zA-Z0-9]*/build/
+^src/share/tools/IdealGraphVisualizer/build/
+^src/share/tools/IdealGraphVisualizer/dist/
--- a/hotspot/.hgtags	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/.hgtags	Wed Jul 05 16:38:46 2017 +0200
@@ -4,3 +4,4 @@
 e3d2692f8442e2d951166dc9bd9a330684754438 jdk7-b27
 c14dab40ed9bf45ad21150bd70c9c80cdf655415 jdk7-b28
 4f91c08b3e4498213a9c5a24898f7d9c38cf86fb jdk7-b29
+d1605aabd0a15ecf93787c47de63073c33fba52d jdk7-b30
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ObjectHeap.java	Wed Jul 05 16:38:46 2017 +0200
@@ -316,6 +316,14 @@
     iterateLiveRegions(liveRegions, visitor, null);
   }
 
+  public boolean isValidMethod(OopHandle handle) {
+    OopHandle klass = Oop.getKlassForOopHandle(handle);
+    if (klass != null && klass.equals(methodKlassHandle)) {
+      return true;
+    }
+    return false;
+  }
+
   // Creates an instance from the Oop hierarchy based based on the handle
   public Oop newOop(OopHandle handle) {
     // The only known way to detect the right type of an oop is
@@ -375,8 +383,10 @@
       }
     }
 
-    System.err.println("Unknown oop at " + handle);
-    System.err.println("Oop's klass is " + klass);
+    if (DEBUG) {
+      System.err.println("Unknown oop at " + handle);
+      System.err.println("Oop's klass is " + klass);
+    }
 
     throw new UnknownOopException();
   }
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/JavaThread.java	Wed Jul 05 16:38:46 2017 +0200
@@ -215,11 +215,11 @@
     if (f == null) return null;
     boolean imprecise = true;
     if (f.isInterpretedFrame() && !f.isInterpretedFrameValid()) {
-      if (DEBUG) {
-        System.out.println("Correcting for invalid interpreter frame");
-      }
-      f = f.sender(regMap);
-      imprecise = false;
+       if (DEBUG) {
+         System.out.println("Correcting for invalid interpreter frame");
+       }
+       f = f.sender(regMap);
+       imprecise = false;
     }
     VFrame vf = VFrame.newVFrame(f, regMap, this, true, imprecise);
     if (vf == null) {
@@ -228,10 +228,7 @@
       }
       return null;
     }
-    if (vf.isJavaFrame()) {
-      return (JavaVFrame) vf;
-    }
-    return (JavaVFrame) vf.javaSender();
+    return vf.isJavaFrame() ? (JavaVFrame)vf : vf.javaSender();
   }
 
   /** In this system, a JavaThread is the top-level factory for a
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/solaris_sparc/SolarisSPARCJavaThreadPDAccess.java	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/solaris_sparc/SolarisSPARCJavaThreadPDAccess.java	Wed Jul 05 16:38:46 2017 +0200
@@ -121,6 +121,13 @@
   }
 
   public Frame getCurrentFrameGuess(JavaThread thread, Address addr) {
+
+    // If java stack is walkable then both last_Java_sp and last_Java_pc are
+    // non null and we can start stack walk from this frame.
+    if (thread.getLastJavaSP() != null && thread.getLastJavaPC() != null) {
+      return new SPARCFrame(SPARCFrame.biasSP(thread.getLastJavaSP()), thread.getLastJavaPC());
+    }
+
     ThreadProxy t = getThreadProxy(addr);
     SPARCThreadContext context = (SPARCThreadContext) t.getContext();
     // For now, let's see what happens if we do a similar thing to
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java	Wed Jul 05 16:38:46 2017 +0200
@@ -422,6 +422,13 @@
     if (getFP().addOffsetTo(INTERPRETER_FRAME_VM_LOCAL_WORDS * VM.getVM().getAddressSize()).lessThan(getSP())) {
       return false;
     }
+
+    OopHandle methodHandle = addressOfInterpreterFrameMethod().getOopHandleAt(0);
+
+    if (VM.getVM().getObjectHeap().isValidMethod(methodHandle) == false) {
+      return false;
+    }
+
     // These are hacks to keep us out of trouble.
     // The problem with these is that they mask other problems
     if (getFP().lessThanOrEqual(getSP())) {        // this attempts to deal with unsigned comparison above
@@ -433,9 +440,18 @@
     // FIXME: this is not atomic with respect to GC and is unsuitable
     // for use in a non-debugging, or reflective, system. Need to
     // figure out how to express this.
-    if (addressOfInterpreterFrameBCX().getAddressAt(0) == null) {
-      return false; // BCP not yet set up
+    Address bcx =  addressOfInterpreterFrameBCX().getAddressAt(0);
+
+    Method method;
+    try {
+       method = (Method) VM.getVM().getObjectHeap().newOop(methodHandle);
+    } catch (UnknownOopException ex) {
+       return false;
     }
+    int  bci = bcpToBci(bcx, method);
+    //validate bci
+    if (bci < 0) return false;
+
     return true;
   }
 
@@ -471,7 +487,7 @@
     // will update it accordingly
     map.setIncludeArgumentOops(false);
 
-    if (cb == null && isEntryFrame()) {
+    if (isEntryFrame()) {
       return senderForEntryFrame(map);
     }
 
@@ -539,7 +555,6 @@
         int SP_OFFSET_IN_GREGSET = 17;
         raw_sp = fp.getAddressAt(VM.getVM().getAddressSize() * SP_OFFSET_IN_GREGSET);
         Address pc = fp.getAddressAt(VM.getVM().getAddressSize() * PC_OFFSET_IN_GREGSET);
-        // System.out.println("  next frame's SP: " + sp + " PC: " + pc);
         return new SPARCFrame(raw_sp, pc);
       }
     }
@@ -562,10 +577,8 @@
       // sender's _interpreter_sp_adjustment field.
       if (VM.getVM().getInterpreter().contains(pc)) {
         isInterpreted = true;
-        if (VM.getVM().isClientCompiler()) {
-          map.makeIntegerRegsUnsaved();
-          map.shiftWindow(sp, youngerSP);
-        }
+        map.makeIntegerRegsUnsaved();
+        map.shiftWindow(sp, youngerSP);
       } else {
         // Find a CodeBlob containing this frame's pc or elide the lookup and use the
         // supplied blob which is already known to be associated with this frame.
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java	Wed Jul 05 16:38:46 2017 +0200
@@ -87,12 +87,13 @@
                while (f != null) {
                   ClosestSymbol sym = f.closestSymbolToPC();
                   Address pc = f.pc();
+                  out.print(pc + "\t");
                   if (sym != null) {
                      String name = sym.getName();
                      if (cdbgCanDemangle) {
                         name = cdbg.demangle(name);
                      }
-                     out.print(pc + "\t" + name);
+                     out.print(name);
                      long diff = sym.getOffset();
                      if (diff != 0L) {
                         out.print(" + 0x" + Long.toHexString(diff));
@@ -120,7 +121,6 @@
                            // look for known code blobs
                            CodeCache c = VM.getVM().getCodeCache();
                            if (c.contains(pc)) {
-                              out.print(pc + "\t");
                               CodeBlob cb = c.findBlobUnsafe(pc);
                               if (cb.isNMethod()) {
                                  names = getJavaNames(th, f.localVariableBase());
@@ -144,18 +144,18 @@
                                  out.println("<Unknown code blob>");
                               }
                            } else {
-                              printUnknown(out,pc);
+                              printUnknown(out);
                            }
                         }
                         // print java frames, if any
                         if (names != null && names.length != 0) {
                            // print java frame(s)
                            for (int i = 0; i < names.length; i++) {
-                               out.println(pc + "\t" + names[i]);
+                               out.println(names[i]);
                            }
                         }
                      } else {
-                        printUnknown(out,pc);
+                        printUnknown(out);
                      }
                   }
                   f = f.sender();
@@ -220,8 +220,8 @@
       }
    }
 
-   private void printUnknown(PrintStream out, Address pc) {
-      out.println(pc + "\t????????");
+   private void printUnknown(PrintStream out) {
+      out.println("\t????????");
    }
 
    private String[] getJavaNames(ThreadProxy th, Address fp) {
--- a/hotspot/make/defs.make	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/defs.make	Wed Jul 05 16:38:46 2017 +0200
@@ -228,6 +228,7 @@
 
 # Required make macro settings for all platforms
 MAKE_ARGS += JAVA_HOME=$(ABS_BOOTDIR)
+MAKE_ARGS += OUTPUTDIR=$(ABS_OUTPUTDIR)
 MAKE_ARGS += GAMMADIR=$(ABS_GAMMADIR)
 MAKE_ARGS += MAKE_VERBOSE=$(MAKE_VERBOSE)
 MAKE_ARGS += HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION)
--- a/hotspot/make/hotspot_version	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/hotspot_version	Wed Jul 05 16:38:46 2017 +0200
@@ -33,9 +33,9 @@
 # Don't put quotes (fail windows build).
 HOTSPOT_VM_COPYRIGHT=Copyright 2008
 
-HS_MAJOR_VER=13
+HS_MAJOR_VER=14
 HS_MINOR_VER=0
-HS_BUILD_NUMBER=02
+HS_BUILD_NUMBER=01
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
Binary file hotspot/make/linux/Queens.class has changed
--- a/hotspot/make/linux/makefiles/buildtree.make	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/linux/makefiles/buildtree.make	Wed Jul 05 16:38:46 2017 +0200
@@ -328,18 +328,19 @@
 WRONG_DATA_MODE_MSG = \
 	echo "JAVA_HOME must point to $(DATA_MODE)bit JDK."
 
-test_gamma:  $(BUILDTREE_MAKE)
+test_gamma:  $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
 	echo '#!/bin/sh'; \
 	$(BUILDTREE_COMMENT); \
 	echo '. ./env.sh'; \
 	echo "if [ -z \$$JAVA_HOME ]; then { $(NO_JAVA_HOME_MSG); exit 0; }; fi"; \
-	echo "if ! \$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion 2>1 > /dev/null"; \
+	echo "if ! \$${JAVA_HOME}/bin/java $(JAVA_FLAG) -fullversion 2>&1 > /dev/null"; \
 	echo "then"; \
 	echo "  $(WRONG_DATA_MODE_MSG); exit 0;"; \
 	echo "fi"; \
-	echo 'CLASSPATH="$(GAMMADIR)/make/$(OS_FAMILY):$$CLASSPATH"'; \
+	echo "rm -f Queens.class"; \
+	echo "\$${JAVA_HOME}/bin/javac -d . $(GAMMADIR)/make/test/Queens.java"; \
 	echo '[ -f gamma_g ] && { gamma=gamma_g; }'; \
 	echo './$${gamma:-gamma} $(TESTFLAGS) Queens < /dev/null'; \
 	) > $@
--- a/hotspot/make/linux/makefiles/gcc.make	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/linux/makefiles/gcc.make	Wed Jul 05 16:38:46 2017 +0200
@@ -50,14 +50,7 @@
 
 VM_PICFLAG/LIBJVM = $(PICFLAG)
 VM_PICFLAG/AOUT   =
-
-ifneq ($(BUILDARCH), i486)
 VM_PICFLAG        = $(VM_PICFLAG/$(LINK_INTO))
-else
-# PIC has significant overhead on x86, build nonpic VM for now.
-# Link JVM at a "good" base location to avoid unnecessary .text patching.
-JVM_BASE_ADDR     = 0x06000000
-endif
 
 CFLAGS += $(VM_PICFLAG)
 CFLAGS += -fno-rtti
@@ -91,8 +84,17 @@
 
 # Compiler warnings are treated as errors
 WARNINGS_ARE_ERRORS = -Werror
+
 # Except for a few acceptable ones
+# Since GCC 4.3, -Wconversion has changed its meanings to warn these implicit
+# conversions which might affect the values. To avoid that, we need to turn
+# it off explicitly. 
+ifneq "$(shell expr \( $(CC_VER_MAJOR) \> 4 \) \| \( \( $(CC_VER_MAJOR) = 4 \) \& \( $(CC_VER_MINOR) \>= 3 \) \))" "0"
+ACCEPTABLE_WARNINGS = -Wpointer-arith -Wsign-compare
+else
 ACCEPTABLE_WARNINGS = -Wpointer-arith -Wconversion -Wsign-compare
+endif
+
 CFLAGS_WARN/DEFAULT = $(WARNINGS_ARE_ERRORS) $(ACCEPTABLE_WARNINGS)
 # Special cases
 CFLAGS_WARN/BYFILE = $(CFLAGS_WARN/$@)$(CFLAGS_WARN/DEFAULT$(CFLAGS_WARN/$@)) 
--- a/hotspot/make/linux/makefiles/mapfile-vers-debug	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/linux/makefiles/mapfile-vers-debug	Wed Jul 05 16:38:46 2017 +0200
@@ -89,6 +89,7 @@
                 JVM_FillInStackTrace;
                 JVM_FindClassFromClass;
                 JVM_FindClassFromClassLoader;
+                JVM_FindClassFromBootLoader;
                 JVM_FindLibraryEntry;
                 JVM_FindLoadedClass;
                 JVM_FindPrimitiveClass;
--- a/hotspot/make/linux/makefiles/mapfile-vers-product	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/linux/makefiles/mapfile-vers-product	Wed Jul 05 16:38:46 2017 +0200
@@ -89,6 +89,7 @@
                 JVM_FillInStackTrace;
                 JVM_FindClassFromClass;
                 JVM_FindClassFromClassLoader;
+                JVM_FindClassFromBootLoader;
                 JVM_FindLibraryEntry;
                 JVM_FindLoadedClass;
                 JVM_FindPrimitiveClass;
--- a/hotspot/make/linux/makefiles/rules.make	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/linux/makefiles/rules.make	Wed Jul 05 16:38:46 2017 +0200
@@ -133,10 +133,25 @@
 COMPILE_DONE    = && { echo Done with $<; }
 endif
 
+# Include $(NONPIC_OBJ_FILES) definition
+ifndef LP64
+include $(GAMMADIR)/make/pic.make
+endif
+
+# The non-PIC object files are only generated for 32 bit platforms.
+ifdef LP64
 %.o: %.cpp
 	@echo Compiling $<
 	$(QUIETLY) $(REMOVE_TARGET)
 	$(QUIETLY) $(COMPILE.CC) -o $@ $< $(COMPILE_DONE)
+else
+%.o: %.cpp
+	@echo Compiling $<
+	$(QUIETLY) $(REMOVE_TARGET)
+	$(QUIETLY) $(if $(findstring $@, $(NONPIC_OBJ_FILES)), \
+	   $(subst $(VM_PICFLAG), ,$(COMPILE.CC)) -o $@ $< $(COMPILE_DONE), \
+	   $(COMPILE.CC) -o $@ $< $(COMPILE_DONE))
+endif
 
 %.o: %.s
 	@echo Assembling $<
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/make/pic.make	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,41 @@
+#
+# Copyright 2006-2007 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+# CA 95054 USA or visit www.sun.com if you need additional information or
+# have any questions.
+#  
+#
+
+# A list of object files built without the platform specific PIC flags, e.g.
+# -fPIC on linux. Performance measurements show that by compiling GC related 
+# code, we could significantly reduce the GC pause time on 32 bit Linux/Unix
+# platforms. See 6454213 for more details.
+include $(GAMMADIR)/make/scm.make
+
+ifneq ($(OSNAME), windows)
+  ifndef LP64
+    NONPIC_DIRS  = memory oops gc_implementation gc_interface 
+    NONPIC_DIRS  := $(foreach dir,$(NONPIC_DIRS), $(GAMMADIR)/src/share/vm/$(dir))
+    # Look for source files under NONPIC_DIRS
+    NONPIC_FILES := $(foreach dir,$(NONPIC_DIRS),\
+                      $(shell find $(dir) \( $(SCM_DIRS) \) -prune -o \
+		      -name '*.cpp' -print))
+    NONPIC_OBJ_FILES := $(notdir $(subst .cpp,.o,$(NONPIC_FILES)))
+  endif
+endif
Binary file hotspot/make/solaris/Queens.class has changed
--- a/hotspot/make/solaris/makefiles/buildtree.make	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/solaris/makefiles/buildtree.make	Wed Jul 05 16:38:46 2017 +0200
@@ -340,7 +340,7 @@
 WRONG_DATA_MODE_MSG = \
 	echo "JAVA_HOME must point to $(DATA_MODE)bit JDK."
 
-test_gamma:  $(BUILDTREE_MAKE)
+test_gamma:  $(BUILDTREE_MAKE) $(GAMMADIR)/make/test/Queens.java
 	@echo Creating $@ ...
 	$(QUIETLY) ( \
 	echo '#!/bin/ksh'; \
@@ -351,7 +351,8 @@
 	echo "then"; \
 	echo "  $(WRONG_DATA_MODE_MSG); exit 0;"; \
 	echo "fi"; \
-	echo 'CLASSPATH="$(GAMMADIR)/make/$(OS_FAMILY):$$CLASSPATH"'; \
+	echo "rm -f Queens.class"; \
+	echo "\$${JAVA_HOME}/bin/javac -d . $(GAMMADIR)/make/test/Queens.java"; \
 	echo '[ -f gamma_g ] && { gamma=gamma_g; }'; \
 	echo './$${gamma:-gamma} $(TESTFLAGS) Queens < /dev/null'; \
 	) > $@
--- a/hotspot/make/solaris/makefiles/jvmg.make	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/solaris/makefiles/jvmg.make	Wed Jul 05 16:38:46 2017 +0200
@@ -30,7 +30,7 @@
 
 ifeq ("${Platform_compiler}", "sparcWorks")
 
-ifeq ($(COMPILER_REV),5.8))
+ifeq ($(COMPILER_REV),5.8)
   # SS11 SEGV when compiling with -g and -xarch=v8, using different backend
   DEBUG_CFLAGS/compileBroker.o = $(DEBUG_CFLAGS) -xO0
   DEBUG_CFLAGS/jvmtiTagMap.o   = $(DEBUG_CFLAGS) -xO0
--- a/hotspot/make/solaris/makefiles/mapfile-vers	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/solaris/makefiles/mapfile-vers	Wed Jul 05 16:38:46 2017 +0200
@@ -89,6 +89,7 @@
 		JVM_FillInStackTrace;
 		JVM_FindClassFromClass;
 		JVM_FindClassFromClassLoader;
+		JVM_FindClassFromBootLoader;
 		JVM_FindLibraryEntry;
 		JVM_FindLoadedClass;
 		JVM_FindPrimitiveClass;
--- a/hotspot/make/solaris/makefiles/reorder_COMPILER1_i486	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/solaris/makefiles/reorder_COMPILER1_i486	Wed Jul 05 16:38:46 2017 +0200
@@ -2175,6 +2175,7 @@
 text: .text%jni_GetStringUTFRegion: jni.o;
 text: .text%__1cQjava_lang_StringOas_utf8_string6FpnHoopDesc_ii_pc_;
 text: .text%JVM_FindClassFromClassLoader;
+text: .text%JVM_FindClassFromBootLoader;
 text: .text%JVM_IsInterface;
 text: .text%JVM_GetClassDeclaredConstructors;
 text: .text%__1cNmethodOopDescOis_initializer6kM_i_;
--- a/hotspot/make/solaris/makefiles/reorder_COMPILER1_sparc	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/solaris/makefiles/reorder_COMPILER1_sparc	Wed Jul 05 16:38:46 2017 +0200
@@ -1500,6 +1500,7 @@
 text: .text%jni_GetStringUTFRegion: jni.o;
 text: .text%__1cQjava_lang_StringOas_utf8_string6FpnHoopDesc_ii_pc_;
 text: .text%JVM_FindClassFromClassLoader;
+text: .text%JVM_FindClassFromBootLoader;
 text: .text%JVM_IsInterface;
 text: .text%JVM_GetClassDeclaredConstructors;
 text: .text%__1cNmethodOopDescOis_initializer6kM_i_;
--- a/hotspot/make/solaris/makefiles/reorder_COMPILER2_amd64	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/solaris/makefiles/reorder_COMPILER2_amd64	Wed Jul 05 16:38:46 2017 +0200
@@ -4339,6 +4339,7 @@
 text: .text%__1cFParseLarray_store6MnJBasicType__v_;
 text: .text%__1cOmangle_name_on6FpnMoutputStream_pnNsymbolOopDesc_ii_v_: nativeLookup.o;
 text: .text%JVM_FindClassFromClassLoader;
+text: .text%JVM_FindClassFromBootLoader;
 text: .text%__1cZCallInterpreterDirectNodeSalignment_required6kM_i_;
 text: .text%__1cZCallInterpreterDirectNodePoper_input_base6kM_I_;
 text: .text%__1cZCallInterpreterDirectNodeEemit6kMrnKCodeBuffer_pnNPhaseRegAlloc__v_;
--- a/hotspot/make/solaris/makefiles/reorder_COMPILER2_i486	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/solaris/makefiles/reorder_COMPILER2_i486	Wed Jul 05 16:38:46 2017 +0200
@@ -4755,6 +4755,7 @@
 text: .text%__1cITemplateKinitialize6MinITosState_1pFi_vi_v_;
 text: .text%__1cNTemplateTableDdef6FnJBytecodesECode_inITosState_3pFi_vi_v_;
 text: .text%JVM_FindClassFromClassLoader;
+text: .text%JVM_FindClassFromBootLoader;
 text: .text%__1cPshrI_eReg_1NodeEsize6kMpnNPhaseRegAlloc__I_;
 text: .text%__1cHi2bNodeMideal_Opcode6kM_i_: ad_i486_misc.o;
 text: .text%__1cMmatch_option6FpknMJavaVMOption_pkcp4_i_: arguments.o;
--- a/hotspot/make/solaris/makefiles/reorder_COMPILER2_sparc	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/solaris/makefiles/reorder_COMPILER2_sparc	Wed Jul 05 16:38:46 2017 +0200
@@ -3713,6 +3713,7 @@
 text: .text%__1cITemplateIgenerate6MpnZInterpreterMacroAssembler__v_;
 text: .text%__1cQregI_to_stkINodeHis_Copy6kM_I_: ad_sparc_misc.o;
 text: .text%JVM_FindClassFromClassLoader;
+text: .text%JVM_FindClassFromBootLoader;
 text: .text%signalHandler;
 text: .text%__1cTtypeArrayKlassKlassIoop_size6kMpnHoopDesc__i_: typeArrayKlassKlass.o;
 text: .text%JVM_handle_solaris_signal;
--- a/hotspot/make/solaris/makefiles/reorder_COMPILER2_sparcv9	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/solaris/makefiles/reorder_COMPILER2_sparcv9	Wed Jul 05 16:38:46 2017 +0200
@@ -3735,6 +3735,7 @@
 text: .text%__1cQjava_lang_ThreadRget_thread_status6FpnHoopDesc__n0AMThreadStatus__;
 text: .text%__1cIMulINodeGadd_id6kM_pknEType__: classes.o;
 text: .text%JVM_FindClassFromClassLoader;
+text: .text%JVM_FindClassFromBootLoader;
 text: .text%__1cHTypePtrFempty6kM_i_;
 text: .text%__1cQaddP_reg_regNodeEsize6kMpnNPhaseRegAlloc__I_;
 text: .text%__1cbFunnecessary_membar_volatileNodePoper_input_base6kM_I_: ad_sparc_misc.o;
--- a/hotspot/make/solaris/makefiles/reorder_TIERED_amd64	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/solaris/makefiles/reorder_TIERED_amd64	Wed Jul 05 16:38:46 2017 +0200
@@ -4339,6 +4339,7 @@
 text: .text%__1cFParseLarray_store6MnJBasicType__v_;
 text: .text%__1cOmangle_name_on6FpnMoutputStream_pnNsymbolOopDesc_ii_v_: nativeLookup.o;
 text: .text%JVM_FindClassFromClassLoader;
+text: .text%JVM_FindClassFromBootLoader;
 text: .text%__1cZCallInterpreterDirectNodeSalignment_required6kM_i_;
 text: .text%__1cZCallInterpreterDirectNodePoper_input_base6kM_I_;
 text: .text%__1cZCallInterpreterDirectNodeEemit6kMrnKCodeBuffer_pnNPhaseRegAlloc__v_;
--- a/hotspot/make/solaris/makefiles/reorder_TIERED_i486	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/solaris/makefiles/reorder_TIERED_i486	Wed Jul 05 16:38:46 2017 +0200
@@ -4755,6 +4755,7 @@
 text: .text%__1cITemplateKinitialize6MinITosState_1pFi_vi_v_;
 text: .text%__1cNTemplateTableDdef6FnJBytecodesECode_inITosState_3pFi_vi_v_;
 text: .text%JVM_FindClassFromClassLoader;
+text: .text%JVM_FindClassFromBootLoader;
 text: .text%__1cPshrI_eReg_1NodeEsize6kMpnNPhaseRegAlloc__I_;
 text: .text%__1cHi2bNodeMideal_Opcode6kM_i_: ad_i486_misc.o;
 text: .text%__1cMmatch_option6FpknMJavaVMOption_pkcp4_i_: arguments.o;
--- a/hotspot/make/solaris/makefiles/reorder_TIERED_sparc	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/solaris/makefiles/reorder_TIERED_sparc	Wed Jul 05 16:38:46 2017 +0200
@@ -3713,6 +3713,7 @@
 text: .text%__1cITemplateIgenerate6MpnZInterpreterMacroAssembler__v_;
 text: .text%__1cQregI_to_stkINodeHis_Copy6kM_I_: ad_sparc_misc.o;
 text: .text%JVM_FindClassFromClassLoader;
+text: .text%JVM_FindClassFromBootLoader;
 text: .text%signalHandler;
 text: .text%__1cTtypeArrayKlassKlassIoop_size6kMpnHoopDesc__i_: typeArrayKlassKlass.o;
 text: .text%JVM_handle_solaris_signal;
--- a/hotspot/make/solaris/makefiles/rules.make	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/solaris/makefiles/rules.make	Wed Jul 05 16:38:46 2017 +0200
@@ -133,19 +133,10 @@
 COMPILE_DONE    = && { echo Done with $<; }
 endif
 
-# A list of directories under which all source code are built without -KPIC/-Kpic
-# flag. Performance measurements show that compiling GC related code will
-# dramatically reduce the gc pause time. See bug 6454213 for more details.
-
-include $(GAMMADIR)/make/scm.make
-
-NONPIC_DIRS  = memory oops gc_implementation gc_interface 
-NONPIC_DIRS  := $(foreach dir,$(NONPIC_DIRS), $(GAMMADIR)/src/share/vm/$(dir))
-# Look for source code under NONPIC_DIRS
-NONPIC_FILES := $(foreach dir,$(NONPIC_DIRS),\
-                 $(shell find $(dir) \( $(SCM_DIRS) \) -prune -o \
-		  -name '*.cpp' -print))
-NONPIC_OBJ_FILES := $(notdir $(subst .cpp,.o,$(NONPIC_FILES)))
+# Include NONPIC_OBJ_FILES definition
+ifndef LP64
+include $(GAMMADIR)/make/pic.make
+endif
 
 # Sun compiler for 64 bit Solaris does not support building non-PIC object files.
 ifdef LP64
--- a/hotspot/make/windows/makefiles/vm.make	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/make/windows/makefiles/vm.make	Wed Jul 05 16:38:46 2017 +0200
@@ -88,13 +88,20 @@
 !endif
 !endif
 
-LINK_FLAGS=$(LINK_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000  \
-  /export:JNI_GetDefaultJavaVMInitArgs /export:JNI_CreateJavaVM    \
-  /export:JNI_GetCreatedJavaVMs /export:jio_snprintf               \
-  /export:jio_printf /export:jio_fprintf                           \
-  /export:jio_vfprintf /export:jio_vsnprintf $(AGCT_EXPORT)        \
-  /export:JVM_GetVersionInfo \
-  /export:JVM_GetThreadStateNames /export:JVM_GetThreadStateValues \
+LINK_FLAGS=$(LINK_FLAGS) $(STACK_SIZE) /subsystem:windows /dll /base:0x8000000 \
+  /export:JNI_GetDefaultJavaVMInitArgs       \
+  /export:JNI_CreateJavaVM                   \
+  /export:JVM_FindClassFromBootLoader        \
+  /export:JNI_GetCreatedJavaVMs              \
+  /export:jio_snprintf                       \
+  /export:jio_printf                         \
+  /export:jio_fprintf                        \
+  /export:jio_vfprintf                       \
+  /export:jio_vsnprintf                      \
+  $(AGCT_EXPORT)                             \
+  /export:JVM_GetVersionInfo                 \
+  /export:JVM_GetThreadStateNames            \
+  /export:JVM_GetThreadStateValues           \
   /export:JVM_InitAgentProperties
 
 CPP_INCLUDE_DIRS=\
--- a/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad	Wed Jul 05 16:38:46 2017 +0200
@@ -5955,7 +5955,7 @@
 
 // Convert oop pointer into compressed form
 instruct encodeHeapOop(iRegN dst, iRegP src) %{
-  predicate(n->bottom_type()->is_narrowoop()->make_oopptr()->ptr() != TypePtr::NotNull);
+  predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
   match(Set dst (EncodeP src));
   format %{ "encode_heap_oop $src, $dst" %}
   ins_encode %{
@@ -5965,7 +5965,7 @@
 %}
 
 instruct encodeHeapOop_not_null(iRegN dst, iRegP src) %{
-  predicate(n->bottom_type()->is_narrowoop()->make_oopptr()->ptr() == TypePtr::NotNull);
+  predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
   match(Set dst (EncodeP src));
   format %{ "encode_heap_oop_not_null $src, $dst" %}
   ins_encode %{
--- a/hotspot/src/cpu/x86/vm/vm_version_x86_32.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86_32.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -307,6 +307,10 @@
       // Use it on new AMD cpus starting from Opteron.
       UseAddressNop = true;
     }
+    if( supports_sse2() && FLAG_IS_DEFAULT(UseNewLongLShift) ) {
+      // Use it on new AMD cpus starting from Opteron.
+      UseNewLongLShift = true;
+    }
     if( FLAG_IS_DEFAULT(UseXmmLoadAndClearUpper) ) {
       if( supports_sse4a() ) {
         UseXmmLoadAndClearUpper = true; // use movsd only on '10h' Opteron
--- a/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad	Wed Jul 05 16:38:46 2017 +0200
@@ -4754,6 +4754,33 @@
   interface(CONST_INTER);
 %}
 
+operand immI_1() %{
+  predicate( n->get_int() == 1 );
+  match(ConI);
+
+  op_cost(0);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
+operand immI_2() %{
+  predicate( n->get_int() == 2 );
+  match(ConI);
+
+  op_cost(0);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
+operand immI_3() %{
+  predicate( n->get_int() == 3 );
+  match(ConI);
+
+  op_cost(0);
+  format %{ %}
+  interface(CONST_INTER);
+%}
+
 // Pointer Immediate
 operand immP() %{
   match(ConP);
@@ -8943,6 +8970,63 @@
   ins_pipe( ialu_reg_long_mem );
 %}
 
+// Shift Left Long by 1
+instruct shlL_eReg_1(eRegL dst, immI_1 cnt, eFlagsReg cr) %{
+  predicate(UseNewLongLShift);
+  match(Set dst (LShiftL dst cnt));
+  effect(KILL cr);
+  ins_cost(100);
+  format %{ "ADD    $dst.lo,$dst.lo\n\t"
+            "ADC    $dst.hi,$dst.hi" %}
+  ins_encode %{
+    __ addl($dst$$Register,$dst$$Register);
+    __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
+  %}
+  ins_pipe( ialu_reg_long );
+%}
+
+// Shift Left Long by 2
+instruct shlL_eReg_2(eRegL dst, immI_2 cnt, eFlagsReg cr) %{
+  predicate(UseNewLongLShift);
+  match(Set dst (LShiftL dst cnt));
+  effect(KILL cr);
+  ins_cost(100);
+  format %{ "ADD    $dst.lo,$dst.lo\n\t"
+            "ADC    $dst.hi,$dst.hi\n\t" 
+            "ADD    $dst.lo,$dst.lo\n\t"
+            "ADC    $dst.hi,$dst.hi" %}
+  ins_encode %{
+    __ addl($dst$$Register,$dst$$Register);
+    __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
+    __ addl($dst$$Register,$dst$$Register);
+    __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
+  %}
+  ins_pipe( ialu_reg_long );
+%}
+
+// Shift Left Long by 3
+instruct shlL_eReg_3(eRegL dst, immI_3 cnt, eFlagsReg cr) %{
+  predicate(UseNewLongLShift);
+  match(Set dst (LShiftL dst cnt));
+  effect(KILL cr);
+  ins_cost(100);
+  format %{ "ADD    $dst.lo,$dst.lo\n\t"
+            "ADC    $dst.hi,$dst.hi\n\t" 
+            "ADD    $dst.lo,$dst.lo\n\t"
+            "ADC    $dst.hi,$dst.hi\n\t" 
+            "ADD    $dst.lo,$dst.lo\n\t"
+            "ADC    $dst.hi,$dst.hi" %}
+  ins_encode %{
+    __ addl($dst$$Register,$dst$$Register);
+    __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
+    __ addl($dst$$Register,$dst$$Register);
+    __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
+    __ addl($dst$$Register,$dst$$Register);
+    __ adcl(HIGH_FROM_LOW($dst$$Register),HIGH_FROM_LOW($dst$$Register));
+  %}
+  ins_pipe( ialu_reg_long );
+%}
+
 // Shift Left Long by 1-31
 instruct shlL_eReg_1_31(eRegL dst, immI_1_31 cnt, eFlagsReg cr) %{
   match(Set dst (LShiftL dst cnt));
--- a/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad	Wed Jul 05 16:38:46 2017 +0200
@@ -7060,7 +7060,7 @@
 
 // Convert oop pointer into compressed form
 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
-  predicate(n->bottom_type()->is_narrowoop()->make_oopptr()->ptr() != TypePtr::NotNull);
+  predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
   match(Set dst (EncodeP src));
   effect(KILL cr);
   format %{ "encode_heap_oop $dst,$src" %}
@@ -7076,7 +7076,7 @@
 %}
 
 instruct encodeHeapOop_not_null(rRegN dst, rRegP src, rFlagsReg cr) %{
-  predicate(n->bottom_type()->is_narrowoop()->make_oopptr()->ptr() == TypePtr::NotNull);
+  predicate(n->bottom_type()->make_ptr()->ptr() == TypePtr::NotNull);
   match(Set dst (EncodeP src));
   effect(KILL cr);
   format %{ "encode_heap_oop_not_null $dst,$src" %}
--- a/hotspot/src/os/linux/vm/hpi_linux.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/os/linux/vm/hpi_linux.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -70,6 +70,10 @@
   RESTARTABLE_RETURN_INT(::send(fd, buf, nBytes, (unsigned int) flags));
 }
 
+inline int hpi::raw_send(int fd, char *buf, int nBytes, int flags) {
+  return send(fd, buf, nBytes, flags);
+}
+
 inline int hpi::timeout(int fd, long timeout) {
   julong prevtime,newtime;
   struct timeval t;
--- a/hotspot/src/os/linux/vm/jvm_linux.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/os/linux/vm/jvm_linux.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -132,7 +132,7 @@
 */
 
 struct siglabel {
-  char *name;
+  const char *name;
   int   number;
 };
 
--- a/hotspot/src/os/linux/vm/os_linux.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -75,8 +75,8 @@
 bool os::Linux::_is_floating_stack = false;
 bool os::Linux::_is_NPTL = false;
 bool os::Linux::_supports_fast_thread_cpu_time = false;
-char * os::Linux::_glibc_version = NULL;
-char * os::Linux::_libpthread_version = NULL;
+const char * os::Linux::_glibc_version = NULL;
+const char * os::Linux::_libpthread_version = NULL;
 
 static jlong initial_time_count=0;
 
@@ -213,9 +213,9 @@
 // the system call returns 1.  This causes the VM to act as if it is
 // a single processor and elide locking (see is_MP() call).
 static bool unsafe_chroot_detected = false;
-static char *unstable_chroot_error = "/proc file system not found.\n"
-              "Java may be unstable running multithreaded in a chroot "
-              "environment on Linux when /proc filesystem is not mounted.";
+static const char *unstable_chroot_error = "/proc file system not found.\n"
+                     "Java may be unstable running multithreaded in a chroot "
+                     "environment on Linux when /proc filesystem is not mounted.";
 
 void os::Linux::initialize_system_info() {
   _processor_count = sysconf(_SC_NPROCESSORS_CONF);
@@ -544,26 +544,23 @@
   if (n > 0) {
      char *str = (char *)malloc(n);
      confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n);
-
      // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells
      // us "NPTL-0.29" even we are running with LinuxThreads. Check if this
-     // is the case:
+     // is the case. LinuxThreads has a hard limit on max number of threads.
+     // So sysconf(_SC_THREAD_THREADS_MAX) will return a positive value.
+     // On the other hand, NPTL does not have such a limit, sysconf()
+     // will return -1 and errno is not changed. Check if it is really NPTL.
      if (strcmp(os::Linux::glibc_version(), "glibc 2.3.2") == 0 &&
-         strstr(str, "NPTL")) {
-        // LinuxThreads has a hard limit on max number of threads. So
-        // sysconf(_SC_THREAD_THREADS_MAX) will return a positive value.
-        // On the other hand, NPTL does not have such a limit, sysconf()
-        // will return -1 and errno is not changed. Check if it is really
-        // NPTL:
-        if (sysconf(_SC_THREAD_THREADS_MAX) > 0) {
-           free(str);
-           str = "linuxthreads";
-        }
+         strstr(str, "NPTL") &&
+         sysconf(_SC_THREAD_THREADS_MAX) > 0) {
+       free(str);
+       os::Linux::set_libpthread_version("linuxthreads");
+     } else {
+       os::Linux::set_libpthread_version(str);
      }
-     os::Linux::set_libpthread_version(str);
   } else {
-     // glibc before 2.3.2 only has LinuxThreads.
-     os::Linux::set_libpthread_version("linuxthreads");
+    // glibc before 2.3.2 only has LinuxThreads.
+    os::Linux::set_libpthread_version("linuxthreads");
   }
 
   if (strstr(libpthread_version(), "NPTL")) {
@@ -4632,11 +4629,7 @@
 // Unlike system(), this function can be called from signal handler. It
 // doesn't block SIGINT et al.
 int os::fork_and_exec(char* cmd) {
-  char * argv[4];
-  argv[0] = "sh";
-  argv[1] = "-c";
-  argv[2] = cmd;
-  argv[3] = NULL;
+  const char * argv[4] = {"sh", "-c", cmd, NULL};
 
   // fork() in LinuxThreads/NPTL is not async-safe. It needs to run
   // pthread_atfork handlers and reset pthread library. All we need is a
@@ -4661,7 +4654,7 @@
     // IA64 should use normal execve() from glibc to match the glibc fork()
     // above.
     NOT_IA64(syscall(__NR_execve, "/bin/sh", argv, environ);)
-    IA64_ONLY(execve("/bin/sh", argv, environ);)
+    IA64_ONLY(execve("/bin/sh", (char* const*)argv, environ);)
 
     // execve failed
     _exit(-1);
--- a/hotspot/src/os/linux/vm/os_linux.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/os/linux/vm/os_linux.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -52,8 +52,8 @@
   static address   _initial_thread_stack_bottom;
   static uintptr_t _initial_thread_stack_size;
 
-  static char *_glibc_version;
-  static char *_libpthread_version;
+  static const char *_glibc_version;
+  static const char *_libpthread_version;
 
   static bool _is_floating_stack;
   static bool _is_NPTL;
@@ -72,8 +72,8 @@
   static julong physical_memory() { return _physical_memory; }
   static void initialize_system_info();
 
-  static void set_glibc_version(char *s)      { _glibc_version = s; }
-  static void set_libpthread_version(char *s) { _libpthread_version = s; }
+  static void set_glibc_version(const char *s)      { _glibc_version = s; }
+  static void set_libpthread_version(const char *s) { _libpthread_version = s; }
 
   static bool supports_variable_stack_size();
 
@@ -134,8 +134,8 @@
   static bool chained_handler(int sig, siginfo_t* siginfo, void* context);
 
   // GNU libc and libpthread version strings
-  static char *glibc_version()                { return _glibc_version; }
-  static char *libpthread_version()           { return _libpthread_version; }
+  static const char *glibc_version()          { return _glibc_version; }
+  static const char *libpthread_version()     { return _libpthread_version; }
 
   // NPTL or LinuxThreads?
   static bool is_LinuxThreads()               { return !_is_NPTL; }
--- a/hotspot/src/os/solaris/vm/hpi_solaris.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/os/solaris/vm/hpi_solaris.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -71,6 +71,10 @@
   INTERRUPTIBLE_RETURN_INT(::send(fd, buf, nBytes, flags), os::Solaris::clear_interrupted);
 }
 
+inline int    hpi::raw_send(int fd, char *buf, int nBytes, int flags) {
+  RESTARTABLE_RETURN_INT(::send(fd, buf, nBytes, flags));
+}
+
 // As both poll and select can be interrupted by signals, we have to be
 // prepared to restart the system call after updating the timeout, unless
 // a poll() is done with timeout == -1, in which case we repeat with this
--- a/hotspot/src/os/windows/vm/hpi_windows.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/os/windows/vm/hpi_windows.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -102,6 +102,10 @@
          fd, buf, nBytes, flags),
         (fd, buf, nBytes, flags));
 
+inline int hpi::raw_send(int fd, char *buf, int nBytes, int flags) {
+  return send(fd, buf, nBytes, flags);
+}
+
 HPIDECL(timeout, "timeout", _socket, Timeout, int, "%d",
         (int fd, long timeout),
         ("fd = %d, timeout = %ld", fd, timeout),
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/build.xml	Wed Jul 05 16:38:46 2017 +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.svg" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.svg.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.svg
+OpenIDE-Module-Layer: com/sun/hotspot/igv/svg/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/svg/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.svg-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,14 @@
+<?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.svg</code-name-base>
+            <suite-component/>
+            <module-dependencies/>
+            <public-packages>
+                <package>com.sun.hotspot.igv.svg</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/BatikSVG.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.svg;
+
+import java.awt.Graphics2D;
+import java.io.Writer;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import org.w3c.dom.DOMImplementation;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class 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;
+
+    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);
+            }
+            DOMImplementation dom = (DOMImplementation) Method_getDOMImplementation.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);
+            Graphics2D svgGenerator = (Graphics2D) SVGGraphics2DConstructor.newInstance(ctx, true);
+            return svgGenerator;
+        } catch (ClassNotFoundException e) {
+            return null;
+        } catch (NoSuchMethodException e) {
+            return null;
+        } catch (IllegalAccessException e) {
+            return null;
+        } catch (InvocationTargetException e) {
+            return null;
+        } catch (InstantiationException e) {
+            return null;
+        }
+    }
+
+    public static void printToStream(Graphics2D svgGenerator, Writer stream, boolean useCSS) {
+        try {
+            Method_stream.invoke(svgGenerator, stream, useCSS);
+        } catch (IllegalAccessException e) {
+            assert false;
+        } catch (InvocationTargetException e) {
+            assert false;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=BatikSVGProxy
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/BatikSVGProxy/src/com/sun/hotspot/igv/svg/layer.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,4 @@
+<?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/Bytecodes/build.xml	Wed Jul 05 16:38:46 2017 +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.bytecodes" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.bytecodes.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +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
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.bytecodes-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=1dee290d
+build.xml.script.CRC32=d594034f
+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=1dee290d
+nbproject/build-impl.xml.script.CRC32=b4dab126
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,62 @@
+<?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.bytecodes</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>org.jdesktop.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.4</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.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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,5 @@
+CTL_BytecodeViewAction=Open BytecodeView Window
+CTL_BytecodeViewTopComponent=BytecodeView Window
+CTL_SelectBytecodesAction=Select nodes
+HINT_BytecodeViewTopComponent=This is a BytecodeView window
+OpenIDE-Module-Name=Bytecodes
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeNode.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.InputBytecode;
+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.Image;
+import java.util.HashSet;
+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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class BytecodeNode extends AbstractNode {
+
+    private Set<InputNode> nodes;
+
+    public BytecodeNode(InputBytecode bytecode, InputGraph graph, String bciValue) {
+
+        super(Children.LEAF);
+        this.setDisplayName(bytecode.getBci() + " " + bytecode.getName());
+
+        bciValue = bytecode.getBci() + " " + bciValue;
+        bciValue = bciValue.trim();
+
+        Properties.PropertySelector<InputNode> selector = new Properties.PropertySelector<InputNode>(graph.getNodes());
+        StringPropertyMatcher matcher = new StringPropertyMatcher("bci", bciValue);
+        List<InputNode> nodeList = selector.selectMultiple(matcher);
+        if (nodeList.size() > 0) {
+            nodes = new HashSet<InputNode>();
+            for (InputNode n : nodeList) {
+                nodes.add(n);
+            }
+            this.setDisplayName(this.getDisplayName() + " (" + nodes.size() + " nodes)");
+        }
+    }
+
+    @Override
+    public Image getIcon(int i) {
+        if (nodes != null) {
+            return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/link.gif");
+        } else {
+            return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/bytecode.gif");
+        }
+    }
+
+    @Override
+    public Image getOpenedIcon(int i) {
+        return getIcon(i);
+    }
+
+    @Override
+    public Action[] getActions(boolean b) {
+        return new Action[]{(Action) SelectBytecodesAction.findObject(SelectBytecodesAction.class, true)};
+    }
+
+    @Override
+    public Action getPreferredAction() {
+        return (Action) SelectBytecodesAction.findObject(SelectBytecodesAction.class, true);
+    }
+
+    @Override
+    public <T extends Node.Cookie> T getCookie(Class<T> aClass) {
+        if (aClass == SelectBytecodesCookie.class && nodes != null) {
+            return (T) (new SelectBytecodesCookie(nodes));
+        }
+        return super.getCookie(aClass);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.bytecodes;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+
+/**
+ * @author Thomas Wuerthinger
+ */
+public class BytecodeViewAction extends AbstractAction {
+
+    public BytecodeViewAction() {
+        super(NbBundle.getMessage(BytecodeViewAction.class, "CTL_BytecodeViewAction"));
+    }
+
+    public void actionPerformed(ActionEvent evt) {
+        TopComponent win = BytecodeViewTopComponent.findInstance();
+        win.open();
+        win.requestActive();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.form	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-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_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"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="400" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="300" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponent.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.Group;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import java.awt.BorderLayout;
+import java.io.Serializable;
+import org.openide.ErrorManager;
+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.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+/**
+ * @author Thomas Wuerthinger
+ */
+final class BytecodeViewTopComponent extends TopComponent implements ExplorerManager.Provider, LookupListener {
+
+    private static BytecodeViewTopComponent instance;
+    private static final String PREFERRED_ID = "BytecodeViewTopComponent";
+    private ExplorerManager manager;
+    private BeanTreeView treeView;
+    private Lookup.Result result = null;
+    private MethodNode rootNode;
+
+    private BytecodeViewTopComponent() {
+        initComponents();
+        setName(NbBundle.getMessage(BytecodeViewTopComponent.class, "CTL_BytecodeViewTopComponent"));
+        setToolTipText(NbBundle.getMessage(BytecodeViewTopComponent.class, "HINT_BytecodeViewTopComponent"));
+
+        manager = new ExplorerManager();
+        rootNode = new MethodNode(null, null, "");
+        manager.setRootContext(rootNode);
+
+        setLayout(new BorderLayout());
+
+        treeView = new BeanTreeView();
+        treeView.setRootVisible(false);
+        this.add(BorderLayout.CENTER, treeView);
+        associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(0, 400, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(0, 300, Short.MAX_VALUE)
+        );
+    }// </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.
+     * To obtain the singleton instance, use {@link findInstance}.
+     */
+    public static synchronized BytecodeViewTopComponent getDefault() {
+        if (instance == null) {
+            instance = new BytecodeViewTopComponent();
+        }
+        return instance;
+    }
+
+    /**
+     * Obtain the BytecodeViewTopComponent instance. Never call {@link #getDefault} directly!
+     */
+    public static synchronized BytecodeViewTopComponent findInstance() {
+        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+        if (win == null) {
+            ErrorManager.getDefault().log(ErrorManager.WARNING, "Cannot find BytecodeView component. It will not be located properly in the window system.");
+            return getDefault();
+        }
+        if (win instanceof BytecodeViewTopComponent) {
+            return (BytecodeViewTopComponent) win;
+        }
+        ErrorManager.getDefault().log(ErrorManager.WARNING, "There seem to be multiple components with the '" + PREFERRED_ID + "' ID. That is a potential source of errors and unexpected behavior.");
+        return getDefault();
+    }
+
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_ALWAYS;
+    }
+
+    @Override
+    public void componentOpened() {
+        Lookup.Template tpl = new Lookup.Template(Object.class);
+        result = Utilities.actionsGlobalContext().lookup(tpl);
+        result.addLookupListener(this);
+    }
+
+    @Override
+    public void componentClosed() {
+        result.removeLookupListener(this);
+        result = null;
+    }
+
+    @Override
+    public Object writeReplace() {
+        return new ResolvableHelper();
+    }
+
+    @Override
+    protected String preferredID() {
+        return PREFERRED_ID;
+    }
+
+    public ExplorerManager getExplorerManager() {
+        return manager;
+    }
+
+    public void resultChanged(LookupEvent lookupEvent) {
+        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        if (p != null) {
+            InputGraph graph = p.getGraph();
+            if (graph != null) {
+                Group g = graph.getGroup();
+                rootNode.update(graph, g.getMethod());
+            }
+        }
+    }
+
+    final static class ResolvableHelper implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        public Object readResolve() {
+            return BytecodeViewTopComponent.getDefault();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentSettings.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
+<settings version="1.0">
+    <module name="com.sun.hotspot.igv.bytecodes" spec="1.0"/>
+    <instanceof class="org.openide.windows.TopComponent"/>
+    <instanceof class="com.sun.hotspot.igv.bytecodes.BytecodeViewTopComponent"/>
+    <instance class="com.sun.hotspot.igv.bytecodes.BytecodeViewTopComponent" method="getDefault"/>
+</settings>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/BytecodeViewTopComponentWstcref.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,7 @@
+<?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="com.sun.hotspot.igv.bytecodes" spec="1.0"/>
+    <tc-id id="BytecodeViewTopComponent"/>
+    <state opened="true"/>
+</tc-ref>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/MethodNode.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.InputBytecode;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputMethod;
+import java.awt.Image;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.nodes.Node;
+import org.openide.util.Utilities;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class MethodNode extends AbstractNode {
+
+    private static class MethodNodeChildren extends Children.Keys {
+
+        private InputMethod method;
+        private InputGraph graph;
+        private String bciString;
+
+        public MethodNodeChildren(InputMethod method, InputGraph graph, String bciString) {
+            this.method = method;
+            this.bciString = bciString;
+            this.graph = graph;
+        }
+
+        protected Node[] createNodes(Object object) {
+            assert object instanceof InputBytecode;
+            InputBytecode bc = (InputBytecode) object;
+            if (bc.getInlined() == null) {
+                return new Node[]{new BytecodeNode(bc, graph, bciString)};
+            } else {
+                return new Node[]{new BytecodeNode(bc, graph, bciString), new MethodNode(bc.getInlined(), graph, bc.getBci() + " " + bciString)};
+            }
+        }
+
+        @Override
+        public void addNotify() {
+            if (method != null) {
+                setKeys(method.getBytecodes());
+            }
+        }
+
+        public void setMethod(InputMethod method, InputGraph graph) {
+            this.method = method;
+            this.graph = graph;
+            addNotify();
+        }
+    }
+
+    /** Creates a new instance of MethodNode */
+    public MethodNode(InputMethod method, InputGraph graph, String bciString) {
+        super((method != null && method.getBytecodes().size() == 0) ? Children.LEAF : new MethodNodeChildren(method, graph, bciString));
+        if (method != null) {
+            this.setDisplayName(method.getName());
+        }
+    }
+
+    @Override
+    public Image getIcon(int i) {
+        return Utilities.loadImage("com/sun/hotspot/igv/bytecodes/images/method.gif");
+    }
+
+    @Override
+    public Image getOpenedIcon(int i) {
+        return getIcon(i);
+    }
+
+    public void update(InputGraph graph, InputMethod method) {
+        ((MethodNodeChildren) this.getChildren()).setMethod(method, graph);
+        if (method != null) {
+            this.setDisplayName(method.getName());
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
+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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class SelectBytecodesAction extends CookieAction {
+
+    protected void performAction(Node[] activatedNodes) {
+        SelectBytecodesCookie c = activatedNodes[0].getCookie(SelectBytecodesCookie.class);
+        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        if (p != null) {
+            p.setSelectedNodes(c.getNodes());
+        }
+    }
+
+    protected int mode() {
+        return CookieAction.MODE_EXACTLY_ONE;
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(SelectBytecodesAction.class, "CTL_SelectBytecodesAction");
+    }
+
+    protected Class[] cookieClasses() {
+        return new Class[]{
+            SelectBytecodesCookie.class
+        };
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+        putValue("noIconInMenu", Boolean.TRUE);
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/SelectBytecodesCookie.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.bytecodes;
+
+import com.sun.hotspot.igv.data.InputNode;
+import java.util.Collections;
+import java.util.Set;
+import org.openide.nodes.Node;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class SelectBytecodesCookie implements Node.Cookie {
+
+    private Set<InputNode> nodes;
+
+    /** Creates a new instance of SelectBytecodesCookie */
+    public SelectBytecodesCookie(Set<InputNode> nodes) {
+        this.nodes = nodes;
+    }
+
+    public Set<InputNode> getNodes() {
+        return Collections.unmodifiableSet(nodes);
+    }
+}
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/link.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/images/method.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Bytecodes/src/com/sun/hotspot/igv/bytecodes/layer.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+<?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="Actions">
+        <folder name="Edit">
+            <file name="com-sun-hotspot-igv-bytecodes-SelectBytecodesAction.instance"/>
+        </folder>
+        <folder name="Window">
+            <file name="com-sun-hotspot-igv-bytecodes-BytecodeViewAction.instance"/>
+        </folder>
+    </folder>
+    <folder name="Menu">
+        <folder name="Window">
+            <file name="BytecodeViewAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Window/com-sun-hotspot-igv-bytecodes-BytecodeViewAction.instance"/>
+            </file>
+        </folder>
+    </folder>
+    <folder name="Windows2">
+        <folder name="Components">
+            <file name="BytecodeViewTopComponent.settings" url="BytecodeViewTopComponentSettings.xml"/>
+        </folder>
+        <folder name="Modes">
+            <folder name="customRightTopMode">
+                <file name="BytecodeViewTopComponent.wstcref" url="BytecodeViewTopComponentWstcref.xml"/>
+            </folder>
+        </folder>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/build.xml	Wed Jul 05 16:38:46 2017 +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.controlflow" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.controlflow.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +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
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.controlflow-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=b524efb3
+build.xml.script.CRC32=79a27be9
+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=b524efb3
+nbproject/build-impl.xml.script.CRC32=582bdab7
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,70 @@
+<?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.controlflow</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.hierarchicallayout</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>org.jdesktop.layout</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.4</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.api.visual</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>2.9</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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockConnectionWidget.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.controlflow;
+
+import com.sun.hotspot.igv.data.InputBlockEdge;
+import com.sun.hotspot.igv.layout.Link;
+import com.sun.hotspot.igv.layout.Port;
+import java.awt.Point;
+import java.util.ArrayList;
+import java.util.List;
+import org.netbeans.api.visual.widget.ConnectionWidget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class BlockConnectionWidget extends ConnectionWidget implements Link {
+
+    private BlockWidget from;
+    private BlockWidget to;
+    private Port inputSlot;
+    private Port outputSlot;
+    private List<Point> points;
+    private InputBlockEdge edge;
+
+    public BlockConnectionWidget(ControlFlowScene scene, InputBlockEdge edge) {
+        super(scene);
+
+        this.edge = edge;
+        this.from = (BlockWidget) scene.findWidget(edge.getFrom());
+        this.to = (BlockWidget) scene.findWidget(edge.getTo());
+        inputSlot = to.getInputSlot();
+        outputSlot = from.getOutputSlot();
+        points = new ArrayList<Point>();
+    }
+
+    public InputBlockEdge getEdge() {
+        return edge;
+    }
+
+    public Port getTo() {
+        return inputSlot;
+    }
+
+    public Port getFrom() {
+        return outputSlot;
+    }
+
+    public void setControlPoints(List<Point> p) {
+        this.points = p;
+    }
+
+    @Override
+    public List<Point> getControlPoints() {
+        return points;
+    }
+
+    @Override
+    public String toString() {
+        return "Connection[ " + from.toString() + " - " + to.toString() + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/BlockWidget.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.controlflow;
+
+import com.sun.hotspot.igv.data.InputBlock;
+import com.sun.hotspot.igv.layout.Cluster;
+import com.sun.hotspot.igv.layout.Port;
+import com.sun.hotspot.igv.layout.Vertex;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.Point;
+import org.netbeans.api.visual.border.BorderFactory;
+import org.netbeans.api.visual.model.ObjectState;
+import org.netbeans.api.visual.widget.LabelWidget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class BlockWidget extends LabelWidget implements Vertex {
+
+    public static final Dimension 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 boldFont = font.deriveFont(Font.BOLD);
+    public static final Color NORMAL_FOREGROUND_COLOR = Color.BLACK;
+    public static final Color HOVER_FOREGROUND_COLOR = Color.BLUE;
+
+    /** Creates a new instance of BlockWidget */
+    public BlockWidget(ControlFlowScene scene, InputBlock block) {
+        super(scene);
+        this.block = block;
+        this.setLabel(block.getName());
+        this.setForeground(NORMAL_FOREGROUND_COLOR);
+        this.setBorder(BorderFactory.createLineBorder(1, NORMAL_FOREGROUND_COLOR));
+        this.setMinimumSize(SIZE);
+        this.setMaximumSize(SIZE);
+
+        this.setFont(font);
+
+        final BlockWidget widget = this;
+        inputSlot = new Port() {
+
+            public Point getRelativePosition() {
+                return new Point((int) (SIZE.getWidth() / 2), (int) (SIZE.getHeight() / 2));
+            }
+
+            public Vertex getVertex() {
+                return widget;
+            }
+        };
+
+        outputSlot = new Port() {
+
+            public Point getRelativePosition() {
+                return new Point((int) (SIZE.getWidth() / 2), (int) (SIZE.getHeight() / 2));
+            }
+
+            public Vertex getVertex() {
+                return widget;
+            }
+        };
+    }
+
+    public Port getInputSlot() {
+        return inputSlot;
+    }
+
+    public Port getOutputSlot() {
+        return outputSlot;
+    }
+
+    public InputBlock getBlock() {
+        return block;
+    }
+
+    public Dimension getSize() {
+        return SIZE;
+    }
+
+    public void setPosition(Point p) {
+        this.setPreferredLocation(p);
+    }
+
+    @Override
+    public String toString() {
+        return block.getName();
+    }
+
+    public Point getPosition() {
+        return this.getPreferredLocation();
+    }
+
+    public Cluster getCluster() {
+        return cluster;
+    }
+
+    public boolean isRoot() {
+        return root;
+    }
+
+    public void setCluster(Cluster c) {
+        cluster = c;
+    }
+
+    public void setRoot(boolean b) {
+        root = b;
+    }
+
+    public int compareTo(Vertex o) {
+        return toString().compareTo(o.toString());
+    }
+
+    @Override
+    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
+        super.notifyStateChanged(previousState, state);
+
+        if (previousState.isHovered() != state.isHovered()) {
+            if (state.isHovered()) {
+                this.setBorder(BorderFactory.createLineBorder(1, HOVER_FOREGROUND_COLOR));
+            } else {
+                this.setBorder(BorderFactory.createLineBorder(1, NORMAL_FOREGROUND_COLOR));
+            }
+        }
+
+        if (previousState.isSelected() != state.isSelected()) {
+            if (state.isSelected()) {
+                this.setFont(boldFont);
+            } else {
+                this.setFont(font);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,4 @@
+CTL_ControlFlowAction=Open ControlFlow Window
+CTL_ControlFlowTopComponent=ControlFlow Window
+HINT_ControlFlowTopComponent=This is a ControlFlow window
+OpenIDE-Module-Name=ControlFlow
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.controlflow;
+
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ControlFlowAction extends AbstractAction {
+
+    public ControlFlowAction() {
+        super(NbBundle.getMessage(ControlFlowAction.class, "CTL_ControlFlowAction"));
+    }
+
+    public void actionPerformed(ActionEvent evt) {
+        TopComponent win = ControlFlowTopComponent.findInstance();
+        win.open();
+        win.requestActive();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowScene.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,296 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.controlflow;
+
+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 java.awt.Color;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+import javax.swing.BorderFactory;
+import org.netbeans.api.visual.action.ActionFactory;
+import org.netbeans.api.visual.action.MoveProvider;
+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.anchor.AnchorFactory;
+import org.netbeans.api.visual.anchor.AnchorShape;
+import com.sun.hotspot.igv.controlflow.HierarchicalGraphLayout;
+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.SceneLayout;
+import org.netbeans.api.visual.widget.ConnectionWidget;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ControlFlowScene extends GraphScene<InputBlock, InputBlockEdge> implements SelectProvider, MoveProvider, RectangularSelectDecorator, RectangularSelectProvider {
+
+    private Set<BlockWidget> selection;
+    private Hashtable<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 moveAction = ActionFactory.createMoveAction(null, this);
+
+    public ControlFlowScene() {
+        selection = new HashSet<BlockWidget>();
+
+        this.getInputBindings().setZoomActionModifiers(0);
+        this.setLayout(LayoutFactory.createAbsoluteLayout());
+
+        mainLayer = new LayerWidget(this);
+        this.addChild(mainLayer);
+
+        edgeLayer = new LayerWidget(this);
+        this.addChild(edgeLayer);
+
+        selectLayer = new LayerWidget(this);
+        this.addChild(selectLayer);
+
+        this.getActions().addAction(hoverAction);
+        this.getActions().addAction(selectAction);
+        this.getActions().addAction(ActionFactory.createRectangularSelectAction(this, selectLayer, this));
+        this.getActions().addAction(ActionFactory.createMouseCenteredZoomAction(1.1));
+    }
+
+    public void setGraph(InputGraph g) {
+        if (g == oldGraph) {
+            return;
+        }
+        oldGraph = g;
+
+        ArrayList<InputBlock> blocks = new ArrayList<InputBlock>(this.getNodes());
+        for (InputBlock b : blocks) {
+            removeNode(b);
+        }
+
+        ArrayList<InputBlockEdge> edges = new ArrayList<InputBlockEdge>(this.getEdges());
+        for (InputBlockEdge e : edges) {
+            removeEdge(e);
+        }
+
+        for (InputBlock b : g.getBlocks()) {
+            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());
+            }
+        }
+
+        GraphLayout layout = new HierarchicalGraphLayout();//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));
+        }
+        selection.clear();
+        selectionChanged();
+    }
+
+    public void selectionChanged() {
+        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        if (p != null) {
+            Set<InputNode> inputNodes = new HashSet<InputNode>();
+            for (BlockWidget w : selection) {
+                inputNodes.addAll(w.getBlock().getNodes());
+            }
+            p.setSelectedNodes(inputNodes);
+        }
+    }
+
+    public void addToSelection(BlockWidget widget) {
+        widget.setState(widget.getState().deriveSelected(true));
+        selection.add(widget);
+        selectionChanged();
+    }
+
+    public void removeFromSelection(BlockWidget widget) {
+        widget.setState(widget.getState().deriveSelected(false));
+        selection.remove(widget);
+        selectionChanged();
+    }
+
+    public boolean isAimingAllowed(Widget widget, Point point, boolean b) {
+        return false;
+    }
+
+    public boolean isSelectionAllowed(Widget widget, Point point, boolean b) {
+        return true;
+    }
+
+    public void select(Widget widget, Point point, boolean change) {
+        if (widget == this) {
+            clearSelection();
+        } else {
+
+            assert widget instanceof BlockWidget;
+            BlockWidget bw = (BlockWidget) widget;
+            if (change) {
+                if (selection.contains(bw)) {
+                    removeFromSelection(bw);
+                } else {
+                    addToSelection(bw);
+                }
+            } else {
+                if (!selection.contains(bw)) {
+                    clearSelection();
+                    addToSelection(bw);
+                }
+            }
+        }
+    }
+
+    public void movementStarted(Widget widget) {
+    }
+
+    public void movementFinished(Widget widget) {
+    }
+
+    public Point getOriginalLocation(Widget widget) {
+        return widget.getPreferredLocation();
+    }
+
+    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);
+        }
+
+    }
+
+    public Widget createSelectionWidget() {
+        Widget widget = new Widget(this);
+        widget.setOpaque(false);
+        widget.setBorder(BorderFactory.createLineBorder(Color.black, 2));
+        widget.setForeground(Color.red);
+        return widget;
+    }
+
+    public void performSelection(Rectangle rectangle) {
+
+        if (rectangle.width < 0) {
+            rectangle.x += rectangle.width;
+            rectangle.width *= -1;
+        }
+
+        if (rectangle.height < 0) {
+            rectangle.y += rectangle.height;
+            rectangle.height *= -1;
+        }
+
+        boolean changed = false;
+        for (InputBlock b : this.getNodes()) {
+            BlockWidget w = (BlockWidget) findWidget(b);
+            Rectangle r = new Rectangle(w.getBounds());
+            r.setLocation(w.getLocation());
+            if (r.intersects(rectangle)) {
+                if (!selection.contains(w)) {
+                    changed = true;
+                    selection.add(w);
+                    w.setState(w.getState().deriveSelected(true));
+                }
+            } else {
+                if (selection.contains(w)) {
+                    changed = true;
+                    selection.remove(w);
+                    w.setState(w.getState().deriveSelected(false));
+                }
+            }
+        }
+
+        if (changed) {
+            selectionChanged();
+        }
+
+    }
+
+    protected Widget attachNodeWidget(InputBlock node) {
+        BlockWidget w = new BlockWidget(this, node);
+        mainLayer.addChild(w);
+        w.getActions().addAction(hoverAction);
+        w.getActions().addAction(selectAction);
+        w.getActions().addAction(moveAction);
+        return w;
+    }
+
+    protected Widget attachEdgeWidget(InputBlockEdge edge) {
+        ConnectionWidget w = new BlockConnectionWidget(this, edge);
+        w.setRouter(RouterFactory.createDirectRouter());
+        w.setTargetAnchorShape(AnchorShape.TRIANGLE_FILLED);
+        edgeLayer.addChild(w);
+        return w;
+    }
+
+    protected void attachEdgeSourceAnchor(InputBlockEdge edge, InputBlock oldSourceNode, InputBlock sourceNode) {
+        Widget w = this.findWidget(edge);
+        assert w instanceof ConnectionWidget;
+        ConnectionWidget cw = (ConnectionWidget) w;
+        cw.setSourceAnchor(AnchorFactory.createRectangularAnchor(findWidget(sourceNode)));
+
+    }
+
+    protected void attachEdgeTargetAnchor(InputBlockEdge edge, InputBlock oldTargetNode, InputBlock targetNode) {
+        Widget w = this.findWidget(edge);
+        assert w instanceof ConnectionWidget;
+        ConnectionWidget cw = (ConnectionWidget) w;
+        cw.setTargetAnchor(AnchorFactory.createRectangularAnchor(findWidget(targetNode)));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.form	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-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_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"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="400" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <EmptySpace min="0" pref="300" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponent.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.controlflow;
+
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import java.awt.BorderLayout;
+import java.io.Serializable;
+import javax.swing.JScrollPane;
+import org.openide.ErrorManager;
+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.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+final class ControlFlowTopComponent extends TopComponent implements LookupListener {
+
+    private static ControlFlowTopComponent instance;
+    private Lookup.Result result = null;
+    private static final String PREFERRED_ID = "ControlFlowTopComponent";
+    private ControlFlowScene scene;
+
+    private ControlFlowTopComponent() {
+        initComponents();
+        setName(NbBundle.getMessage(ControlFlowTopComponent.class, "CTL_ControlFlowTopComponent"));
+        setToolTipText(NbBundle.getMessage(ControlFlowTopComponent.class, "HINT_ControlFlowTopComponent"));
+
+        scene = new ControlFlowScene();
+        this.setLayout(new BorderLayout());
+        this.associateLookup(scene.getLookup());
+
+
+        JScrollPane panel = new JScrollPane(scene.createView());
+        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.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(0, 400, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(0, 300, Short.MAX_VALUE)
+        );
+    }// </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.
+     * To obtain the singleton instance, use {@link findInstance}.
+     */
+    public static synchronized ControlFlowTopComponent getDefault() {
+        if (instance == null) {
+            instance = new ControlFlowTopComponent();
+        }
+        return instance;
+    }
+
+    /**
+     * Obtain the ControlFlowTopComponent instance. Never call {@link #getDefault} directly!
+     */
+    public static synchronized ControlFlowTopComponent findInstance() {
+        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+        if (win == null) {
+            ErrorManager.getDefault().log(ErrorManager.WARNING, "Cannot find ControlFlow component. It will not be located properly in the window system.");
+            return getDefault();
+        }
+        if (win instanceof ControlFlowTopComponent) {
+            return (ControlFlowTopComponent) win;
+        }
+        ErrorManager.getDefault().log(ErrorManager.WARNING, "There seem to be multiple components with the '" + PREFERRED_ID + "' ID. That is a potential source of errors and unexpected behavior.");
+        return getDefault();
+    }
+
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_ALWAYS;
+    }
+
+    @Override
+    public void componentOpened() {
+        Lookup.Template tpl = new Lookup.Template(Object.class);
+        result = Utilities.actionsGlobalContext().lookup(tpl);
+        result.addLookupListener(this);
+    }
+
+    @Override
+    public void componentClosed() {
+        result.removeLookupListener(this);
+        result = null;
+    }
+
+    public void resultChanged(LookupEvent lookupEvent) {
+
+        InputGraphProvider p = Lookup.getDefault().lookup(InputGraphProvider.class);
+        if (p != null) {
+            InputGraph g = p.getGraph();
+            if (g != null) {
+                scene.setGraph(g);
+            }
+        }
+    }
+
+    @Override
+    public Object writeReplace() {
+        return new ResolvableHelper();
+    }
+
+    @Override
+    protected String preferredID() {
+        return PREFERRED_ID;
+    }
+
+    @Override
+    public void requestActive() {
+        scene.getView().requestFocusInWindow();
+        super.requestActive();
+    }
+
+    final static class ResolvableHelper implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        public Object readResolve() {
+            return ControlFlowTopComponent.getDefault();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponentSettings.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
+<settings version="1.0">
+    <module name="com.sun.hotspot.igv.controlflow" spec="1.0"/>
+    <instanceof class="org.openide.windows.TopComponent"/>
+    <instanceof class="com.sun.hotspot.igv.controlflow.ControlFlowTopComponent"/>
+    <instance class="com.sun.hotspot.igv.controlflow.ControlFlowTopComponent" method="getDefault"/>
+</settings>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/ControlFlowTopComponentWstcref.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,7 @@
+<?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="com.sun.hotspot.igv.controlflow" spec="1.0"/>
+    <tc-id id="ControlFlowTopComponent"/>
+    <state opened="true"/>
+</tc-ref>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/HierarchicalGraphLayout.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.controlflow;
+
+import com.sun.hotspot.igv.hierarchicallayout.HierarchicalLayoutManager;
+import com.sun.hotspot.igv.layout.Cluster;
+import com.sun.hotspot.igv.layout.LayoutGraph;
+import com.sun.hotspot.igv.layout.Link;
+import com.sun.hotspot.igv.layout.Port;
+import com.sun.hotspot.igv.layout.Vertex;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import org.netbeans.api.visual.graph.layout.GraphLayout;
+import org.netbeans.api.visual.graph.layout.UniversalGraph;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class HierarchicalGraphLayout<N, E> extends GraphLayout<N, E> {
+
+    public HierarchicalGraphLayout() {
+    }
+
+    private class LinkWrapper implements Link {
+
+        private VertexWrapper from;
+        private VertexWrapper to;
+
+        public LinkWrapper(VertexWrapper from, VertexWrapper to) {
+            this.from = from;
+            this.to = to;
+        }
+
+        public Port getFrom() {
+            return from.getSlot();
+        }
+
+        public Port getTo() {
+            return to.getSlot();
+        }
+
+        public List<Point> getControlPoints() {
+            return new ArrayList<Point>();
+        }
+
+        public void setControlPoints(List<Point> list) {
+        // Do nothing for now
+        }
+    }
+
+    private class VertexWrapper implements Vertex {
+
+        private N node;
+        private UniversalGraph<N, E> graph;
+        private Port slot;
+        private Point position;
+
+        public VertexWrapper(N node, UniversalGraph<N, E> graph) {
+            this.node = node;
+            this.graph = graph;
+            final VertexWrapper vertex = this;
+            this.slot = new Port() {
+
+                public Vertex getVertex() {
+                    return vertex;
+                }
+
+                public Point getRelativePosition() {
+                    return new Point((int) (vertex.getSize().getWidth() / 2), (int) (vertex.getSize().getHeight() / 2));
+                }
+            };
+
+            Widget w = graph.getScene().findWidget(node);
+            this.position = w.getPreferredLocation();
+        }
+
+        public Cluster getCluster() {
+            return null;
+        }
+
+        public Dimension getSize() {
+            Widget w = graph.getScene().findWidget(node);
+            return w.getBounds().getSize();
+        }
+
+        public Point getPosition() {
+            return position;
+        }
+
+        public void setPosition(Point p) {
+            HierarchicalGraphLayout.this.setResolvedNodeLocation(graph, node, p);
+            position = p;
+        }
+
+        public boolean isRoot() {
+            return false;
+        }
+
+        public int compareTo(Vertex o) {
+            VertexWrapper vw = (VertexWrapper) o;
+            return node.toString().compareTo(vw.node.toString());
+        }
+
+        public Port getSlot() {
+            return slot;
+        }
+    }
+
+    protected void performGraphLayout(UniversalGraph<N, E> graph) {
+
+        Set<LinkWrapper> links = new HashSet<LinkWrapper>();
+        Set<VertexWrapper> vertices = new HashSet<VertexWrapper>();
+        Map<N, VertexWrapper> vertexMap = new HashMap<N, VertexWrapper>();
+
+        for (N node : graph.getNodes()) {
+            VertexWrapper v = new VertexWrapper(node, graph);
+            vertexMap.put(node, v);
+            vertices.add(v);
+        }
+
+        for (E edge : graph.getEdges()) {
+            N source = graph.getEdgeSource(edge);
+            N target = graph.getEdgeTarget(edge);
+            LinkWrapper l = new LinkWrapper(vertexMap.get(source), vertexMap.get(target));
+            links.add(l);
+        }
+
+        HierarchicalLayoutManager m = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.NONE);
+
+        LayoutGraph layoutGraph = new LayoutGraph(links, vertices);
+        m.doLayout(layoutGraph);
+    }
+
+    protected void performNodesLayout(UniversalGraph<N, E> graph, Collection<N> nodes) {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ControlFlow/src/com/sun/hotspot/igv/controlflow/layer.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,26 @@
+<?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="Actions">
+        <folder name="Window">
+            <file name="com-sun-hotspot-igv-controlflow-ControlFlowAction.instance"/>
+        </folder>
+    </folder>
+    <folder name="Menu">
+        <folder name="Window">
+            <file name="ControlFlowAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Window/com-sun-hotspot-igv-controlflow-ControlFlowAction.instance"/>
+            </file>
+        </folder>
+    </folder>
+    <folder name="Windows2">
+        <folder name="Components">
+            <file name="ControlFlowTopComponent.settings" url="ControlFlowTopComponentSettings.xml"/>
+        </folder>
+        <folder name="Modes">
+            <folder name="customRightTopMode">
+                <file name="ControlFlowTopComponent.wstcref" url="ControlFlowTopComponentWstcref.xml"/>
+            </folder>
+        </folder>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/build.xml	Wed Jul 05 16:38:46 2017 +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.coordinator" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.coordinator.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.coordinator
+OpenIDE-Module-Layer: com/sun/hotspot/igv/coordinator/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/coordinator/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.coordinator-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=077de97c
+build.xml.script.CRC32=d29d586c
+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=077de97c
+nbproject/build-impl.xml.script.CRC32=03daa42d
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,126 @@
+<?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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupOrganizer	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+com.sun.hotspot.igv.coordinator.StandardGroupOrganizer
+com.sun.hotspot.igv.coordinator.GraphCountGroupOrganizer
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,7 @@
+
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/FolderNode.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.coordinator;
+
+import com.sun.hotspot.igv.coordinator.actions.RemoveCookie;
+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 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.lookup.AbstractLookup;
+import org.openide.util.lookup.InstanceContent;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+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 {
+
+        private FolderNode parent;
+
+        public void setParent(FolderNode parent) {
+            this.parent = parent;
+        }
+
+        @Override
+        protected Node[] createNodes(Object arg0) {
+
+            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));
+                    }
+                }
+
+                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())};
+            }
+        }
+
+        @Override
+        public void addNotify() {
+            this.setKeys(parent.structure);
+
+        }
+    }
+
+    protected InstanceContent getContent() {
+        return content;
+    }
+
+    @Override
+    public Image getIcon(int i) {
+        return Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/folder.gif");
+    }
+
+    protected FolderNode(String name, GroupOrganizer organizer, List<String> subFolders, List<Group> groups) {
+        this(name, organizer, subFolders, groups, new FolderChildren(), new InstanceContent());
+    }
+
+    private FolderNode(String name, GroupOrganizer organizer, List<String> oldSubFolders, final List<Group> groups, 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);
+                    }
+                }
+            }
+        });
+        init(name, organizer, oldSubFolders, groups);
+    }
+
+    public void init(String name, GroupOrganizer organizer, List<String> oldSubFolders, List<Group> groups) {
+        this.setDisplayName(name);
+        this.organizer = organizer;
+        this.subFolders = new ArrayList<String>(oldSubFolders);
+        if (name.length() > 0) {
+            this.subFolders.add(name);
+        }
+        structure = organizer.organize(subFolders, groups);
+        assert structure != null;
+        children.addNotify();
+    }
+
+    @Override
+    public Image getOpenedIcon(int i) {
+        return getIcon(i);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphCountGroupOrganizer.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,81 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/GraphNode.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.coordinator;
+
+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.data.InputGraph;
+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.Sheet;
+import org.openide.util.Lookup;
+import org.openide.util.Utilities;
+import org.openide.util.lookup.AbstractLookup;
+import org.openide.util.lookup.InstanceContent;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class GraphNode extends AbstractNode {
+
+    private InputGraph graph;
+
+    /** Creates a new instance of GraphNode */
+    public GraphNode(InputGraph graph) {
+        this(graph, new InstanceContent());
+    }
+
+    private GraphNode(final InputGraph graph, InstanceContent content) {
+        super(Children.LEAF, new AbstractLookup(content));
+        this.graph = graph;
+        this.setDisplayName(graph.getName());
+        content.add(graph);
+
+        final GraphViewer viewer = Lookup.getDefault().lookup(GraphViewer.class);
+
+        if (viewer != null) {
+            // Action for opening the graph
+            content.add(new OpenCookie() {
+
+                public void open() {
+                    viewer.view(graph);
+                }
+            });
+        }
+
+        // Action for removing a graph
+        content.add(new RemoveCookie() {
+
+            public void remove() {
+                graph.getGroup().removeGraph(graph);
+            }
+        });
+    }
+
+    @Override
+    protected Sheet createSheet() {
+        Sheet s = super.createSheet();
+        PropertiesSheet.initializeSheet(graph.getProperties(), s);
+        return s;
+    }
+
+    @Override
+    public Image getIcon(int i) {
+        return Utilities.loadImage("com/sun/hotspot/igv/coordinator/images/graph.gif");
+    }
+
+    @Override
+    public Image getOpenedIcon(int i) {
+        return getIcon(i);
+    }
+
+    @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)};
+    }
+
+    @Override
+    public Action getPreferredAction() {
+        return (Action) OpenAction.findObject(OpenAction.class, true);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.form	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-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_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"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+    <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
+  </AuxValues>
+
+  <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="jPanel2">
+      <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>
+    </Container>
+  </SubComponents>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponent.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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.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.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;
+import org.openide.util.actions.NodeAction;
+import org.openide.windows.TopComponent;
+import org.openide.windows.WindowManager;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class OutlineTopComponent extends TopComponent implements ExplorerManager.Provider, LookupListener {
+
+    public static OutlineTopComponent instance;
+    public static final String PREFERRED_ID = "OutlineTopComponent";
+    private ExplorerManager manager;
+    private GraphDocument document;
+    private FolderNode root;
+    private GroupOrganizer organizer;
+
+    private OutlineTopComponent() {
+        initComponents();
+
+        setName(NbBundle.getMessage(OutlineTopComponent.class, "CTL_OutlineTopComponent"));
+        setToolTipText(NbBundle.getMessage(OutlineTopComponent.class, "HINT_OutlineTopComponent"));
+
+        document = new GraphDocument();
+        initListView();
+        initToolbar();
+        initReceivers();
+    }
+
+    private void initListView() {
+        manager = new ExplorerManager();
+        organizer = new StandardGroupOrganizer();
+        root = new FolderNode("", organizer, new ArrayList<String>(), document.getGroups());
+        manager.setRootContext(root);
+        ((BeanTreeView) this.jScrollPane1).setRootVisible(false);
+
+        document.getChangedEvent().addListener(new ChangedListener<GraphDocument>() {
+
+            public void changed(GraphDocument document) {
+                updateStructure();
+            }
+        });
+
+        associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
+    }
+
+    private void initToolbar() {
+
+        Toolbar toolbar = new Toolbar();
+        Border b = (Border) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N
+        toolbar.setBorder(b);
+        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());
+
+        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() {
+
+            public void started(Group g) {
+                getDocument().addGroup(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());
+    }
+
+    public void clear() {
+        document.clear();
+    }
+
+    public ExplorerManager getExplorerManager() {
+        return manager;
+    }
+
+    public GraphDocument getDocument() {
+        return document;
+    }
+
+    /**
+     * Gets default instance. Do not use directly: reserved for *.settings files only,
+     * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
+     * To obtain the singleton instance, use {@link findInstance}.
+     */
+    public static synchronized OutlineTopComponent getDefault() {
+        if (instance == null) {
+            instance = new OutlineTopComponent();
+        }
+        return instance;
+    }
+
+    /**
+     * Obtain the OutlineTopComponent instance. Never call {@link #getDefault} directly!
+     */
+    public static synchronized OutlineTopComponent findInstance() {
+        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+        if (win == null) {
+            ErrorManager.getDefault().log(ErrorManager.WARNING, "Cannot find Outline component. It will not be located properly in the window system.");
+            return getDefault();
+        }
+        if (win instanceof OutlineTopComponent) {
+            return (OutlineTopComponent) win;
+        }
+        ErrorManager.getDefault().log(ErrorManager.WARNING, "There seem to be multiple components with the '" + PREFERRED_ID + "' ID. That is a potential source of errors and unexpected behavior.");
+        return getDefault();
+    }
+
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_ALWAYS;
+    }
+
+    @Override
+    public void componentOpened() {
+        this.requestActive();
+    }
+
+    @Override
+    public void componentClosed() {
+    }
+
+    @Override
+    protected String preferredID() {
+        return PREFERRED_ID;
+    }
+
+    public void resultChanged(LookupEvent lookupEvent) {
+    }
+
+    @Override
+    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);
+    }
+
+    @Override
+    public void writeExternal(ObjectOutput objectOutput) throws IOException {
+        super.writeExternal(objectOutput);
+    }
+
+    static final class ResolvableHelper implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        public Object readResolve() {
+            return OutlineTopComponent.getDefault();
+        }
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jPanel2 = new javax.swing.JPanel();
+        jScrollPane1 = 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);
+    }// </editor-fold>//GEN-END:initComponents
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JPanel jPanel2;
+    private javax.swing.JScrollPane jScrollPane1;
+    // End of variables declaration//GEN-END:variables
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponentSettings.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
+<settings version="1.0">
+    <module name="com.sun.hotspot.igv.coordinator" spec="1.0"/>
+    <instanceof class="at.openide.windows.TopComponent"/>
+    <instanceof class="com.sun.hotspot.igv.coordinator.OutlineTopComponent"/>
+    <instance class="com.sun.hotspot.igv.coordinator.OutlineTopComponent" method="getDefault"/>
+</settings>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/OutlineTopComponentWstcref.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,7 @@
+<?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="com.sun.hotspot.igv.coordinator" spec="1.0"/>
+    <tc-id id="OutlineTopComponent"/>
+    <state opened="true"/>
+</tc-ref>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardConfiguration.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,13 @@
+<?xml version="1.0"?>
+<!DOCTYPE Configuration PUBLIC "-//NetBeans IDE//DTD toolbar//EN" "http://www.netbeans.org/dtds/toolbar.dtd">
+<Configuration>
+    <Row>
+        <Toolbar name="Edit" position="1" visible="false"/>
+        <Toolbar name="File" position="1" visible="false" />
+        <Toolbar name="Memory" position="1" visible="false" />
+    </Row>
+    <Row>
+        <Toolbar name="WorkspaceSwitcher" />
+        <Toolbar name="StatusLine" />
+    </Row>
+</Configuration>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/StandardGroupOrganizer.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,62 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,18 @@
+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_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/DiffGraphAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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.NbBundle;
+import org.openide.util.actions.CookieAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class DiffGraphAction extends CookieAction {
+
+    protected void performAction(Node[] activatedNodes) {
+        DiffGraphCookie c = activatedNodes[0].getCookie(DiffGraphCookie.class);
+        c.openDiff();
+    }
+
+    protected int mode() {
+        return CookieAction.MODE_EXACTLY_ONE;
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(DiffGraphAction.class, "CTL_DiffGraphAction");
+    }
+
+    protected Class[] cookieClasses() {
+        return new Class[]{
+            DiffGraphCookie.class
+        };
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/coordinator/images/diff.gif";
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return 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/DiffGraphCookie.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 com.sun.hotspot.igv.difference.Difference;
+import org.openide.nodes.Node;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class DiffGraphCookie implements Node.Cookie {
+
+    private InputGraph a;
+    private InputGraph b;
+
+    public DiffGraphCookie(InputGraph a, InputGraph b) {
+        this.a = a;
+        this.b = b;
+    }
+
+    public void openDiff() {
+
+        final GraphViewer viewer = Lookup.getDefault().lookup(GraphViewer.class);
+
+        if(viewer != null) {
+            InputGraph diffGraph = Difference.createDiffGraph(a, b);
+            viewer.view(diffGraph);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/ImportAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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.GraphDocument;
+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 javax.swing.Action;
+import javax.swing.JFileChooser;
+import javax.swing.KeyStroke;
+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.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 {
+
+    public static FileFilter getFileFilter() {
+        return new FileFilter() {
+
+            public boolean accept(File f) {
+                return f.getName().toLowerCase().endsWith(".xml") || f.isDirectory();
+            }
+
+            public String getDescription() {
+                return "XML files (*.xml)";
+            }
+        };
+    }
+
+    public void performAction() {
+
+        JFileChooser fc = new JFileChooser();
+        fc.setFileFilter(ImportAction.getFileFilter());
+        fc.setCurrentDirectory(new File(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT)));
+
+        if (fc.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
+            File file = fc.getSelectedFile();
+
+            File dir = file;
+            if (!dir.isDirectory()) {
+                dir = dir.getParentFile();
+            }
+
+            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 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) {
+                        try {
+                            int curAvailable = inputStream.available();
+                            int prog = (int) (basis * (double) (start - curAvailable) / (double) start);
+                            handle.progress(prog);
+                        } catch (IOException ex) {
+                        }
+                    }
+
+                    public void setState(String state) {
+                        setProgress(0.0);
+                        handle.progress(state);
+                    }
+                };
+                final Parser parser = new Parser();
+                final OutlineTopComponent component = OutlineTopComponent.findInstance();
+
+                component.requestActive();
+
+                RequestProcessor.getDefault().post(new Runnable() {
+
+                    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() + "\"";
+                            }
+                            ex.printStackTrace();
+                            NotifyDescriptor d = new NotifyDescriptor.Message(s, NotifyDescriptor.ERROR_MESSAGE);
+                            DialogDisplayer.getDefault().notify(d);
+                        }
+                        handle.finish();
+                    }
+                });
+
+            } catch (SAXException ex) {
+                ex.printStackTrace();
+            } catch (FileNotFoundException ex) {
+                ex.printStackTrace();
+            } catch (IOException ex) {
+                ex.printStackTrace();
+            }
+        }
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(ImportAction.class, "CTL_ImportAction");
+    }
+
+    public ImportAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Open an 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";
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return 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/OutlineAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package com.sun.hotspot.igv.coordinator.actions;
+
+import com.sun.hotspot.igv.coordinator.*;
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class OutlineAction extends AbstractAction {
+
+    public OutlineAction() {
+        super(NbBundle.getMessage(OutlineAction.class, "CTL_OutlineAction"));
+    }
+
+    public void actionPerformed(ActionEvent evt) {
+        TopComponent win = OutlineTopComponent.findInstance();
+        win.open();
+        win.requestActive();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package com.sun.hotspot.igv.coordinator.actions;
+
+import javax.swing.Action;
+import org.openide.nodes.Node;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.NodeAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class RemoveAction extends NodeAction {
+
+    protected void performAction(Node[] activatedNodes) {
+        for (Node n : activatedNodes) {
+            RemoveCookie removeCookie = n.getCookie(RemoveCookie.class);
+            if (removeCookie != null) {
+                removeCookie.remove();
+            }
+        }
+    }
+
+    public RemoveAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Remove");
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(RemoveAction.class, "CTL_RemoveAction");
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/coordinator/images/remove.gif";
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    protected boolean enable(Node[] nodes) {
+        return nodes.length > 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveAllAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import javax.swing.Action;
+import javax.swing.KeyStroke;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class RemoveAllAction extends CallableSystemAction {
+
+
+    public String getName() {
+        return NbBundle.getMessage(RemoveAllAction.class, "CTL_ImportAction");
+    }
+
+    public RemoveAllAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Remove all methods");
+        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";
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    public void performAction() {
+        OutlineTopComponent.findInstance().clear();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/RemoveCookie.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package com.sun.hotspot.igv.coordinator.actions;
+
+import org.openide.nodes.Node;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface RemoveCookie extends Node.Cookie {
+        void remove();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/SaveAllAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import javax.swing.Action;
+import javax.swing.KeyStroke;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class SaveAllAction extends CallableSystemAction {
+
+    public void performAction() {
+        final OutlineTopComponent component = OutlineTopComponent.findInstance();
+        SaveAsAction.save(component.getDocument());
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(SaveAllAction.class, "CTL_SaveAllAction");
+    }
+
+    public SaveAllAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Save all methods to XML file");
+        putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/coordinator/images/saveall.gif";
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return 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/SaveAsAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+
+package com.sun.hotspot.igv.coordinator.actions;
+
+import com.sun.hotspot.igv.data.GraphDocument;
+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 javax.swing.JFileChooser;
+import org.openide.nodes.Node;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CookieAction;
+import org.openide.util.actions.NodeAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class SaveAsAction extends NodeAction {
+
+    protected void performAction(Node[] activatedNodes) {
+
+        GraphDocument doc = new GraphDocument();
+        for (Node n : activatedNodes) {
+            Group group = n.getLookup().lookup(Group.class);
+            doc.addGroup(group);
+        }
+
+        save(doc);
+    }
+
+    public static void save(GraphDocument doc) {
+        JFileChooser fc = new JFileChooser();
+        fc.setFileFilter(ImportAction.getFileFilter());
+        fc.setCurrentDirectory(new File(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT)));
+
+        if (fc.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
+            File file = fc.getSelectedFile();
+            if (!file.getName().contains(".")) {
+                file = new File(file.getAbsolutePath() + ".xml");
+            }
+
+            File dir = file;
+            if (!dir.isDirectory()) {
+                dir = dir.getParentFile();
+            }
+            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();
+            } catch (FileNotFoundException e) {
+                e.printStackTrace();
+            } catch (IOException e) {
+                e.printStackTrace();
+
+            }
+        }
+    }
+
+    protected int mode() {
+        return CookieAction.MODE_SOME;
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(SaveAsAction.class, "CTL_SaveAsAction");
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/coordinator/images/save.gif";
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    protected boolean enable(Node[] nodes) {
+
+        int cnt = 0;
+        for (Node n : nodes) {
+            cnt += n.getLookup().lookupAll(Group.class).size();
+        }
+
+        return cnt > 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/actions/StructuredViewAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,180 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/customLeftWsmode.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mode version="2.1">
+    <name unique="customLeft" />
+    <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"/>
+    </constraints>
+    <bounds x="0" y="0" width="0" height="0" />
+    <frame state="0"/>
+    <active-tc id="OutlineTopComponent"/>
+    <empty-behavior permanent="false"/>
+</mode>
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/folder.gif 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/import.gif 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/removeall.gif 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/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/structured.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,114 @@
+<?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>
+    <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>
+        </folder>
+        <folder name="Edit">
+
+            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance">
+                <attr name="position" intvalue="1200"/>
+            </file>
+        </folder>
+        <folder name="Window">
+            <file name="com-sun-hotspot-igv-coordinator-actions-OutlineAction.instance"/>
+        </folder>
+    </folder>
+    <folder name="Menu">
+        <folder name="File">
+            <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">
+                <attr name="instanceClass" stringvalue="javax.swing.JSeparator"/>
+                <attr name="position" intvalue="300"/>
+            </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"/>
+            </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"/>
+            </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>
+            <file name="com-sun-hotspot-igv-coordinator-actions-RemoveAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Edit/com-sun-hotspot-igv-coordinator-actions-RemoveAction.instance"/>
+            </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"/>
+        </folder>
+        <file name="GoTo_hidden"/>
+        <folder name="View">
+            <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="org-netbeans-core-windows-actions-ToolbarsListAction.instance_hidden"/>
+        </folder>
+        <folder name="Window">
+            <file name="OutlineAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Window/com-sun-hotspot-igv-coordinator-actions-OutlineAction.instance"/>
+            </file>
+        </folder>
+    </folder>
+    <folder name="Toolbars">
+        <file name="Standard.xml" url="StandardConfiguration.xml"/>
+    </folder>
+    <folder name="Windows2">
+        <folder name="Components">
+            <file name="OutlineTopComponent.settings" url="OutlineTopComponentSettings.xml"/>
+        </folder>
+        <folder name="Modes">
+            <file name="customLeft.wsmode" url="customLeftWsmode.xml"/>
+            <folder name="customLeft">
+                <file name="OutlineTopComponent.wstcref" url="OutlineTopComponentWstcref.xml"/>
+            </folder>
+        </folder>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/build.xml	Wed Jul 05 16:38:46 2017 +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.data" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.data.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +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
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.data-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=a403efd8
+build.xml.script.CRC32=b87f73ba
+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=a403efd8
+nbproject/build-impl.xml.script.CRC32=cc649146
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,16 @@
+<?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.data</code-name-base>
+            <suite-component/>
+            <module-dependencies/>
+            <public-packages>
+                <package>com.sun.hotspot.igv.data</package>
+                <package>com.sun.hotspot.igv.data.serialization</package>
+                <package>com.sun.hotspot.igv.data.services</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Data
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEvent.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ChangedEvent<T> extends Event<ChangedListener<T>> {
+
+    private T object;
+
+    public ChangedEvent() {
+    }
+
+    public ChangedEvent(T object) {
+        this.object = object;
+    }
+
+    protected void fire(ChangedListener<T> l) {
+        l.changed(object);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEventProvider.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface ChangedEventProvider<T> {
+
+    public ChangedEvent<T> getChangedEvent();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedListener.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface ChangedListener<T> {
+
+    public 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/Event.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public abstract class Event<L> {
+
+    private List<L> listener;
+
+    public Event() {
+        listener = new ArrayList<L>();
+    }
+
+    public void addListener(L l) {
+        listener.add(l);
+    }
+
+    public void removeListener(L l) {
+        listener.remove(l);
+    }
+
+    public void fire() {
+        List<L> tmpList = new ArrayList<L>(listener);
+        for (L l : tmpList) {
+            fire(l);
+        }
+    }
+
+    protected abstract void fire(L l);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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.Object implements ChangedEventProvider<GraphDocument> {
+
+    private List<Group> groups;
+    private ChangedEvent<GraphDocument> changedEvent;
+
+    public GraphDocument() {
+        groups = new ArrayList<Group>();
+        changedEvent = new ChangedEvent<GraphDocument>(this);
+    }
+
+    public void clear() {
+        groups.clear();
+        getChangedEvent().fire();
+    }
+
+    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);
+        }
+        document.clear();
+        getChangedEvent().fire();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+
+        sb.append("GraphDocument: " + getProperties().toString() + " \n\n");
+        for (Group g : getGroups()) {
+            sb.append(g.toString());
+            sb.append("\n\n");
+        }
+
+        return sb.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,141 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Group extends Properties.Object implements ChangedEventProvider<Group> {
+
+    private List<InputGraph> graphs;
+    private transient ChangedEvent<Group> changedEvent;
+    private GraphDocument document;
+    private InputMethod method;
+    private String assembly;
+
+    public Group() {
+        graphs = new ArrayList<InputGraph>();
+        init();
+    }
+
+    private void init() {
+        changedEvent = new ChangedEvent<Group>(this);
+    }
+
+    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;
+    }
+
+    public InputMethod getMethod() {
+        return method;
+    }
+
+    void setDocument(GraphDocument document) {
+        this.document = document;
+    }
+
+    public GraphDocument getDocument() {
+        return document;
+    }
+
+    public ChangedEvent<Group> getChangedEvent() {
+        return changedEvent;
+    }
+
+    public List<InputGraph> getGraphs() {
+        return Collections.unmodifiableList(graphs);
+    }
+
+    public void addGraph(InputGraph g) {
+        assert g != null;
+        assert !graphs.contains(g);
+        graphs.add(g);
+        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);
+            }
+        }
+        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(g.toString());
+            sb.append("\n");
+        }
+        return sb.toString();
+    }
+
+    public String getName() {
+        return getProperties().get("name");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+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;
+
+    public 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);
+        }
+    }
+
+    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);
+        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);
+    }
+
+    public void resolveBlockLinks() {
+        for (String s : successorNames) {
+            InputBlock b = graph.getBlock(s);
+            addSuccessor(b);
+        }
+
+        successorNames.clear();
+    }
+
+    public 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();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlockEdge.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputBlockEdge {
+
+    private InputBlock from;
+    private InputBlock to;
+
+    public InputBlockEdge(InputBlock from, InputBlock to) {
+        assert from != null;
+        assert to != null;
+        this.from = from;
+        this.to = to;
+    }
+
+    public InputBlock getFrom() {
+        return from;
+    }
+
+    public InputBlock getTo() {
+        return to;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (obj instanceof InputBlockEdge && obj != null) {
+            InputBlockEdge e = (InputBlockEdge) obj;
+            return e.from.equals(from) && e.to.equals(to);
+        }
+        return super.equals(obj);
+    }
+
+    @Override
+    public int hashCode() {
+        int hash = from.hashCode();
+        hash = 59 * hash + to.hashCode();
+        return hash;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBytecode.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputBytecode {
+
+    private int bci;
+    private String name;
+    private InputMethod inlined;
+
+    public InputBytecode(int bci, String name) {
+        this.bci = bci;
+        this.name = name;
+    }
+
+    public InputMethod getInlined() {
+        return inlined;
+    }
+
+    public void setInlined(InputMethod inlined) {
+        this.inlined = inlined;
+    }
+
+    public int getBci() {
+        return bci;
+    }
+
+    public String getName() {
+        return name;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputEdge {
+
+    public enum State {
+
+        SAME,
+        NEW,
+        DELETED
+    }
+    private char toIndex;
+    private int from;
+    private int to;
+    private State state;
+
+    public InputEdge(char toIndex, int from, int to) {
+        this.toIndex = toIndex;
+        this.from = from;
+        this.to = to;
+        this.state = State.SAME;
+    }
+
+    public State getState() {
+        return state;
+    }
+
+    public void setState(State x) {
+        this.state = x;
+    }
+
+    public char getToIndex() {
+        return toIndex;
+    }
+
+    public String getName() {
+        return "in" + toIndex;
+    }
+
+    public int getFrom() {
+        return from;
+    }
+
+    public int getTo() {
+        return to;
+    }
+
+    @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;
+    }
+
+    @Override
+    public String toString() {
+        return "Edge from " + from + " to " + to + "(" + (int) toIndex + ") ";
+    }
+
+    @Override
+    public int hashCode() {
+        return (from << 20 | to << 8 | toIndex);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+import com.sun.hotspot.igv.data.Properties;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputGraph extends Properties.Object {
+
+    private Map<Integer, InputNode> nodes;
+    private Set<InputEdge> edges;
+    private Group parent;
+    private Map<String, InputBlock> blocks;
+    private Map<Integer, InputBlock> nodeToBlock;
+    private boolean isDifferenceGraph;
+
+    public InputGraph(Group parent) {
+        this(parent, null);
+    }
+
+    public InputGraph(Group parent, InputGraph last) {
+        this(parent, last, "");
+    }
+
+    private void clearBlocks() {
+        blocks.clear();
+        nodeToBlock.clear();
+    }
+
+    public InputGraph(Group parent, InputGraph last, String name) {
+        this.parent = parent;
+        setName(name);
+        nodes = new Hashtable<Integer, InputNode>();
+        edges = new HashSet<InputEdge>();
+        blocks = new Hashtable<String, InputBlock>();
+        nodeToBlock = new Hashtable<Integer, InputBlock>();
+        if (last != null) {
+
+            for (InputNode n : last.getNodes()) {
+                addNode(n);
+            }
+
+            for (InputEdge c : last.getEdges()) {
+                addEdge(c);
+            }
+        }
+    }
+
+    public void schedule(Collection<InputBlock> newBlocks) {
+        clearBlocks();
+        InputBlock noBlock = new InputBlock(this, "no block");
+        Set<InputNode> scheduledNodes = new HashSet<InputNode>();
+
+        for (InputBlock b : newBlocks) {
+            for (InputNode n : b.getNodes()) {
+                assert !scheduledNodes.contains(n);
+                scheduledNodes.add(n);
+            }
+        }
+
+        for (InputNode n : this.getNodes()) {
+            assert nodes.get(n.getId()) == n;
+            if (!scheduledNodes.contains(n)) {
+                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;
+        }
+    }
+
+    public void setBlock(InputNode node, InputBlock block) {
+        nodeToBlock.put(node.getId(), block);
+    }
+
+    public InputBlock getBlock(int nodeId) {
+        return nodeToBlock.get(nodeId);
+    }
+
+    public InputBlock getBlock(InputNode 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);
+        }
+    }
+
+    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);
+        }
+    }
+
+    public String getName() {
+        return getProperties().get("name");
+    }
+
+    public String getAbsoluteName() {
+        String result = getName();
+        if (this.parent != null) {
+            result = parent.getName() + ": " + result;
+        }
+        return result;
+    }
+
+    public Collection<InputNode> getNodes() {
+        return Collections.unmodifiableCollection(nodes.values());
+    }
+
+    public Set<Integer> getNodesAsSet() {
+        return Collections.unmodifiableSet(nodes.keySet());
+    }
+
+    public Collection<InputBlock> getBlocks() {
+        return Collections.unmodifiableCollection(blocks.values());
+    }
+
+    public void addNode(InputNode node) {
+        nodes.put(node.getId(), node);
+    }
+
+    public InputNode getNode(int id) {
+        return nodes.get(id);
+    }
+
+    public InputNode removeNode(int index) {
+        return nodes.remove(index);
+    }
+
+    public Set<InputEdge> getEdges() {
+        return Collections.unmodifiableSet(edges);
+    }
+
+    public void removeEdge(InputEdge c) {
+        assert edges.contains(c);
+        edges.remove(c);
+        assert !edges.contains(c);
+    }
+
+    public void addEdge(InputEdge c) {
+        assert !edges.contains(c);
+        edges.add(c);
+        assert edges.contains(c);
+    }
+
+    public Group getGroup() {
+        return parent;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("Graph " + getName() + " " + getProperties().toString() + "\n");
+        for (InputNode n : nodes.values()) {
+            sb.append(n.toString());
+            sb.append("\n");
+        }
+
+        for (InputEdge c : edges) {
+            sb.append(c.toString());
+            sb.append("\n");
+        }
+        return sb.toString();
+    }
+
+    public void addBlock(InputBlock b) {
+        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);
+    }
+
+    public InputBlock getBlock(String s) {
+        return blocks.get(s);
+    }
+
+    public boolean isDifferenceGraph() {
+        return this.isDifferenceGraph;
+    }
+
+    public void setIsDifferenceGraph(boolean b) {
+        isDifferenceGraph = b;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputMethod extends Properties.Object {
+
+    private String name;
+    private int bci;
+    private String shortName;
+    private List<InputMethod> inlined;
+    private InputMethod parentMethod;
+    private Group group;
+    private List<InputBytecode> 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>();
+    }
+
+    public List<InputBytecode> getBytecodes() {
+        return Collections.unmodifiableList(bytecodes);
+    }
+
+    public List<InputMethod> getInlined() {
+        return Collections.unmodifiableList(inlined);
+    }
+
+    public void addInlined(InputMethod m) {
+
+        // assert bci unique
+        for (InputMethod m2 : inlined) {
+            assert m2.getBci() != m.getBci();
+        }
+
+        inlined.add(m);
+        assert m.parentMethod == null;
+        m.parentMethod = this;
+
+        for (InputBytecode bc : bytecodes) {
+            if (bc.getBci() == m.getBci()) {
+                bc.setInlined(m);
+            }
+        }
+    }
+
+    public Group getGroup() {
+        return group;
+    }
+
+    public String getShortName() {
+        return shortName;
+    }
+
+    public void setBytecodes(String text) {
+
+        String[] strings = text.split("\n");
+        int oldNumber = -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());
+
+                int number = -1;
+                number = Integer.parseInt(numberString);
+
+                // assert correct order of bytecodes
+                assert number > oldNumber;
+
+                InputBytecode bc = new InputBytecode(number, tmpName);
+                bytecodes.add(bc);
+
+                for (InputMethod m : inlined) {
+                    if (m.getBci() == number) {
+                        bc.setInlined(m);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public int getBci() {
+        return bci;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputNode extends Properties.Object {
+
+    private int id;
+
+    public InputNode(InputNode n) {
+        super(n);
+        setId(n.id);
+    }
+
+    public InputNode(int id) {
+        setId(id);
+    }
+
+    public void setId(int id) {
+        this.id = id;
+        getProperties().setProperty("id", "" + id);
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    @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());
+    }
+
+    @Override
+    public int hashCode() {
+        return id;
+    }
+
+    @Override
+    public String toString() {
+        return "Node " + id + " " + getProperties().toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Pair.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Pair<L, R> {
+
+    private L l;
+    private R r;
+
+    public Pair() {
+    }
+
+    public Pair(L l, R r) {
+        this.l = l;
+        this.r = r;
+    }
+
+    public L getLeft() {
+        return l;
+    }
+
+    public void setLeft(L l) {
+        this.l = l;
+    }
+
+    public R getRight() {
+        return r;
+    }
+
+    public void setRight(R r) {
+        this.r = r;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Pair)) {
+            return false;
+        }
+        Pair obj = (Pair) o;
+        return l.equals(obj.l) && r.equals(obj.r);
+    }
+
+    @Override
+    public int hashCode() {
+        return l.hashCode() * 71 + r.hashCode();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+import java.io.Serializable;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Properties implements Serializable {
+
+    public static final long serialVersionUID = 1L;
+    private Map<String, Property> map;
+
+    public Properties() {
+        map = new HashMap<String, Property>(5);
+    }
+
+    @Override
+    public boolean equals(java.lang.Object o) {
+        if (!(o instanceof Properties)) {
+            return false;
+        }
+
+        Properties p = (Properties) o;
+
+        if (getProperties().size() != p.getProperties().size()) {
+            return false;
+        }
+        for (Property prop : getProperties()) {
+            String value = p.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);
+        return hash;
+    }
+
+    public Properties(String name, String value) {
+        this();
+        this.add(new Property(name, value));
+    }
+
+    public Properties(String name, String value, String name1, String value1) {
+        this(name, value);
+        this.add(new Property(name1, value1));
+    }
+
+    public Properties(String name, String value, String name1, String value1, String name2, String value2) {
+        this(name, value, name1, value1);
+        this.add(new Property(name2, value2));
+    }
+
+    public Properties(Properties p) {
+        map = new HashMap<String, Property>(p.map);
+    }
+
+    public static class Object implements Provider {
+
+        private Properties properties;
+
+        public Object() {
+            properties = new Properties();
+        }
+
+        public Object(Properties.Object object) {
+            properties = new Properties(object.getProperties());
+        }
+
+        public Properties getProperties() {
+            return properties;
+        }
+    }
+
+    public interface PropertyMatcher {
+
+        String getName();
+
+        boolean match(String value);
+    }
+
+    public static class InvertPropertyMatcher implements PropertyMatcher {
+
+        private PropertyMatcher matcher;
+
+        public InvertPropertyMatcher(PropertyMatcher matcher) {
+            this.matcher = matcher;
+        }
+
+        public String getName() {
+            return matcher.getName();
+        }
+
+        public boolean match(String p) {
+            return !matcher.match(p);
+        }
+    }
+
+    public static class StringPropertyMatcher implements PropertyMatcher {
+
+        private String name;
+        private String value;
+
+        public StringPropertyMatcher(String name, String value) {
+            this.name = name;
+            this.value = value;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public boolean match(String p) {
+            return p.equals(value);
+        }
+    }
+
+    public static class RegexpPropertyMatcher implements PropertyMatcher {
+
+        private String name;
+        private Pattern valuePattern;
+
+        public RegexpPropertyMatcher(String name, String value) {
+            this.name = name;
+            valuePattern = Pattern.compile(value);
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public boolean match(String p) {
+            Matcher m = valuePattern.matcher(p);
+            return m.matches();
+        }
+    }
+
+    public Property selectSingle(PropertyMatcher matcher) {
+
+        Property p = this.map.get(matcher.getName());
+        if (p == null) {
+            return null;
+        }
+        if (matcher.match(p.getValue())) {
+            return p;
+        } else {
+            return null;
+        }
+    }
+
+    public interface Provider {
+
+        public Properties getProperties();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("[");
+        for (Property p : map.values()) {
+            sb.append(p.toString());
+        }
+        return sb.append("]").toString();
+    }
+
+    public static class PropertySelector<T extends Properties.Provider> {
+
+        private Collection<T> objects;
+
+        public PropertySelector(Collection<T> objects) {
+            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) {
+                Property p = t.getProperties().selectSingle(matcher);
+                if (p != null) {
+                    return t;
+                }
+            }
+
+            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<T>();
+            for (T t : objects) {
+                Property p = t.getProperties().selectSingle(matcher);
+                if (p != null) {
+                    result.add(t);
+                }
+            }
+            return result;
+        }
+    }
+
+    public String get(String key) {
+        Property p = map.get(key);
+        if (p == null) {
+            return null;
+        } else {
+            return p.getValue();
+        }
+    }
+
+    public String getProperty(String string) {
+        return get(string);
+    }
+
+    public Property setProperty(String name, String value) {
+
+        if (value == null) {
+            // remove this property
+            return map.remove(name);
+        } else {
+            Property p = map.get(name);
+            if (p == null) {
+                p = new Property(name, value);
+                map.put(name, p);
+            } else {
+                p.setValue(value);
+            }
+            return p;
+        }
+    }
+
+    public Collection<Property> getProperties() {
+        return Collections.unmodifiableCollection(map.values());
+    }
+
+    public void add(Properties properties) {
+        for (Property p : properties.getProperties()) {
+            add(p);
+        }
+    }
+
+    public void add(Property property) {
+        assert property.getName() != null;
+        assert property.getValue() != null;
+        map.put(property.getName(), property);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.data;
+
+import java.io.Serializable;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Property implements Serializable {
+
+    public static final long serialVersionUID = 1L;
+    private String name;
+    private String value;
+
+    public Property() {
+        this(null, null);
+    }
+
+    public Property(Property p) {
+        this(p.getName(), p.getValue());
+    }
+
+    public Property(String name) {
+        this(name, null);
+    }
+
+    public Property(String name, String value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+    public void setName(String s) {
+        this.name = s;
+    }
+
+    public void setValue(String s) {
+        this.value = s;
+    }
+
+    @Override
+    public String toString() {
+        return name + " = " + value + "; ";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,422 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 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.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 java.io.IOException;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.XMLReader;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Parser {
+
+    public static final String INDENT = "  ";
+    public static final String TOP_ELEMENT = "graphDocument";
+    public static final String GROUP_ELEMENT = "group";
+    public static final String GRAPH_ELEMENT = "graph";
+    public static final String ROOT_ELEMENT = "graphDocument";
+    public static final String PROPERTIES_ELEMENT = "properties";
+    public static final String EDGES_ELEMENT = "edges";
+    public static final String PROPERTY_ELEMENT = "p";
+    public static final String EDGE_ELEMENT = "edge";
+    public static final String NODE_ELEMENT = "node";
+    public static final String NODES_ELEMENT = "nodes";
+    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 METHOD_IS_PUBLIC_PROPERTY = "public";
+    public static final String METHOD_IS_STATIC_PROPERTY = "static";
+    public static final String TRUE_VALUE = "true";
+    public static final String NODE_NAME_PROPERTY = "name";
+    public static final String EDGE_NAME_PROPERTY = "name";
+    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 PROPERTY_NAME_PROPERTY = "name";
+    public static final String GRAPH_NAME_PROPERTY = "name";
+    public static final String TO_INDEX_PROPERTY = "index";
+    public static final String METHOD_ELEMENT = "method";
+    public static final String INLINE_ELEMENT = "inline";
+    public static final String BYTECODES_ELEMENT = "bytecodes";
+    public static final String METHOD_BCI_PROPERTY = "bci";
+    public static final String METHOD_SHORT_NAME_PROPERTY = "shortName";
+    public static final String CONTROL_FLOW_ELEMENT = "controlFlow";
+    public static final String BLOCK_NAME_PROPERTY = "name";
+    public static final String BLOCK_ELEMENT = "block";
+    public static final String SUCCESSORS_ELEMENT = "successors";
+    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 GroupCallback groupCallback;
+    // <graphDocument>
+    private ElementHandler<GraphDocument, Object> topHandler = new ElementHandler<GraphDocument, Object>(TOP_ELEMENT) {
+
+        @Override
+        protected GraphDocument start() throws SAXException {
+            return new GraphDocument();
+        }
+    };
+    // <group>
+    private ElementHandler<Group, GraphDocument> groupHandler = new XMLParser.ElementHandler<Group, GraphDocument>(GROUP_ELEMENT) {
+
+        @Override
+        protected Group start() throws SAXException {
+            Group group = new Group();
+            Parser.this.difference = false;
+            String differenceProperty = this.readAttribute(DIFFERENCE_PROPERTY);
+            if (differenceProperty != null && (differenceProperty.equals("1") || differenceProperty.equals("true"))) {
+                Parser.this.difference = true;
+            }
+
+            ParseMonitor monitor = getMonitor();
+            if (monitor != null) {
+                monitor.setState(group.getName());
+            }
+
+            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>
+    private ElementHandler<InputMethod, Group> methodHandler = new XMLParser.ElementHandler<InputMethod, Group>(METHOD_ELEMENT) {
+
+        @Override
+        protected InputMethod start() throws SAXException {
+
+            InputMethod method = parseMethod(this, getParentObject());
+            getParentObject().setMethod(method);
+            return method;
+        }
+    };
+
+    private InputMethod parseMethod(XMLParser.ElementHandler handler, Group group) throws SAXException {
+        String s = handler.readRequiredAttribute(METHOD_BCI_PROPERTY);
+        int bci = 0;
+        try {
+            bci = Integer.parseInt(s);
+        } catch (NumberFormatException e) {
+            throw new SAXException(e);
+        }
+        InputMethod method = new InputMethod(group, handler.readRequiredAttribute(METHOD_NAME_PROPERTY), handler.readRequiredAttribute(METHOD_SHORT_NAME_PROPERTY), bci);
+        return method;
+    }
+    // <bytecodes>
+    private HandoverElementHandler<InputMethod> bytecodesHandler = new XMLParser.HandoverElementHandler<InputMethod>(BYTECODES_ELEMENT, true) {
+
+        @Override
+        protected void end(String text) throws SAXException {
+            getParentObject().setBytecodes(text);
+        }
+    };
+    // <inlined>
+    private HandoverElementHandler<InputMethod> inlinedHandler = new XMLParser.HandoverElementHandler<InputMethod>(INLINE_ELEMENT);
+    // <inlined><method>
+    private ElementHandler<InputMethod, InputMethod> inlinedMethodHandler = new XMLParser.ElementHandler<InputMethod, InputMethod>(METHOD_ELEMENT) {
+
+        @Override
+        protected InputMethod start() throws SAXException {
+            InputMethod method = parseMethod(this, getParentObject().getGroup());
+            getParentObject().addInlined(method);
+            return method;
+        }
+    };
+    // <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(getParentObject(), previous, name);
+            getParentObject().addGraph(curGraph);
+            this.graph = curGraph;
+            return curGraph;
+        }
+
+        @Override
+        protected void end(String text) throws SAXException {
+            graph.resolveBlockLinks();
+        }
+    };
+    // <nodes>
+    private HandoverElementHandler<InputGraph> nodesHandler = new HandoverElementHandler<InputGraph>(NODES_ELEMENT);
+    // <controlFlow>
+    private HandoverElementHandler<InputGraph> controlFlowHandler = new HandoverElementHandler<InputGraph>(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);
+            InputBlock b = new InputBlock(getParentObject(), name);
+            graph.addBlock(b);
+            return b;
+        }
+    };
+    // <nodes>
+    private HandoverElementHandler<InputBlock> blockNodesHandler = new HandoverElementHandler<InputBlock>(NODES_ELEMENT);
+    // <node>
+    private ElementHandler<InputBlock, InputBlock> blockNodeHandler = new ElementHandler<InputBlock, InputBlock>(NODE_ELEMENT) {
+
+        @Override
+        protected InputBlock start() throws SAXException {
+            String s = readRequiredAttribute(NODE_ID_PROPERTY);
+
+            int id = 0;
+            try {
+                id = Integer.parseInt(s);
+            } catch (NumberFormatException e) {
+                throw new SAXException(e);
+            }
+            getParentObject().addNode(id);
+            return getParentObject();
+        }
+    };
+    // <successors>
+    private HandoverElementHandler<InputBlock> successorsHandler = new HandoverElementHandler<InputBlock>(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);
+            return getParentObject();
+        }
+    };
+    // <node>
+    private ElementHandler<InputNode, InputGraph> nodeHandler = new ElementHandler<InputNode, InputGraph>(NODE_ELEMENT) {
+
+        @Override
+        protected InputNode start() throws SAXException {
+            String s = readRequiredAttribute(NODE_ID_PROPERTY);
+            int id = 0;
+            try {
+                id = Integer.parseInt(s);
+            } catch (NumberFormatException e) {
+                throw new SAXException(e);
+            }
+            InputNode node = new InputNode(id);
+            getParentObject().addNode(node);
+            return node;
+        }
+    };
+    // <removeNode>
+    private ElementHandler<InputNode, InputGraph> removeNodeHandler = new ElementHandler<InputNode, InputGraph>(REMOVE_NODE_ELEMENT) {
+
+        @Override
+        protected InputNode start() throws SAXException {
+            String s = readRequiredAttribute(NODE_ID_PROPERTY);
+            int id = 0;
+            try {
+                id = Integer.parseInt(s);
+            } catch (NumberFormatException e) {
+                throw new SAXException(e);
+            }
+            return getParentObject().removeNode(id);
+        }
+    };
+    // <graph>
+    private HandoverElementHandler<InputGraph> edgesHandler = new HandoverElementHandler<InputGraph>(EDGES_ELEMENT);
+
+    // Local class for edge elements
+    private static class EdgeElementHandler extends ElementHandler<InputEdge, InputGraph> {
+
+        public EdgeElementHandler(String name) {
+            super(name);
+        }
+
+        @Override
+        protected InputEdge start() throws SAXException {
+            int toIndex = 0;
+            int from = -1;
+            int to = -1;
+
+            try {
+                String toIndexString = readAttribute(TO_INDEX_PROPERTY);
+                if (toIndexString != null) {
+                    toIndex = Integer.parseInt(toIndexString);
+                }
+
+                from = Integer.parseInt(readRequiredAttribute(FROM_PROPERTY));
+                to = Integer.parseInt(readRequiredAttribute(TO_PROPERTY));
+            } catch (NumberFormatException e) {
+                throw new SAXException(e);
+            }
+
+
+            InputEdge conn = new InputEdge((char) toIndex, from, to);
+            return start(conn);
+        }
+
+        protected InputEdge start(InputEdge conn) throws SAXException {
+            return conn;
+        }
+    }
+    // <edge>
+    private EdgeElementHandler edgeHandler = new EdgeElementHandler(EDGE_ELEMENT) {
+
+        @Override
+        protected InputEdge start(InputEdge conn) throws SAXException {
+            getParentObject().addEdge(conn);
+            return conn;
+        }
+    };
+    // <removeEdge>
+    private EdgeElementHandler removeEdgeHandler = new EdgeElementHandler(REMOVE_EDGE_ELEMENT) {
+
+        @Override
+        protected InputEdge start(InputEdge conn) throws SAXException {
+            getParentObject().removeEdge(conn);
+            return conn;
+        }
+    };
+    // <properties>
+    private HandoverElementHandler<Properties.Provider> propertiesHandler = new HandoverElementHandler<Properties.Provider>(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());
+            }
+        }
+    };
+    // <property>
+    private ElementHandler<Property, Properties.Provider> propertyHandler = new XMLParser.ElementHandler<Property, Properties.Provider>(PROPERTY_ELEMENT, true) {
+
+        @Override
+        public Property start() throws SAXException {
+            String value = "";
+            String name = readRequiredAttribute(PROPERTY_NAME_PROPERTY).intern();
+            return getParentObject().getProperties().setProperty(name, value);
+        }
+
+        @Override
+        public void end(String text) {
+            getObject().setValue(text.trim().intern());
+        }
+    };
+
+    public Parser() {
+        this(null);
+    }
+
+    public Parser(GroupCallback groupCallback) {
+
+        this.groupCallback = groupCallback;
+
+        // Initialize dependencies
+        xmlDocument.addChild(topHandler);
+        topHandler.addChild(groupHandler);
+
+        groupHandler.addChild(methodHandler);
+        groupHandler.addChild(assemblyHandler);
+        groupHandler.addChild(graphHandler);
+
+        methodHandler.addChild(inlinedHandler);
+        methodHandler.addChild(bytecodesHandler);
+
+        inlinedHandler.addChild(inlinedMethodHandler);
+        inlinedMethodHandler.addChild(bytecodesHandler);
+        inlinedMethodHandler.addChild(inlinedHandler);
+
+        graphHandler.addChild(nodesHandler);
+        graphHandler.addChild(edgesHandler);
+        graphHandler.addChild(controlFlowHandler);
+
+        controlFlowHandler.addChild(blockHandler);
+
+        blockHandler.addChild(successorsHandler);
+        successorsHandler.addChild(successorHandler);
+        blockHandler.addChild(blockNodesHandler);
+        blockNodesHandler.addChild(blockNodeHandler);
+
+        nodesHandler.addChild(nodeHandler);
+        nodesHandler.addChild(removeNodeHandler);
+        edgesHandler.addChild(edgeHandler);
+        edgesHandler.addChild(removeEdgeHandler);
+
+        methodHandler.addChild(propertiesHandler);
+        inlinedMethodHandler.addChild(propertiesHandler);
+        topHandler.addChild(propertiesHandler);
+        groupHandler.addChild(groupPropertiesHandler);
+        graphHandler.addChild(propertiesHandler);
+        nodeHandler.addChild(propertiesHandler);
+        propertiesHandler.addChild(propertyHandler);
+        groupPropertiesHandler.addChild(propertyHandler);
+    }
+
+    // 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));
+        try {
+            reader.parse(source);
+        } catch (IOException ex) {
+            throw new SAXException(ex);
+        }
+
+        return topHandler.getObject();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 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 java.io.IOException;
+import java.io.Writer;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Printer {
+
+    public void export(Writer writer, GraphDocument document) {
+
+        XMLWriter xmlWriter = new XMLWriter(writer);
+
+        try {
+            export(xmlWriter, document);
+        } catch (IOException ex) {
+        }
+    }
+
+    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);
+        }
+
+        xmlWriter.endTag();
+        xmlWriter.flush();
+    }
+
+    private void export(XMLWriter writer, Group g) throws IOException {
+        Properties attributes = new Properties();
+        attributes.add(new Property("difference", Boolean.toString(true)));
+        writer.startTag(Parser.GROUP_ELEMENT, attributes);
+        writer.writeProperties(g.getProperties());
+
+        if (g.getMethod() != null) {
+            export(writer, g.getMethod());
+        }
+
+        InputGraph previous = null;
+        for (InputGraph graph : g.getGraphs()) {
+            export(writer, graph, previous, true);
+            previous = graph;
+        }
+
+        writer.endTag();
+    }
+
+    public void export(XMLWriter writer, InputGraph graph, InputGraph previous, boolean difference) throws IOException {
+
+        writer.startTag(Parser.GRAPH_ELEMENT);
+        writer.writeProperties(graph.getProperties());
+        writer.startTag(Parser.NODES_ELEMENT);
+
+        Set<InputNode> removed = new HashSet<InputNode>();
+        Set<InputNode> equal = new HashSet<InputNode>();
+
+        if (previous != null) {
+            for (InputNode n : previous.getNodes()) {
+                int id = n.getId();
+                InputNode n2 = graph.getNode(id);
+                if (n2 == null) {
+                    removed.add(n);
+                } else if (n.equals(n2)) {
+                    equal.add(n);
+                }
+            }
+        }
+
+        if (difference) {
+            for (InputNode n : removed) {
+                writer.simpleTag(Parser.REMOVE_NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, Integer.toString(n.getId())));
+            }
+        }
+
+        for (InputNode n : graph.getNodes()) {
+            if (!difference || !equal.contains(n)) {
+                writer.startTag(Parser.NODE_ELEMENT, new Properties(Parser.NODE_ID_PROPERTY, Integer.toString(n.getId())));
+                writer.writeProperties(n.getProperties());
+                writer.endTag();
+            }
+        }
+
+        writer.endTag();
+
+        writer.startTag(Parser.EDGES_ELEMENT);
+        Set<InputEdge> removedEdges = new HashSet<InputEdge>();
+        Set<InputEdge> equalEdges = new HashSet<InputEdge>();
+
+        if (previous != null) {
+            for (InputEdge e : previous.getEdges()) {
+                if (graph.getEdges().contains(e)) {
+                    equalEdges.add(e);
+                } else {
+                    removedEdges.add(e);
+                }
+            }
+        }
+
+        if (difference) {
+            for (InputEdge e : removedEdges) {
+                writer.simpleTag(Parser.REMOVE_EDGE_ELEMENT, createProperties(e));
+            }
+        }
+
+        for (InputEdge e : graph.getEdges()) {
+            if (!difference || !equalEdges.contains(e)) {
+                if (!equalEdges.contains(e)) {
+                    writer.simpleTag(Parser.EDGE_ELEMENT, createProperties(e));
+                }
+            }
+        }
+
+        writer.endTag();
+
+        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()));
+            }
+            writer.endTag();
+
+            writer.startTag(Parser.NODES_ELEMENT);
+            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();
+    }
+
+    private void export(XMLWriter w, InputMethod method) throws IOException {
+
+        w.startTag(Parser.METHOD_ELEMENT, new Properties(Parser.METHOD_BCI_PROPERTY, method.getBci() + "", Parser.METHOD_NAME_PROPERTY, method.getName(), Parser.METHOD_SHORT_NAME_PROPERTY, method.getShortName()));
+
+        w.writeProperties(method.getProperties());
+
+        if (method.getInlined().size() > 0) {
+            w.startTag(Parser.INLINE_ELEMENT);
+            for (InputMethod m : method.getInlined()) {
+                export(w, m);
+            }
+            w.endTag();
+        }
+
+        w.startTag(Parser.BYTECODES_ELEMENT);
+
+        StringBuilder b = new StringBuilder();
+        b.append("<![CDATA[\n");
+        for (InputBytecode code : method.getBytecodes()) {
+            b.append(code.getBci());
+            b.append(" ");
+            b.append(code.getName());
+            b.append("\n");
+
+        }
+        b.append("]]>");
+        w.write(b.toString());
+        w.endTag();
+        w.endTag();
+    }
+
+    private Properties createProperties(InputEdge edge) {
+        Properties p = new Properties();
+        p.setProperty(Parser.TO_INDEX_PROPERTY, Integer.toString(edge.getToIndex()));
+        p.setProperty(Parser.TO_PROPERTY, Integer.toString(edge.getTo()));
+        p.setProperty(Parser.FROM_PROPERTY, Integer.toString(edge.getFrom()));
+        return p;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLParser.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.data.serialization;
+
+import com.sun.hotspot.igv.data.Property;
+import com.sun.hotspot.igv.data.Properties;
+import java.util.Hashtable;
+import java.util.Stack;
+import org.xml.sax.Attributes;
+import org.xml.sax.ContentHandler;
+import org.xml.sax.Locator;
+import org.xml.sax.SAXException;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+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;
+
+        public MissingAttributeException(String name) {
+            super("Missing attribute \"" + name + "\"");
+            this.name = name;
+        }
+
+        public String getAttributeName() {
+            return this.getMessage();
+        }
+    }
+
+    public static class HandoverElementHandler<P> extends ElementHandler<P, P> {
+
+        @Override
+        protected P start() throws SAXException {
+            return getParentObject();
+        }
+
+        public HandoverElementHandler(String name) {
+            super(name);
+        }
+
+        public HandoverElementHandler(String name, boolean needsText) {
+            super(name, needsText);
+        }
+    }
+
+    public static class TopElementHandler<P> extends ElementHandler<P, Object> {
+
+        public TopElementHandler() {
+            super(null);
+        }
+    }
+
+    public static class ElementHandler<T, P> {
+
+        private String name;
+        private T object;
+        private Attributes attr;
+        private StringBuilder currentText;
+        private ParseMonitor monitor;
+        private Hashtable<String, ElementHandler<?, ? super T>> hashtable;
+        private boolean needsText;
+        private ElementHandler<P, ?> parentElement;
+
+        public ElementHandler(String name) {
+            this(name, false);
+        }
+
+        public ElementHandler<P, ?> getParentElement() {
+            return parentElement;
+        }
+
+        public P getParentObject() {
+            return getParentElement().getObject();
+        }
+
+        protected boolean needsText() {
+            return needsText;
+        }
+
+        public ElementHandler(String name, boolean needsText) {
+            this.hashtable = new Hashtable<String, ElementHandler<?, ? super T>>();
+            this.name = name;
+            this.needsText = needsText;
+        }
+
+        public ParseMonitor getMonitor() {
+            return monitor;
+        }
+
+        public ElementHandler<?, ? super T> getChild(String name) {
+            return hashtable.get(name);
+        }
+
+        public void addChild(ElementHandler<?, ? super T> handler) {
+            assert handler != null;
+            hashtable.put(handler.getName(), handler);
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public T getObject() {
+            return object;
+        }
+
+        public String readAttribute(String name) {
+            return attr.getValue(name);
+        }
+
+        public String readRequiredAttribute(String name) throws SAXException {
+            String s = readAttribute(name);
+            if (s == null) {
+                throw new MissingAttributeException(name);
+            }
+            return s;
+        }
+
+        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();
+                p.add(new Property(val, localName));
+            }
+        }
+
+        public void startElement(ElementHandler<P, ?> parentElement, Attributes attr, ParseMonitor monitor) throws SAXException {
+            this.currentText = new StringBuilder();
+            this.attr = attr;
+            this.monitor = monitor;
+            this.parentElement = parentElement;
+            object = start();
+        }
+
+        protected T start() throws SAXException {
+            return null;
+        }
+
+        protected void end(String text) throws SAXException {
+
+        }
+
+        public void endElement() throws SAXException {
+            end(currentText.toString());
+        }
+
+        protected void text(char[] c, int start, int length) {
+            assert currentText != null;
+            currentText.append(c, start, length);
+        }
+    }
+    private Stack<ElementHandler> stack;
+    private ParseMonitor monitor;
+
+    public XMLParser(TopElementHandler rootHandler, ParseMonitor monitor) {
+        this.stack = new Stack<ElementHandler>();
+        this.monitor = monitor;
+        this.stack.push(rootHandler);
+    }
+
+    public void setDocumentLocator(Locator locator) {
+        if (monitor != null) {
+            monitor.setState("Starting parsing");
+        }
+    }
+
+    public void startDocument() throws SAXException {
+    }
+
+    public void endDocument() throws SAXException {
+    }
+
+    public void startPrefixMapping(String prefix, String uri) throws SAXException {
+    }
+
+    public void endPrefixMapping(String prefix) throws SAXException {
+    }
+
+    public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException {
+
+        assert !stack.isEmpty();
+        ElementHandler parent = stack.peek();
+        if (parent != null) {
+            ElementHandler child = parent.getChild(qName);
+            if (child != null) {
+                child.startElement(parent, atts, monitor);
+                stack.push(child);
+                return;
+            }
+        }
+
+        stack.push(null);
+    }
+
+    public void endElement(String uri, String localName, String qName) throws SAXException {
+        ElementHandler handler = stack.pop();
+        if (handler != null) {
+            handler.endElement();
+        }
+    }
+
+    public void characters(char[] ch, int start, int length) throws SAXException {
+
+        assert !stack.isEmpty();
+
+
+        ElementHandler top = stack.peek();
+        if (top != null && top.needsText()) {
+            top.text(ch, start, length);
+        }
+    }
+
+    public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
+    }
+
+    public void processingInstruction(String target, String data) throws SAXException {
+    }
+
+    public void skippedEntity(String name) throws SAXException {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,128 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.hotspot.igv.data.serialization;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Property;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Stack;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class XMLWriter extends Writer {
+
+    private Writer inner;
+    private Stack<String> elementStack;
+
+    public XMLWriter(Writer inner) {
+        this.inner = inner;
+        elementStack = new Stack<String>();
+    }
+
+    @Override
+    public void write(char[] arr) throws IOException {
+        write(arr, 0, arr.length);
+    }
+
+    public void write(char[] cbuf, int off, int len) throws IOException {
+        for (int i = off; i < off + len; i++) {
+            char c = cbuf[i];
+            if (c == '>') {
+                inner.write("&gt;");
+            } else if (c == '<') {
+                inner.write("&lt;");
+            } else if (c == '&') {
+                inner.write("&amp;");
+            } else {
+                inner.write(c);
+            }
+        }
+    }
+
+    public void flush() throws IOException {
+        inner.flush();
+    }
+
+    public void close() throws IOException {
+        inner.close();
+    }
+
+    public void endTag() throws IOException {
+        inner.write("</" + elementStack.pop() + ">\n");
+    }
+
+    public void startTag(String name) throws IOException {
+        inner.write("<" + name + ">\n");
+        elementStack.push(name);
+    }
+
+    public void simpleTag(String name) throws IOException {
+        inner.write("<" + name + "/>\n");
+    }
+
+    public void startTag(String name, Properties attributes) throws IOException {
+        inner.write("<" + name);
+        elementStack.push(name);
+
+        for (Property p : attributes.getProperties()) {
+            inner.write(" " + p.getName() + "=\"");
+            write(p.getValue().toCharArray());
+            inner.write("\"");
+        }
+
+        inner.write(">\n");
+    }
+
+    public void simpleTag(String name, Properties attributes) throws IOException {
+        inner.write("<" + name);
+
+        for (Property p : attributes.getProperties()) {
+            inner.write(" " + p.getName() + "=\"");
+            write(p.getValue().toCharArray());
+            inner.write("\"");
+        }
+
+        inner.write("/>\n");
+    }
+
+    public void writeProperties(Properties props) throws IOException {
+        if (props.getProperties().size() == 0) {
+            return;
+        }
+
+        startTag(Parser.PROPERTIES_ELEMENT);
+
+        for (Property p : props.getProperties()) {
+            startTag(Parser.PROPERTY_ELEMENT, new Properties(Parser.PROPERTY_NAME_PROPERTY, p.getName()));
+            this.write(p.getValue().toCharArray());
+            endTag();
+        }
+
+        endTag();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GraphViewer.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.data.services;
+
+import com.sun.hotspot.igv.data.InputGraph;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface GraphViewer {
+
+    public void view(InputGraph graph);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupCallback.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.hotspot.igv.data.services;
+
+import com.sun.hotspot.igv.data.Group;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface GroupCallback {
+
+    public void started(Group g);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupOrganizer.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupReceiver.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/InputGraphProvider.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.hotspot.igv.data.services;
+
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputNode;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface InputGraphProvider {
+
+    InputGraph getGraph();
+
+    void setSelectedNodes(Set<InputNode> nodes);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/Scheduler.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.hotspot.igv.data.services;
+
+import com.sun.hotspot.igv.data.InputBlock;
+import com.sun.hotspot.igv.data.InputGraph;
+import java.util.Collection;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface Scheduler {
+
+    public Collection<InputBlock> schedule(InputGraph graph);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/build.xml	Wed Jul 05 16:38:46 2017 +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.difference" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.difference.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.difference
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/difference/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.difference-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=1657ecfe
+build.xml.script.CRC32=03909051
+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=1657ecfe
+nbproject/build-impl.xml.script.CRC32=2208e770
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +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.difference</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.difference</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Difference
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,320 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+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.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Difference {
+
+    public static final String PROPERTY_STATE = "state";
+    public static final String VALUE_NEW = "new";
+    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 MAIN_PROPERTY = "name";
+    public static final double LIMIT = 100.0;
+    public static final String[] IGNORE_PROPERTIES = new String[]{"idx", "debug_idx"};
+
+    public static InputGraph createDiffGraph(InputGraph a, InputGraph b) {
+        if (a.getGroup() == b.getGroup()) {
+            return createDiffSameGroup(a, b);
+        } else {
+            return createDiff(a, b);
+        }
+    }
+
+    private static InputGraph createDiffSameGroup(InputGraph a, InputGraph b) {
+        Map<Integer, InputNode> keyMapB = new HashMap<Integer, InputNode>();
+        for (InputNode n : b.getNodes()) {
+            Integer key = n.getId();
+            assert !keyMapB.containsKey(key);
+            keyMapB.put(key, n);
+        }
+
+        Set<Pair> pairs = new HashSet<Pair>();
+
+        for (InputNode n : a.getNodes()) {
+            Integer key = n.getId();
+
+
+            if (keyMapB.containsKey(key)) {
+                InputNode nB = keyMapB.get(key);
+                pairs.add(new Pair(n, nB));
+            }
+        }
+
+        return createDiff(a, b, pairs);
+    }
+
+    private static InputGraph createDiff(InputGraph a, InputGraph b, Set<Pair> pairs) {
+        Group g = new Group();
+        g.setMethod(a.getGroup().getMethod());
+        g.setAssembly(a.getGroup().getAssembly());
+        g.getProperties().setProperty("name", "Difference");
+        InputGraph graph = new InputGraph(g, null);
+        graph.setName(a.getName() + ", " + b.getName());
+        graph.setIsDifferenceGraph(true);
+
+        Set<InputNode> nodesA = new HashSet<InputNode>(a.getNodes());
+        Set<InputNode> nodesB = new HashSet<InputNode>(b.getNodes());
+
+        Map<InputNode, InputNode> inputNodeMap = new HashMap<InputNode, InputNode>();
+        for (Pair p : pairs) {
+            InputNode n = p.getN1();
+            assert nodesA.contains(n);
+            InputNode nB = p.getN2();
+            assert nodesB.contains(nB);
+
+            nodesA.remove(n);
+            nodesB.remove(nB);
+            InputNode n2 = new InputNode(n);
+            inputNodeMap.put(n, n2);
+            inputNodeMap.put(nB, n2);
+            graph.addNode(n2);
+            markAsChanged(n2, n, nB);
+        }
+
+        for (InputNode n : nodesA) {
+            InputNode n2 = new InputNode(n);
+            graph.addNode(n2);
+            markAsNew(n2);
+            inputNodeMap.put(n, n2);
+        }
+
+        for (InputNode n : nodesB) {
+            InputNode n2 = new InputNode(n);
+            n2.setId(-n2.getId());
+            graph.addNode(n2);
+            markAsDeleted(n2);
+            inputNodeMap.put(n, n2);
+        }
+
+        Set<InputEdge> edgesA = a.getEdges();
+        Set<InputEdge> edgesB = b.getEdges();
+
+        Set<InputEdge> newEdges = new HashSet<InputEdge>();
+
+        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();
+
+            InputEdge newEdge = new InputEdge(index, nodeFrom.getId(), nodeTo.getId());
+            if (!newEdges.contains(newEdge)) {
+                markAsNew(newEdge);
+                newEdges.add(newEdge);
+                graph.addEdge(newEdge);
+            }
+        }
+
+        for (InputEdge e : edgesB) {
+            int from = e.getFrom();
+            int to = e.getTo();
+            InputNode nodeFrom = inputNodeMap.get(b.getNode(from));
+            InputNode nodeTo = inputNodeMap.get(b.getNode(to));
+            char index = e.getToIndex();
+
+            InputEdge newEdge = new InputEdge(index, nodeFrom.getId(), nodeTo.getId());
+            if (!newEdges.contains(newEdge)) {
+                markAsDeleted(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 InputNode n1;
+        private InputNode n2;
+
+        public Pair(InputNode n1, InputNode n2) {
+            this.n1 = n1;
+            this.n2 = n2;
+        }
+
+        public double getValue() {
+
+            double result = 0.0;
+            for (Property p : n1.getProperties().getProperties()) {
+                double faktor = 1.0;
+                for (String forbidden : IGNORE_PROPERTIES) {
+                    if (p.getName().equals(forbidden)) {
+                        faktor = 0.1;
+                        break;
+                    }
+                }
+                String p2 = n2.getProperties().get(p.getName());
+                result += evaluate(p.getValue(), p2) * faktor;
+            }
+
+            return result;
+        }
+
+        private double evaluate(String p, String p2) {
+            if (p2 == null) {
+                return 1.0;
+            }
+            if (p.equals(p2)) {
+                return 0.0;
+            } else {
+                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<Pair> pairs = new HashSet<Pair>();
+        for (InputNode n : a.getNodes()) {
+            String s = n.getProperties().get(MAIN_PROPERTY);
+            if (s == null) {
+                s = "";
+            }
+            for (InputNode n2 : b.getNodes()) {
+                String s2 = n2.getProperties().get(MAIN_PROPERTY);
+                if (s2 == null) {
+                    s2 = "";
+                }
+
+                if (s.equals(s2)) {
+                    Pair p = new Pair(n, n2);
+                    pairs.add(p);
+                }
+            }
+        }
+
+        Set<Pair> selectedPairs = new HashSet<Pair>();
+        while (pairs.size() > 0) {
+
+            double min = Double.MAX_VALUE;
+            Pair minPair = null;
+            for (Pair p : pairs) {
+                double cur = p.getValue();
+                if (cur < min) {
+                    minPair = p;
+                    min = cur;
+                }
+            }
+
+            if (min > LIMIT) {
+                break;
+            } else {
+                selectedPairs.add(minPair);
+
+                Set<Pair> toRemove = new HashSet<Pair>();
+                for (Pair p : pairs) {
+                    if (p.getN1() == minPair.getN1() || p.getN2() == minPair.getN2()) {
+                        toRemove.add(p);
+                    }
+                }
+                pairs.removeAll(toRemove);
+            }
+        }
+
+        return createDiff(a, b, selectedPairs);
+    }
+
+    private static void markAsNew(InputEdge e) {
+        e.setState(InputEdge.State.NEW);
+    }
+
+    private static void markAsDeleted(InputEdge e) {
+        e.setState(InputEdge.State.DELETED);
+
+    }
+
+    private static void markAsSame(InputEdge e) {
+        e.setState(InputEdge.State.SAME);
+    }
+
+    private static void markAsChanged(InputNode n, InputNode firstNode, InputNode otherNode) {
+
+        boolean difference = false;
+        for (Property p : otherNode.getProperties().getProperties()) {
+            String s = firstNode.getProperties().getProperty(p.getName());
+            if (!p.getValue().equals(s)) {
+                difference = true;
+                n.getProperties().add(new Property(OLD_PREFIX + p.getName(), p.getValue()));
+            }
+        }
+
+        for (Property p : firstNode.getProperties().getProperties()) {
+            String s = otherNode.getProperties().getProperty(p.getName());
+            if (s == null && p.getValue().length() > 0) {
+                difference = true;
+                n.getProperties().add(new Property(OLD_PREFIX + p.getName(), ""));
+            }
+        }
+
+        if (difference) {
+            n.getProperties().add(new Property(PROPERTY_STATE, VALUE_CHANGED));
+        } else {
+            n.getProperties().add(new Property(PROPERTY_STATE, VALUE_SAME));
+        }
+    }
+
+    private static void markAsDeleted(InputNode n) {
+        n.getProperties().add(new Property(PROPERTY_STATE, VALUE_DELETED));
+    }
+
+    private static void markAsNew(InputNode n) {
+        n.getProperties().add(new Property(PROPERTY_STATE, VALUE_NEW));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/build.xml	Wed Jul 05 16:38:46 2017 +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.filter" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.filter.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.filter
+OpenIDE-Module-Layer: com/sun/hotspot/igv/filter/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filter/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.filter-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=7c032ebf
+build.xml.script.CRC32=3b022a25
+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=7c032ebf
+nbproject/build-impl.xml.script.CRC32=26513f91
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,80 @@
+<?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.filter</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>
+                <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>
+                    </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.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.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>
+                <package>com.sun.hotspot.igv.filter</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+com.sun.hotspot.igv.filter.JavaSE6ScriptEngine
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/AbstractFilter.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.data.Properties;
+import org.openide.cookies.OpenCookie;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public abstract class AbstractFilter implements Filter {
+
+    private ChangedEvent<Filter> changedEvent;
+    private Properties properties;
+
+    public AbstractFilter() {
+        changedEvent = new ChangedEvent<Filter>(this);
+        properties = new Properties();
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public OpenCookie getEditor() {
+        return null;
+    }
+
+    public ChangedEvent<Filter> getChangedEvent() {
+        return changedEvent;
+    }
+
+    protected void fireChangedEvent() {
+        changedEvent.fire();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,11 @@
+OpenIDE-Module-Name=Filter
+
+jLabel1.text=Name\:
+jLabel2.text=Source\:
+
+nameTextField.text=
+
+jButton1.text=OK
+jButton2.text=Cancel
+
+title=Edit Filter Dialog
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ColorFilter.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filter;
+
+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.OutputSlot;
+import com.sun.hotspot.igv.graph.Selector;
+import com.sun.hotspot.igv.data.Properties;
+import java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ColorFilter extends AbstractFilter {
+
+    private List<ColorRule> colorRules;
+    private String name;
+
+    public ColorFilter(String name) {
+        this.name = name;
+        colorRules = new ArrayList<ColorRule>();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void apply(Diagram diagram) {
+
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(diagram.getFigures());
+        for (ColorRule rule : colorRules) {
+            if (rule.getSelector() != null) {
+                List<Figure> figures = rule.getSelector().selected(diagram);
+                for (Figure f : figures) {
+                    applyRule(rule, f);
+                    if (rule.getColor() != null) {
+                        f.setColor(rule.getColor());
+                    }
+                }
+            } else {
+                for (Figure f : diagram.getFigures()) {
+                    applyRule(rule, f);
+                }
+            }
+        }
+    }
+
+    private void applyRule(ColorRule rule, Figure f) {
+        if (rule.getColor() != null) {
+            f.setColor(rule.getColor());
+        }
+        Color color = rule.getLineColor();
+        ConnectionStyle style = rule.getLineStyle();
+
+        for (OutputSlot s : f.getOutputSlots()) {
+            for (Connection c : s.getConnections()) {
+                if (color != null) {
+                    c.setColor(color);
+                }
+
+                if (style != null) {
+                    c.setStyle(style);
+                }
+            }
+        }
+    }
+
+    public void addRule(ColorRule r) {
+        colorRules.add(r);
+    }
+
+    public static class ColorRule {
+
+        private Color color;
+        private Color lineColor;
+        private Connection.ConnectionStyle lineStyle;
+        private Selector selector;
+
+        public ColorRule(Selector selector, Color c) {
+            this(selector, c, null, null);
+        }
+
+        public ColorRule(Selector selector, Color c, Color lineColor, Connection.ConnectionStyle lineStyle) {
+            this.selector = selector;
+            this.color = c;
+            this.lineColor = lineColor;
+            this.lineStyle = lineStyle;
+
+        }
+
+        public ColorRule(Color c) {
+            this(null, c);
+        }
+
+        public Color getColor() {
+            return color;
+        }
+
+        public Selector getSelector() {
+            return selector;
+        }
+
+        public Color getLineColor() {
+            return lineColor;
+        }
+
+        public Connection.ConnectionStyle getLineStyle() {
+            return lineStyle;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CombineFilter.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,194 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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 java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class CombineFilter extends AbstractFilter {
+
+    private List<CombineRule> rules;
+    private String name;
+
+    public CombineFilter(String name) {
+        this.name = name;
+        rules = new ArrayList<CombineRule>();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void apply(Diagram diagram) {
+
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(diagram.getFigures());
+        for (CombineRule r : rules) {
+
+            List<Figure> list = selector.selectMultiple(r.getFirstMatcher());
+            Set<Figure> figuresToRemove = new HashSet<Figure>();
+            for (Figure f : list) {
+
+                List<Figure> successors = new ArrayList<Figure>(f.getSuccessors());
+                if (r.isReversed()) {
+                    if (successors.size() == 1) {
+                        Figure succ = successors.get(0);
+                        InputSlot slot = null;
+
+                        for (InputSlot s : succ.getInputSlots()) {
+                            for (Connection c : s.getConnections()) {
+                                if (c.getOutputSlot().getFigure() == f) {
+                                    slot = s;
+                                }
+                            }
+                        }
+
+                        assert slot != null;
+                        slot.setName(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());
+                                newConn.setColor(c.getColor());
+                                newConn.setStyle(c.getStyle());
+                            }
+                        }
+
+                        figuresToRemove.add(f);
+                    }
+                } else {
+
+                    for (Figure succ : successors) {
+                        if (succ.getPredecessors().size() == 1) {
+                            if (succ.getProperties().selectSingle(r.getSecondMatcher()) != null && succ.getOutputSlots().size() == 1) {
+
+
+                                OutputSlot oldSlot = null;
+                                for (OutputSlot s : f.getOutputSlots()) {
+                                    for (Connection c : s.getConnections()) {
+                                        if (c.getInputSlot().getFigure() == succ) {
+                                            oldSlot = s;
+                                        }
+                                    }
+                                }
+
+                                assert oldSlot != null;
+
+                                OutputSlot nextSlot = succ.getOutputSlots().get(0);
+                                int pos = 0;
+                                if (succ.getProperties().get("con") != null) {
+                                    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"));
+                                } else {
+                                    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);
+                                    newConn.setColor(c.getColor());
+                                    newConn.setStyle(c.getStyle());
+                                }
+
+
+                                figuresToRemove.add(succ);
+
+                                if (oldSlot.getConnections().size() == 0) {
+                                    f.removeSlot(oldSlot);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+
+            diagram.removeAllFigures(figuresToRemove);
+        }
+    }
+
+    public void addRule(CombineRule combineRule) {
+        rules.add(combineRule);
+    }
+
+    public static class CombineRule {
+
+        private PropertyMatcher first;
+        private PropertyMatcher second;
+        private boolean reversed;
+
+        public CombineRule(PropertyMatcher first, PropertyMatcher second) {
+            this(first, second, false);
+
+        }
+
+        public CombineRule(PropertyMatcher first, PropertyMatcher second, boolean reversed) {
+            this.first = first;
+            this.second = second;
+            this.reversed = reversed;
+        }
+
+        public boolean isReversed() {
+            return reversed;
+        }
+
+        public PropertyMatcher getFirstMatcher() {
+            return first;
+        }
+
+        public PropertyMatcher getSecondMatcher() {
+            return second;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ConnectionFilter.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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 java.awt.Color;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ConnectionFilter extends AbstractFilter {
+
+    private List<ConnectionStyleRule> connectionStyleRules;
+    private String name;
+
+    public ConnectionFilter(String name) {
+        this.name = name;
+        connectionStyleRules = new ArrayList<ConnectionStyleRule>();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void apply(Diagram diagram) {
+
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(diagram.getFigures());
+        for (ConnectionStyleRule rule : connectionStyleRules) {
+            List<Figure> figures = null;
+            if (rule.getSelector() != null) {
+                figures = rule.getSelector().selected(diagram);
+            } else {
+                figures = diagram.getFigures();
+            }
+
+            for (Figure f : figures) {
+                for (OutputSlot os : f.getOutputSlots()) {
+                    for (Connection c : os.getConnections()) {
+                        if (figures.contains(c.getInputSlot().getFigure())) {
+                            c.setStyle(rule.getLineStyle());
+                            c.setColor(rule.getLineColor());
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    public void addRule(ConnectionStyleRule r) {
+        connectionStyleRules.add(r);
+    }
+
+    public static class ConnectionStyleRule {
+
+        private Color lineColor;
+        private Connection.ConnectionStyle lineStyle;
+        private Selector selector;
+
+        public ConnectionStyleRule(Selector selector, Color lineColor, Connection.ConnectionStyle lineStyle) {
+            this.selector = selector;
+            this.lineColor = lineColor;
+            this.lineStyle = lineStyle;
+        }
+
+        public Selector getSelector() {
+            return selector;
+        }
+
+        public Color getLineColor() {
+            return lineColor;
+        }
+
+        public Connection.ConnectionStyle getLineStyle() {
+            return lineStyle;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,159 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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.data.Property;
+import java.io.BufferedReader;
+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 org.openide.cookies.OpenCookie;
+import org.openide.filesystems.Repository;
+import org.openide.filesystems.FileSystem;
+import org.openide.filesystems.FileObject;
+import org.openide.util.Exceptions;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class CustomFilter extends AbstractFilter {
+
+    public static final String JAVASCRIPT_HELPER_ID = "JavaScriptHelper";
+    private static ScriptEngineAbstraction engine;
+    private String code;
+    private String name;
+
+    public CustomFilter(String name, String code) {
+        this.name = name;
+        this.code = code;
+        getProperties().add(new Property("name", name));
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setName(String s) {
+        name = s;
+        fireChangedEvent();
+    }
+
+    public void setCode(String s) {
+        code = s;
+        fireChangedEvent();
+    }
+
+    @Override
+    public OpenCookie getEditor() {
+        return new OpenCookie() {
+
+            public void open() {
+                openInEditor();
+            }
+        };
+    }
+
+    public boolean openInEditor() {
+        EditFilterDialog dialog = new EditFilterDialog(CustomFilter.this);
+        dialog.setVisible(true);
+        return dialog.wasAccepted();
+    }
+
+    @Override
+    public String toString() {
+        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);");
+        try {
+            FileSystem fs = Repository.getDefault().getDefaultFileSystem();
+            FileObject fo = fs.getRoot().getFileObject(JAVASCRIPT_HELPER_ID);
+            is = fo.getInputStream();
+            BufferedReader r = new BufferedReader(new InputStreamReader(is));
+            String s;
+            while ((s = r.readLine()) != null) {
+                sb.append(s);
+                sb.append("\n");
+            }
+
+        } catch (IOException ex) {
+            Logger.getLogger("global").log(Level.SEVERE, null, ex);
+        } finally {
+            try {
+                is.close();
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+        }
+        return sb.toString();
+    }
+
+    public void apply(Diagram d) {
+        getEngine().execute(d, code);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/EditFilterDialog.form	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,133 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.4" maxVersion="1.4" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
+  <Properties>
+    <Property name="defaultCloseOperation" type="int" value="2"/>
+    <Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+      <ResourceString bundle="at/ssw/graphanalyzer/filter/Bundle.properties" key="title" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+    </Property>
+    <Property name="resizable" type="boolean" value="false"/>
+  </Properties>
+  <SyntheticProperties>
+    <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+  </SyntheticProperties>
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="1"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="2"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Group type="102" alignment="1" attributes="0">
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="sourceLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                          <Component id="nameLabel" alignment="0" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                      <EmptySpace min="-2" pref="25" max="-2" attributes="0"/>
+                      <Group type="103" groupAlignment="0" attributes="0">
+                          <Component id="jScrollPane1" pref="695" max="32767" attributes="1"/>
+                          <Component id="nameTextField" alignment="0" pref="695" max="32767" attributes="1"/>
+                      </Group>
+                  </Group>
+                  <Group type="102" alignment="1" attributes="0">
+                      <Component id="okButton" min="-2" pref="76" max="-2" attributes="0"/>
+                      <EmptySpace max="-2" attributes="0"/>
+                      <Component id="cancelButton" min="-2" max="-2" attributes="0"/>
+                  </Group>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="nameLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="nameTextField" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace type="unrelated" max="-2" attributes="0"/>
+              <Group type="103" groupAlignment="0" attributes="0">
+                  <Component id="sourceLabel" min="-2" max="-2" attributes="0"/>
+                  <Component id="jScrollPane1" min="-2" pref="337" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace pref="16" max="32767" attributes="0"/>
+              <Group type="103" groupAlignment="3" attributes="0">
+                  <Component id="cancelButton" alignment="3" min="-2" max="-2" attributes="0"/>
+                  <Component id="okButton" alignment="3" min="-2" max="-2" attributes="0"/>
+              </Group>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+      <AuxValues>
+        <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+      </AuxValues>
+
+      <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+      <SubComponents>
+        <Component class="javax.swing.JTextArea" name="sourceTextArea">
+          <Properties>
+            <Property name="columns" type="int" value="20"/>
+            <Property name="rows" type="int" value="5"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+    <Component class="javax.swing.JTextField" name="nameTextField">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="at/ssw/graphanalyzer/coordinator/Bundle.properties" key="nameTextField.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="nameLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="at/ssw/graphanalyzer/filter/Bundle.properties" key="jLabel1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JLabel" name="sourceLabel">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="at/ssw/graphanalyzer/filter/Bundle.properties" key="jLabel2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+    </Component>
+    <Component class="javax.swing.JButton" name="okButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="at/ssw/graphanalyzer/filter/Bundle.properties" key="jButton1.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonClicked,okButtonClicked"/>
+      </Events>
+    </Component>
+    <Component class="javax.swing.JButton" name="cancelButton">
+      <Properties>
+        <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+          <ResourceString bundle="at/ssw/graphanalyzer/filter/Bundle.properties" key="jButton2.text" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
+        </Property>
+      </Properties>
+      <Events>
+        <EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="cancelButtonClicked"/>
+      </Events>
+    </Component>
+  </SubComponents>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/EditFilterDialog.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,161 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.hotspot.igv.filter;
+
+import org.openide.windows.WindowManager;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class EditFilterDialog extends javax.swing.JDialog {
+
+    private CustomFilter customFilter;
+    private boolean accepted;
+
+    /** Creates new form EditFilterDialog */
+    public EditFilterDialog(CustomFilter customFilter) {
+        super(WindowManager.getDefault().getMainWindow(), true);
+        this.customFilter = customFilter;
+        initComponents();
+
+        sourceTextArea.setText(customFilter.getCode());
+        nameTextField.setText(customFilter.getName());
+    }
+
+    public boolean wasAccepted() {
+        return accepted;
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jScrollPane1 = new javax.swing.JScrollPane();
+        sourceTextArea = new javax.swing.JTextArea();
+        nameTextField = new javax.swing.JTextField();
+        nameLabel = new javax.swing.JLabel();
+        sourceLabel = new javax.swing.JLabel();
+        okButton = new javax.swing.JButton();
+        cancelButton = new javax.swing.JButton();
+
+        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+        setTitle(org.openide.util.NbBundle.getMessage(EditFilterDialog.class, "title")); // NOI18N
+        setResizable(false);
+
+        sourceTextArea.setColumns(20);
+        sourceTextArea.setRows(5);
+        jScrollPane1.setViewportView(sourceTextArea);
+
+        nameTextField.setText("null");
+
+        nameLabel.setText(org.openide.util.NbBundle.getMessage(EditFilterDialog.class, "jLabel1.text")); // NOI18N
+
+        sourceLabel.setText(org.openide.util.NbBundle.getMessage(EditFilterDialog.class, "jLabel2.text")); // NOI18N
+
+        okButton.setText(org.openide.util.NbBundle.getMessage(EditFilterDialog.class, "jButton1.text")); // NOI18N
+        okButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                cancelButtonClicked(evt);
+                okButtonClicked(evt);
+            }
+        });
+
+        cancelButton.setText(org.openide.util.NbBundle.getMessage(EditFilterDialog.class, "jButton2.text")); // NOI18N
+        cancelButton.addActionListener(new java.awt.event.ActionListener() {
+            public void actionPerformed(java.awt.event.ActionEvent evt) {
+                cancelButtonClicked(evt);
+            }
+        });
+
+        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
+        getContentPane().setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(layout.createSequentialGroup()
+                .addContainerGap()
+                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
+                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                            .add(sourceLabel)
+                            .add(nameLabel))
+                        .add(25, 25, 25)
+                        .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                            .add(jScrollPane1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 695, Short.MAX_VALUE)
+                            .add(nameTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 695, Short.MAX_VALUE)))
+                    .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup()
+                        .add(okButton, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 76, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                        .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
+                        .add(cancelButton)))
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(layout.createSequentialGroup()
+                .addContainerGap()
+                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
+                    .add(nameLabel)
+                    .add(nameTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
+                .addPreferredGap(org.jdesktop.layout.LayoutStyle.UNRELATED)
+                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                    .add(sourceLabel)
+                    .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 337, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
+                .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, 16, Short.MAX_VALUE)
+                .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
+                    .add(cancelButton)
+                    .add(okButton))
+                .addContainerGap())
+        );
+
+        pack();
+    }// </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);
+}//GEN-LAST:event_okButtonClicked
+
+private void cancelButtonClicked(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_cancelButtonClicked
+        setVisible(false);
+}//GEN-LAST:event_cancelButtonClicked
+
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JButton cancelButton;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JLabel nameLabel;
+    private javax.swing.JTextField nameTextField;
+    private javax.swing.JButton okButton;
+    private javax.swing.JLabel sourceLabel;
+    private javax.swing.JTextArea sourceTextArea;
+    // End of variables declaration//GEN-END:variables
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/Filter.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filter;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import com.sun.hotspot.igv.data.ChangedEventProvider;
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.graph.Diagram;
+import org.openide.cookies.OpenCookie;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface Filter extends Properties.Provider, ChangedEventProvider<Filter> {
+
+    public String getName();
+
+    public void apply(Diagram d);
+
+    OpenCookie getEditor();
+
+    ChangedEvent<Filter> getChangedEvent();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChain.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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.data.ChangedEvent;
+import com.sun.hotspot.igv.data.ChangedEventProvider;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class FilterChain implements ChangedEventProvider<FilterChain> {
+
+    private List<Filter> filters;
+    private transient ChangedEvent<FilterChain> changedEvent;
+    private boolean fireEvents;
+
+    public FilterChain() {
+        filters = new ArrayList<Filter>();
+        changedEvent = new ChangedEvent<FilterChain>(this);
+        this.fireEvents = true;
+    }
+
+    public FilterChain(FilterChain f) {
+        this.filters = new ArrayList<Filter>(f.filters);
+        changedEvent = new ChangedEvent<FilterChain>(this);
+        this.fireEvents = true;
+    }
+
+    public ChangedEvent<FilterChain> getChangedEvent() {
+        return changedEvent;
+    }
+
+    public Filter getFilterAt(int index) {
+        assert index >= 0 && index < filters.size();
+        return filters.get(index);
+    }
+
+    public void apply(Diagram d) {
+        for (Filter f : filters) {
+            f.apply(d);
+        }
+    }
+
+    public void apply(Diagram d, FilterChain sequence) {
+        List<Filter> applied = new ArrayList<Filter>();
+        for (Filter f : sequence.getFilters()) {
+            if (filters.contains(f)) {
+                f.apply(d);
+                applied.add(f);
+            }
+        }
+
+
+        for (Filter f : filters) {
+            if (!applied.contains(f)) {
+                f.apply(d);
+            }
+        }
+    }
+
+    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();
+        }
+    }
+
+    public boolean containsFilter(Filter filter) {
+        return filters.contains(filter);
+    }
+
+    public void removeFilter(Filter filter) {
+        assert filters.contains(filter);
+        filters.remove(filter);
+        if (fireEvents) {
+            changedEvent.fire();
+        }
+    }
+
+    public void moveFilterUp(Filter filter) {
+        assert filters.contains(filter);
+        int index = filters.indexOf(filter);
+        if (index != 0) {
+            filters.remove(index);
+            filters.add(index - 1, filter);
+        }
+        if (fireEvents) {
+            changedEvent.fire();
+        }
+    }
+
+    public void moveFilterDown(Filter filter) {
+        assert filters.contains(filter);
+        int index = filters.indexOf(filter);
+        if (index != filters.size() - 1) {
+            filters.remove(index);
+            filters.add(index + 1, filter);
+        }
+        if (fireEvents) {
+            changedEvent.fire();
+        }
+    }
+
+    public List<Filter> getFilters() {
+        return Collections.unmodifiableList(filters);
+    }
+
+    public void clear() {
+        filters.clear();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChainProvider.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filter;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface FilterChainProvider {
+
+    public FilterChain getFilterChain();
+
+    public FilterChain getSequence();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterSetting.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filter;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class FilterSetting {
+
+    private Set<Filter> filters;
+    private String name;
+
+    public FilterSetting() {
+        this(null);
+    }
+
+    public FilterSetting(String name) {
+        this.name = name;
+        filters = new HashSet<Filter>();
+    }
+
+    public Set<Filter> getFilters() {
+        return Collections.unmodifiableSet(filters);
+    }
+
+    public void addFilter(Filter f) {
+        assert !filters.contains(f);
+        filters.add(f);
+    }
+
+    public void removeFilter(Filter f) {
+        assert filters.contains(f);
+        filters.remove(f);
+    }
+
+    public boolean containsFilter(Filter f) {
+        return filters.contains(f);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    public int getFilterCount() {
+        return filters.size();
+    }
+
+    @Override
+    public String toString() {
+        return getName();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/JavaSE6ScriptEngine.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/NullScriptEngine.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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) {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveFilter.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 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;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class RemoveFilter extends AbstractFilter {
+
+    private List<RemoveRule> rules;
+    private String name;
+
+    public RemoveFilter(String name) {
+        this.name = name;
+        rules = new ArrayList<RemoveRule>();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void apply(Diagram diagram) {
+
+        for (RemoveRule r : rules) {
+
+            List<Figure> list = r.getSelector().selected(diagram);
+            Set<Figure> figuresToRemove = new HashSet<Figure>();
+
+            List<Figure> protectedFigures = null;
+            if (r.getRemoveAllWithoutPredecessor()) {
+                protectedFigures = diagram.getRootFigures();
+            }
+
+            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);
+        }
+    }
+
+    public void addRule(RemoveRule rule) {
+        rules.add(rule);
+    }
+
+    public static class RemoveRule {
+
+        private Selector selector;
+        private boolean removeAllWithoutPredecessor;
+        private boolean removeOnlyInputs;
+
+        public RemoveRule(Selector selector, boolean b) {
+            this(selector, b, false);
+        }
+
+        public RemoveRule(Selector selector, boolean removeAllWithoutPredecessor, boolean removeOnlyInputs) {
+            this.selector = selector;
+            this.removeOnlyInputs = removeOnlyInputs;
+            this.removeAllWithoutPredecessor = removeAllWithoutPredecessor;
+        }
+
+        public Selector getSelector() {
+            return selector;
+        }
+
+        public boolean getRemoveOnlyInputs() {
+            return removeOnlyInputs;
+        }
+
+        public boolean getRemoveAllWithoutPredecessor() {
+            return removeAllWithoutPredecessor;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveInputsFilter.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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 java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class RemoveInputsFilter extends AbstractFilter {
+
+    private List<RemoveInputsRule> rules;
+    private String name;
+
+    public RemoveInputsFilter(String name) {
+        this.name = name;
+        rules = new ArrayList<RemoveInputsRule>();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void apply(Diagram diagram) {
+
+        for (RemoveInputsRule r : rules) {
+
+            List<Figure> list = r.getSelector().selected(diagram);
+            for (Figure f : list) {
+                int z = 0;
+                List<InputSlot> last = new ArrayList<InputSlot>();
+                for (InputSlot is : f.getInputSlots()) {
+                    if (z >= r.getStartingIndex() && z <= r.getEndIndex() && is.getConnections().size() > 0) {
+                        StringBuilder sb = new StringBuilder();
+                        List<Connection> conns = is.getConnections();
+                        for (int i = 0; i < conns.size(); i++) {
+                            Connection c = conns.get(i);
+                            OutputSlot os = c.getOutputSlot();
+                            Figure pred = os.getFigure();
+                            if (i != 0) {
+                                sb.append("<BR>");
+                            }
+                            sb.append(pred.getLines()[0]);
+                        }
+                        is.removeAllConnections();
+                        is.setShortName("X");
+                        is.setName(sb.toString());
+                        last.add(is);
+                    } else {
+                        last.clear();
+                    }
+                    z++;
+                }
+
+                if (last.size() > 3) {
+                    InputSlot first = last.get(0);
+                    first.setShortName("XX");
+
+                    StringBuilder sb = new StringBuilder();
+                    for (int i = 0; i < last.size(); i++) {
+                        InputSlot is2 = last.get(i);
+                        if (i != 0) {
+                            sb.append("<BR>");
+                        }
+                        sb.append(is2.getName());
+                    }
+
+                    first.setName(sb.toString());
+
+                    for (int i = 1; i < last.size(); i++) {
+                        f.removeSlot(last.get(i));
+                    }
+                }
+            }
+        }
+    }
+
+    public void addRule(RemoveInputsRule rule) {
+        rules.add(rule);
+    }
+
+    public static class RemoveInputsRule {
+
+        private Selector selector;
+        private int startingIndex;
+        private int endIndex;
+
+        public RemoveInputsRule(Selector selector) {
+            this(selector, 0);
+        }
+
+        public RemoveInputsRule(Selector selector, int startIndex) {
+            this(selector, startIndex, Integer.MAX_VALUE);
+        }
+
+        public RemoveInputsRule(Selector selector, int startIndex, int endIndex) {
+            this.startingIndex = startIndex;
+            this.endIndex = endIndex;
+            this.selector = selector;
+        }
+
+        public int getStartingIndex() {
+            return startingIndex;
+        }
+
+        public int getEndIndex() {
+            return endIndex;
+        }
+
+        public Selector getSelector() {
+            return selector;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveSelfLoopsFilter.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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 java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class RemoveSelfLoopsFilter extends AbstractFilter {
+
+    private String name;
+
+    /** Creates a new instance of RemoveSelfLoops */
+    public RemoveSelfLoopsFilter(String name) {
+        this.name = name;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void apply(Diagram d) {
+
+        for (Figure f : d.getFigures()) {
+
+            for (InputSlot is : f.getInputSlots()) {
+
+                List<Connection> toRemove = new ArrayList<Connection>();
+                for (Connection c : is.getConnections()) {
+
+                    if (c.getOutputSlot().getFigure() == f) {
+                        toRemove.add(c);
+                    }
+                }
+
+                for (Connection c : toRemove) {
+
+                    c.remove();
+
+                    OutputSlot os = c.getOutputSlot();
+                    if (os.getConnections().size() == 0) {
+                        f.removeSlot(os);
+                    }
+
+                    c.getInputSlot().setShortName("O");
+                    c.getInputSlot().setName("Self Loop");
+                }
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ScriptEngineAbstraction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,38 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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 java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class SplitFilter extends AbstractFilter {
+
+    private String name;
+    private Selector selector;
+
+    public SplitFilter(String name, Selector selector) {
+        this.name = name;
+        this.selector = selector;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void apply(Diagram d) {
+        List<Figure> list = selector.selected(d);
+
+        for (Figure f : list) {
+            for (OutputSlot os : f.getOutputSlots()) {
+                for (Connection c : os.getConnections()) {
+                    InputSlot is = c.getInputSlot();
+                    is.setName(f.getProperties().getProperty("dump_spec"));
+                    String s = f.getProperties().getProperty("short_name");
+                    if (s != null) {
+                        is.setShortName(s);
+                    }
+                }
+            }
+
+            d.removeFigure(f);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/helper.js	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any 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);
+}
+
+function remove(property, regexp) {
+    var f = new RemoveFilter("");
+    f.addRule(new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), false, false));
+    f.apply(graph);
+}
+
+function split(property, regexp) {
+    var f = new SplitFilter("", new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)));
+    f.apply(graph);
+}
+
+function removeInputs(property, regexp, from, to) {
+    var f = new RemoveInputsFilter("");
+    if(from == undefined && to == undefined) {
+        f.addRule(new RemoveInputsFilter.RemoveInputsRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp))));
+    } else if(to == undefined) {
+        f.addRule(new RemoveInputsFilter.RemoveInputsRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), from));
+    } else {
+        f.addRule(new RemoveInputsFilter.RemoveInputsRule(new MatcherSelector(new Properties.RegexpPropertyMatcher(property, regexp)), from, to));
+    }
+    f.apply(graph);
+}
+
+var black = Color.black;
+var blue = Color.blue;
+var cyan = Color.cyan;
+var darkGray = Color.darkGray;
+var gray = Color.gray;
+var green = Color.green;
+var lightGray = Color.lightGray;
+var magenta = Color.magenta;
+var orange = Color.orange;
+var pink = Color.pink
+var red = Color.red;
+var yellow = Color.yellow;
+var white = Color.white;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/layer.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,5 @@
+<?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>
+        <file name="JavaScriptHelper" url="helper.js"/>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/build.xml	Wed Jul 05 16:38:46 2017 +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.filterwindow" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.filterwindow.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.filterwindow
+OpenIDE-Module-Layer: com/sun/hotspot/igv/filterwindow/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/filterwindow/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.filterwindow-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,109 @@
+<?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.filterwindow</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.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.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.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.12.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.3.1</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.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.2.1.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.10.1.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.18.1</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/FilterWindow/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/META-INF/services/com.sun.hotspot.igv.filter.FilterChainProvider	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+com.sun.hotspot.igv.filterwindow.FilterChainProviderImplementation
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,3 @@
+OpenIDE-Module-Name=FilterWindow
+CTL_FilterTopComponent=Filter Window
+HINT_FilterTopComponent=This is a Filter window
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckListView.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filterwindow;
+
+import javax.swing.JList;
+import org.openide.explorer.view.ListView;
+import org.openide.explorer.view.NodeListModel;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class CheckListView extends ListView {
+
+    @Override
+    public void showSelection(int[] indices) {
+        super.showSelection(indices);
+    }
+
+    @Override
+    protected NodeListModel createModel() {
+        return new CheckNodeListModel();
+    }
+
+    @Override
+    protected JList createList() {
+        JList tmpList = super.createList();
+        tmpList.setCellRenderer(new CheckRenderer(tmpList));
+        return tmpList;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNode.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filterwindow;
+
+import com.sun.hotspot.igv.data.ChangedEvent;
+import org.openide.nodes.AbstractNode;
+import org.openide.nodes.Children;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class CheckNode extends AbstractNode {
+
+    private ChangedEvent<CheckNode> selectionChangedEvent;
+    public boolean selected;
+    public boolean enabled;
+
+    public CheckNode(Children c, Lookup lookup) {
+        super(c, lookup);
+        selectionChangedEvent = new ChangedEvent<CheckNode>(this);
+        selected = false;
+        enabled = true;
+    }
+
+    public ChangedEvent<CheckNode> getSelectionChangedEvent() {
+        return selectionChangedEvent;
+    }
+
+    public boolean isSelected() {
+        return selected;
+    }
+
+    public void setSelected(boolean b) {
+        if (b != selected) {
+            selected = b;
+            selectionChangedEvent.fire();
+        }
+    }
+
+    public void setEnabled(boolean b) {
+        enabled = b;
+    }
+
+    public boolean isEnabled() {
+        return enabled;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNodeListModel.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filterwindow;
+
+import org.openide.explorer.view.NodeListModel;
+import org.openide.nodes.Node;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+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];
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckRenderer.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import javax.swing.JCheckBox;
+import javax.swing.JList;
+import javax.swing.ListCellRenderer;
+
+/**
+ * @author Thomas Wuerthinger
+ */
+public class CheckRenderer extends JCheckBox implements ListCellRenderer {
+
+    private JList list;
+    private Color startBackground;
+
+    public CheckRenderer(final JList list) {
+        this.list = list;
+        list.addMouseListener(
+                new MouseAdapter() {
+
+                    @Override
+                    public void mouseClicked(MouseEvent e) {
+                        int index = list.locationToIndex(e.getPoint());
+                        Point p2 = list.indexToLocation(index);
+                        Rectangle r = new Rectangle(p2.x, p2.y, getPreferredSize().height, getPreferredSize().height);
+                        if (r.contains(e.getPoint())) {
+                            CheckNode node = ((CheckNodeListModel) list.getModel()).getCheckNodeAt(index);
+                            node.setSelected(!node.isSelected());
+                            list.repaint();
+                            e.consume();
+                        }
+                    }
+                });
+
+        this.setPreferredSize(new Dimension(getPreferredSize().width, getPreferredSize().height - 5));
+        startBackground = this.getBackground();
+    }
+
+    public Component getListCellRendererComponent(final JList list, Object value, final int index, boolean isSelected, boolean cellHasFocus) {
+        setText(value.toString());
+        CheckNode node = ((CheckNodeListModel) list.getModel()).getCheckNodeAt(index);
+        this.setSelected(node.isSelected());
+        this.setEnabled(list.isEnabled());
+
+        if (isSelected && list.hasFocus()) {
+            this.setBackground(list.getSelectionBackground());
+            this.setForeground(list.getSelectionForeground());
+        } else if (isSelected) {
+            assert !list.hasFocus();
+            this.setBackground(startBackground);
+            this.setForeground(list.getForeground());
+
+        } else {
+            this.setBackground(list.getBackground());
+            this.setForeground(list.getForeground());
+        }
+        return this;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterChainProviderImplementation.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filterwindow;
+
+import com.sun.hotspot.igv.filter.FilterChain;
+import com.sun.hotspot.igv.filter.FilterChainProvider;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class FilterChainProviderImplementation implements FilterChainProvider {
+
+    public FilterChain getFilterChain() {
+        return FilterTopComponent.findInstance().getFilterChain();
+    }
+
+    public FilterChain getSequence() {
+        return FilterTopComponent.findInstance().getSequence();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterNode.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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.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;
+import org.openide.nodes.Children;
+import org.openide.nodes.Sheet;
+import org.openide.util.Lookup;
+import org.openide.util.LookupEvent;
+import org.openide.util.LookupListener;
+import org.openide.util.Utilities;
+import org.openide.util.lookup.AbstractLookup;
+import org.openide.util.lookup.InstanceContent;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class FilterNode extends CheckNode implements LookupListener, ChangedListener<FilterTopComponent> {
+
+    private Filter filter;
+    private Lookup.Result result;
+
+    public FilterNode(Filter filter) {
+        this(filter, new InstanceContent());
+    }
+
+    private FilterNode(Filter filter, InstanceContent content) {
+        super(Children.LEAF, new AbstractLookup(content));
+        content.add(filter);
+
+        content.add(filter.getEditor());
+        this.filter = filter;
+        filter.getChangedEvent().addListener(new ChangedListener<Filter>() {
+
+            public void changed(Filter source) {
+                update();
+            }
+        });
+
+        update();
+
+        Lookup.Template<FilterChain> tpl = new Lookup.Template<FilterChain>(FilterChain.class);
+        result = Utilities.actionsGlobalContext().lookup(tpl);
+        result.addLookupListener(this);
+
+        FilterTopComponent.findInstance().getFilterSettingsChangedEvent().addListener(this);
+        resultChanged(null);
+    }
+
+    private void update() {
+        this.setDisplayName(filter.getName());
+    }
+
+    public Filter getFilter() {
+        return filter;
+    }
+
+    @Override
+    protected Sheet createSheet() {
+        Sheet s = super.createSheet();
+        PropertiesSheet.initializeSheet(getFilter().getProperties(), s);
+        return s;
+    }
+
+    @Override
+    public Action[] getActions(boolean b) {
+        return new Action[]{(Action) OpenAction.findObject(OpenAction.class, true), (Action) MoveFilterUpAction.findObject(MoveFilterUpAction.class, true), (Action) MoveFilterDownAction.findObject(MoveFilterDownAction.class, true), (Action) RemoveFilterAction.findObject(RemoveFilterAction.class, true)};
+    }
+
+    @Override
+    public Action getPreferredAction() {
+        return OpenAction.get(OpenAction.class).createContextAwareInstance(Utilities.actionsGlobalContext());
+    }
+
+    public void resultChanged(LookupEvent lookupEvent) {
+        changed(FilterTopComponent.findInstance());
+    }
+
+    public void changed(FilterTopComponent source) {
+        setSelected(source.getFilterChain().containsFilter(filter));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.form	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-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_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"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+    <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
+  </AuxValues>
+
+  <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,689 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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.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 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 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.ToolbarPool;
+import org.openide.explorer.ExplorerManager;
+import org.openide.explorer.ExplorerUtils;
+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.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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class FilterTopComponent extends TopComponent implements LookupListener, ExplorerManager.Provider {
+
+    private static FilterTopComponent instance;
+    public static final String FOLDER_ID = "Filters";
+    public static final String AFTER_ID = "after";
+    public static final String ENABLED_ID = "enabled";
+    public static final String PREFERRED_ID = "FilterTopComponent";
+    private CheckListView view;
+    private ExplorerManager manager;
+    private FilterChain filterChain;
+    private FilterChain sequence;
+    private Lookup.Result result;
+    private JComboBox comboBox;
+    private List<FilterSetting> filterSettings;
+    private FilterSetting customFilterSetting = new FilterSetting("-- Custom --");
+    private ChangedEvent<FilterTopComponent> filterSettingsChangedEvent;
+    private ActionListener comboBoxActionListener = new ActionListener() {
+
+        public void actionPerformed(ActionEvent e) {
+            comboBoxSelectionChanged();
+        }
+    };
+
+    public ChangedEvent<FilterTopComponent> getFilterSettingsChangedEvent() {
+        return filterSettingsChangedEvent;
+    }
+
+    public FilterChain getSequence() {
+        return sequence;
+    }
+
+    public void updateSelection() {
+        Node[] nodes = this.getExplorerManager().getSelectedNodes();
+        int[] arr = new int[nodes.length];
+        for (int i = 0; i < nodes.length; i++) {
+            int index = sequence.getFilters().indexOf(((FilterNode) nodes[i]).getFilter());
+            arr[i] = index;
+        }
+        view.showSelection(arr);
+    }
+
+    private void comboBoxSelectionChanged() {
+
+        Object o = comboBox.getSelectedItem();
+        if (o == null) {
+            return;
+        }
+        assert o instanceof FilterSetting;
+        FilterSetting s = (FilterSetting) o;
+
+        if (s != customFilterSetting) {
+            FilterChain chain = getFilterChain();
+            chain.beginAtomic();
+            List<Filter> toRemove = new ArrayList<Filter>();
+            for (Filter f : chain.getFilters()) {
+                if (!s.containsFilter(f)) {
+                    toRemove.add(f);
+                }
+            }
+            for (Filter f : toRemove) {
+                chain.removeFilter(f);
+            }
+
+            for (Filter f : s.getFilters()) {
+                if (!chain.containsFilter(f)) {
+                    chain.addFilter(f);
+                }
+            }
+
+            chain.endAtomic();
+            filterSettingsChangedEvent.fire();
+        } else {
+            this.updateComboBoxSelection();
+        }
+
+        SystemAction.get(RemoveFilterSettingsAction.class).setEnabled(comboBox.getSelectedItem() != this.customFilterSetting);
+        SystemAction.get(SaveFilterSettingsAction.class).setEnabled(comboBox.getSelectedItem() == this.customFilterSetting);
+    }
+
+    private void updateComboBox() {
+        comboBox.removeAllItems();
+        comboBox.addItem(customFilterSetting);
+        for (FilterSetting s : filterSettings) {
+            comboBox.addItem(s);
+        }
+
+        this.updateComboBoxSelection();
+    }
+
+    public void addFilterSetting() {
+        NotifyDescriptor.InputLine l = new NotifyDescriptor.InputLine("Enter a name:", "Filter");
+        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");
+                    if (DialogDisplayer.getDefault().notify(conf) == NotifyDescriptor.YES_OPTION) {
+                        toRemove = s;
+                        break;
+                    } else {
+                        return;
+                    }
+                }
+            }
+
+            if (toRemove != null) {
+                filterSettings.remove(toRemove);
+            }
+            FilterSetting setting = createFilterSetting(name);
+            filterSettings.add(setting);
+
+            // Sort alphabetically
+            Collections.sort(filterSettings, new Comparator<FilterSetting>() {
+
+                public int compare(FilterSetting o1, FilterSetting o2) {
+                    return o1.getName().compareTo(o2.getName());
+                }
+            });
+
+            updateComboBox();
+        }
+    }
+
+    public boolean canRemoveFilterSetting() {
+        return comboBox.getSelectedItem() != customFilterSetting;
+    }
+
+    public void removeFilterSetting() {
+        if (canRemoveFilterSetting()) {
+            Object o = comboBox.getSelectedItem();
+            assert o instanceof FilterSetting;
+            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");
+            if (DialogDisplayer.getDefault().notify(l) == NotifyDescriptor.YES_OPTION) {
+                filterSettings.remove(f);
+                updateComboBox();
+            }
+        }
+    }
+
+    private FilterSetting createFilterSetting(String name) {
+        FilterSetting s = new FilterSetting(name);
+        FilterChain chain = this.getFilterChain();
+        for (Filter f : chain.getFilters()) {
+            s.addFilter(f);
+        }
+        return s;
+    }
+
+    private void updateComboBoxSelection() {
+        List<Filter> filters = this.getFilterChain().getFilters();
+        boolean found = false;
+        for (FilterSetting s : filterSettings) {
+            if (s.getFilterCount() == filters.size()) {
+                boolean ok = true;
+                for (Filter f : filters) {
+                    if (!s.containsFilter(f)) {
+                        ok = false;
+                    }
+                }
+
+                if (ok) {
+                    if (comboBox.getSelectedItem() != s) {
+                        comboBox.setSelectedItem(s);
+                    }
+                    found = true;
+                    break;
+                }
+            }
+        }
+
+        if (!found && comboBox.getSelectedItem() != customFilterSetting) {
+            comboBox.setSelectedItem(customFilterSetting);
+        }
+    }
+
+    private class FilterChildren extends Children.Keys implements ChangedListener<CheckNode> {
+
+        //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)};
+            }
+
+            assert object instanceof Filter;
+            Filter filter = (Filter) object;
+            com.sun.hotspot.igv.filterwindow.FilterNode node = new com.sun.hotspot.igv.filterwindow.FilterNode(filter);
+            node.getSelectionChangedEvent().addListener(this);
+            nodeHash.put(object, node);
+            return new Node[]{node};
+        }
+
+        public FilterChildren() {
+            sequence.getChangedEvent().addListener(new ChangedListener<FilterChain>() {
+
+                public void changed(FilterChain source) {
+                    addNotify();
+                }
+            });
+
+            setBefore(false);
+        }
+
+        protected void addNotify() {
+            setKeys(sequence.getFilters());
+            updateSelection();
+        }
+
+        public void changed(CheckNode source) {
+            FilterNode node = (FilterNode) source;
+            Filter f = node.getFilter();
+            FilterChain chain = getFilterChain();
+            if (node.isSelected()) {
+                if (!chain.containsFilter(f)) {
+                    chain.addFilter(f);
+                }
+            } else {
+                if (chain.containsFilter(f)) {
+                    chain.removeFilter(f);
+                }
+            }
+            view.revalidate();
+            view.repaint();
+            updateComboBoxSelection();
+        }
+    }
+
+    public FilterChain getFilterChain() {
+        return filterChain;/*
+    EditorTopComponent tc = EditorTopComponent.getActive();
+    if (tc == null) {
+    return filterChain;
+    }
+    return tc.getFilterChain();*/
+    }
+
+    private FilterTopComponent() {
+        filterSettingsChangedEvent = new ChangedEvent<FilterTopComponent>(this);
+        initComponents();
+        setName(NbBundle.getMessage(FilterTopComponent.class, "CTL_FilterTopComponent"));
+        setToolTipText(NbBundle.getMessage(FilterTopComponent.class, "HINT_FilterTopComponent"));
+        //        setIcon(Utilities.loadImage(ICON_PATH, true));
+
+        sequence = new FilterChain();
+        filterChain = new FilterChain();
+        initFilters();
+        manager = new ExplorerManager();
+        manager.setRootContext(new AbstractNode(new FilterChildren()));
+        associateLookup(ExplorerUtils.createLookup(manager, getActionMap()));
+        view = new CheckListView();
+
+        ToolbarPool.getDefault().setPreferredIconSize(16);
+        Toolbar toolBar = new Toolbar();
+        Border b = (Border) UIManager.get("Nb.Editor.Toolbar.border"); //NOI18N
+        toolBar.setBorder(b);
+        comboBox = new JComboBox();
+        toolBar.add(comboBox);
+        this.add(toolBar, BorderLayout.NORTH);
+        toolBar.add(SaveFilterSettingsAction.get(SaveFilterSettingsAction.class));
+        toolBar.add(RemoveFilterSettingsAction.get(RemoveFilterSettingsAction.class));
+        toolBar.addSeparator();
+        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>();
+        updateComboBox();
+
+        comboBox.addActionListener(comboBoxActionListener);
+        setChain(filterChain);
+    }
+
+    public void newFilter() {
+        CustomFilter cf = new CustomFilter("My custom filter", "");
+        if (cf.openInEditor()) {
+            sequence.addFilter(cf);
+            FileObject fo = getFileObject(cf);
+            FilterChangedListener listener = new FilterChangedListener(fo, cf);
+            listener.changed(cf);
+            cf.getChangedEvent().addListener(listener);
+        }
+    }
+
+    public void removeFilter(Filter f) {
+        com.sun.hotspot.igv.filter.CustomFilter cf = (com.sun.hotspot.igv.filter.CustomFilter) f;
+
+        sequence.removeFilter(cf);
+        try {
+            getFileObject(cf).delete();
+        } catch (IOException ex) {
+            Exceptions.printStackTrace(ex);
+        }
+
+    }
+
+    private static class FilterChangedListener implements ChangedListener<Filter> {
+
+        private FileObject fileObject;
+        private CustomFilter filter;
+
+        public FilterChangedListener(FileObject fo, CustomFilter cf) {
+            fileObject = fo;
+            filter = cf;
+        }
+
+        public void changed(Filter source) {
+            try {
+                if (!fileObject.getName().equals(filter.getName())) {
+                    FileLock lock = fileObject.lock();
+                    fileObject.move(lock, fileObject.getParent(), filter.getName(), "");
+                    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();
+                lock.releaseLock();
+
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+        }
+    }
+
+    public void initFilters() {
+
+        FileSystem fs = Repository.getDefault().getDefaultFileSystem();
+        FileObject folder = fs.getRoot().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>();
+
+        for (final FileObject fo : children) {
+            InputStream is = null;
+
+            String code = "";
+            FileLock lock = null;
+            try {
+                lock = fo.lock();
+                is = fo.getInputStream();
+                BufferedReader r = new BufferedReader(new InputStreamReader(is));
+                String s;
+                StringBuffer sb = new StringBuffer();
+                while ((s = r.readLine()) != null) {
+                    sb.append(s);
+                    sb.append("\n");
+                }
+                code = sb.toString();
+
+            } catch (FileNotFoundException ex) {
+                Exceptions.printStackTrace(ex);
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            } finally {
+                try {
+                    is.close();
+                } catch (IOException ex) {
+                    Exceptions.printStackTrace(ex);
+                }
+                lock.releaseLock();
+            }
+
+            String displayName = fo.getName();
+
+
+            final CustomFilter cf = new CustomFilter(displayName, code);
+            map.put(displayName, cf);
+
+            String after = (String) fo.getAttribute(AFTER_ID);
+            afterMap.put(cf, after);
+
+            Boolean enabled = (Boolean) fo.getAttribute(ENABLED_ID);
+            if (enabled != null && (boolean) enabled) {
+                enabledSet.add(cf);
+            }
+
+            cf.getChangedEvent().addListener(new FilterChangedListener(fo, cf));
+
+            customFilters.add(cf);
+        }
+
+        for (int j = 0; j < customFilters.size(); j++) {
+            for (int i = 0; i < customFilters.size(); i++) {
+                List<CustomFilter> copiedList = new ArrayList<CustomFilter>(customFilters);
+                for (CustomFilter cf : copiedList) {
+
+                    String after = afterMap.get(cf);
+
+                    if (map.containsKey(after)) {
+                        CustomFilter afterCf = map.get(after);
+                        int index = customFilters.indexOf(afterCf);
+                        int currentIndex = customFilters.indexOf(cf);
+
+                        if (currentIndex < index) {
+                            customFilters.remove(currentIndex);
+                            customFilters.add(index, cf);
+                        }
+                    }
+                }
+            }
+        }
+
+        for (CustomFilter cf : customFilters) {
+            sequence.addFilter(cf);
+            if (enabledSet.contains(cf)) {
+                filterChain.addFilter(cf);
+            }
+        }
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        setLayout(new java.awt.BorderLayout());
+
+    }// </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.
+     * To obtain the singleton instance, use {@link findInstance}.
+     */
+    public static synchronized FilterTopComponent getDefault() {
+        if (instance == null) {
+            instance = new FilterTopComponent();
+        }
+        return instance;
+    }
+
+    /**
+     * Obtain the FilterTopComponent instance. Never call {@link #getDefault} directly!
+     */
+    public static synchronized FilterTopComponent findInstance() {
+        TopComponent win = WindowManager.getDefault().findTopComponent(PREFERRED_ID);
+        if (win == null) {
+            ErrorManager.getDefault().log(ErrorManager.WARNING, "Cannot find Filter component. It will not be located properly in the window system.");
+            return getDefault();
+        }
+        if (win instanceof FilterTopComponent) {
+            return (FilterTopComponent) win;
+        }
+        ErrorManager.getDefault().log(ErrorManager.WARNING, "There seem to be multiple components with the '" + PREFERRED_ID + "' ID. That is a potential source of errors and unexpected behavior.");
+        return getDefault();
+    }
+
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_ALWAYS;
+    }
+
+    @Override
+    protected String preferredID() {
+        return PREFERRED_ID;
+    }
+
+    @Override
+    public ExplorerManager getExplorerManager() {
+        return manager;
+    }
+
+    @Override
+    public void componentOpened() {
+        Lookup.Template<FilterChain> tpl = new Lookup.Template<FilterChain>(FilterChain.class);
+        result = Utilities.actionsGlobalContext().lookup(tpl);
+        result.addLookupListener(this);
+    }
+
+    @Override
+    public void componentClosed() {
+        result.removeLookupListener(this);
+        result = null;
+    }
+
+    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) {
+        updateComboBoxSelection();
+    }
+
+    private FileObject getFileObject(CustomFilter cf) {
+        FileObject fo = Repository.getDefault().getDefaultFileSystem().getRoot().getFileObject(FOLDER_ID + "/" + cf.getName());
+        if (fo == null) {
+            try {
+                fo = org.openide.filesystems.Repository.getDefault().getDefaultFileSystem().getRoot().getFileObject(FOLDER_ID).createData(cf.getName());
+            } catch (IOException ex) {
+                Exceptions.printStackTrace(ex);
+            }
+        }
+        return fo;
+    }
+
+    @Override
+    public void writeExternal(ObjectOutput out) throws IOException {
+        super.writeExternal(out);
+
+        out.writeInt(filterSettings.size());
+        for (FilterSetting f : filterSettings) {
+            out.writeUTF(f.getName());
+
+            out.writeInt(f.getFilterCount());
+            for (Filter filter : f.getFilters()) {
+                CustomFilter cf = (CustomFilter) filter;
+                out.writeUTF(cf.getName());
+            }
+        }
+
+        CustomFilter prev = null;
+        for (Filter f : this.sequence.getFilters()) {
+            CustomFilter cf = (CustomFilter) f;
+            FileObject fo = getFileObject(cf);
+            if (getFilterChain().containsFilter(cf)) {
+                fo.setAttribute(ENABLED_ID, true);
+            } else {
+                fo.setAttribute(ENABLED_ID, false);
+            }
+
+            if (prev == null) {
+                fo.setAttribute(AFTER_ID, null);
+            } else {
+                fo.setAttribute(AFTER_ID, prev.getName());
+            }
+
+            prev = cf;
+        }
+    }
+
+    public CustomFilter findFilter(String name) {
+        for (Filter f : sequence.getFilters()) {
+
+            CustomFilter cf = (CustomFilter) f;
+            if (cf.getName().equals(name)) {
+                return cf;
+            }
+        }
+
+        return null;
+    }
+
+    @Override
+    public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
+        super.readExternal(in);
+
+        int filterSettingsCount = in.readInt();
+        for (int i = 0; i < filterSettingsCount; i++) {
+            String name = in.readUTF();
+            FilterSetting s = new FilterSetting(name);
+            int filterCount = in.readInt();
+            for (int j = 0; j < filterCount; j++) {
+                String filterName = in.readUTF();
+                CustomFilter filter = findFilter(filterName);
+                if (filter != null) {
+                    s.addFilter(filter);
+                }
+            }
+
+            filterSettings.add(s);
+        }
+        updateComboBox();
+    }
+
+    final static class ResolvableHelper implements Serializable {
+
+        private static final long serialVersionUID = 1L;
+
+        public Object readResolve() {
+            return FilterTopComponent.getDefault();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponentSettings.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE settings PUBLIC "-//NetBeans//DTD Session settings 1.0//EN" "http://www.netbeans.org/dtds/sessionsettings-1_0.dtd">
+<settings version="1.0">
+    <module name="com.sun.hotspot.igv.filterwindow" spec="1.0"/>
+    <instanceof class="org.openide.windows.TopComponent"/>
+    <instanceof class="com.sun.hotspot.igv.filterwindow.FilterTopComponent"/>
+    <instance class="com.sun.hotspot.igv.filterwindow.FilterTopComponent" method="getDefault"/>
+</settings>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponentWstcref.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,7 @@
+<?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="com.sun.hotspot.igv.filterwindow" spec="1.0"/>
+    <tc-id id="FilterTopComponent"/>
+    <state opened="true"/>
+</tc-ref>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,10 @@
+# To change this template, choose Tools | Templates
+# and open the template in the editor.
+
+CTL_FilterAction=Open Filter Window
+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...
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/FilterAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filterwindow.actions;
+
+import com.sun.hotspot.igv.filterwindow.*;
+import java.awt.event.ActionEvent;
+import javax.swing.AbstractAction;
+import org.openide.util.NbBundle;
+import org.openide.windows.TopComponent;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class FilterAction extends AbstractAction {
+
+    public FilterAction() {
+        super(NbBundle.getMessage(FilterAction.class, "CTL_FilterAction"));
+    }
+
+    public void actionPerformed(ActionEvent evt) {
+        TopComponent win = FilterTopComponent.findInstance();
+        win.open();
+        win.requestActive();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterDownAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filterwindow.actions;
+
+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;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CookieAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class MoveFilterDownAction extends CookieAction {
+
+    protected void performAction(Node[] activatedNodes) {
+        for (Node n : activatedNodes) {
+            Filter c = n.getLookup().lookup(Filter.class);
+            FilterTopComponent.findInstance().getSequence().moveFilterDown(c);
+        }
+    }
+
+    protected int mode() {
+        return CookieAction.MODE_EXACTLY_ONE;
+    }
+
+    public MoveFilterDownAction() {
+
+        putValue(Action.SHORT_DESCRIPTION, "Move filter downwards");
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(MoveFilterUpAction.class, "CTL_MoveFilterDownAction");
+    }
+
+    protected Class[] cookieClasses() {
+        return new Class[]{
+            Filter.class
+        };
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/filterwindow/images/down.gif";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+        putValue("noIconInMenu", Boolean.TRUE);
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterUpAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filterwindow.actions;
+
+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;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CookieAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class MoveFilterUpAction extends CookieAction {
+
+    protected void performAction(Node[] activatedNodes) {
+        for (Node n : activatedNodes) {
+            Filter c = n.getLookup().lookup(Filter.class);
+            FilterTopComponent.findInstance().getSequence().moveFilterUp(c);
+        }
+    }
+
+    protected int mode() {
+        return CookieAction.MODE_EXACTLY_ONE;
+    }
+
+    public MoveFilterUpAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Move filter upwards");
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(MoveFilterUpAction.class, "CTL_MoveFilterUpAction");
+    }
+
+    protected Class[] cookieClasses() {
+        return new Class[]{
+            Filter.class
+        };
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/filterwindow/images/up.gif";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+        putValue("noIconInMenu", Boolean.TRUE);
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/NewFilterAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filterwindow.actions;
+
+import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
+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 NewFilterAction extends CallableSystemAction {
+
+    public NewFilterAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Create new filter");
+    }
+
+    public void performAction() {
+        FilterTopComponent.findInstance().newFilter();
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(SaveFilterSettingsAction.class, "CTL_NewFilterAction");
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/filterwindow/images/plus.gif";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,99 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filterwindow.actions;
+
+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;
+import org.openide.util.HelpCtx;
+import org.openide.util.NbBundle;
+import org.openide.util.actions.CookieAction;
+import org.openide.windows.WindowManager;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class RemoveFilterAction extends CookieAction {
+
+    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?",
+                JOptionPane.YES_NO_CANCEL_OPTION,
+                JOptionPane.QUESTION_MESSAGE,
+                null,
+                options,
+                options[2]);
+
+        if (n == JOptionPane.YES_OPTION) {
+            for (int i = 0; i < activatedNodes.length; i++) {
+                FilterTopComponent.findInstance().removeFilter(activatedNodes[i].getLookup().lookup(Filter.class));
+            }
+        }
+    }
+
+    protected int mode() {
+        return CookieAction.MODE_ALL;
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(RemoveFilterAction.class, "CTL_RemoveFilterAction");
+    }
+
+    public RemoveFilterAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Remove filter");
+    }
+
+    protected Class[] cookieClasses() {
+        return new Class[]{
+            Filter.class
+        };
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+        putValue("noIconInMenu", Boolean.TRUE);
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/filterwindow/images/minus.gif";
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterSettingsAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filterwindow.actions;
+
+import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
+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 RemoveFilterSettingsAction extends CallableSystemAction {
+
+    public void performAction() {
+        FilterTopComponent.findInstance().removeFilterSetting();
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(RemoveFilterSettingsAction.class, "CTL_RemoveFilterSettingsAction");
+    }
+
+    public RemoveFilterSettingsAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Remove filter profile");
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/filterwindow/images/delete.gif";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/SaveFilterSettingsAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.filterwindow.actions;
+
+import com.sun.hotspot.igv.filterwindow.FilterTopComponent;
+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 SaveFilterSettingsAction extends CallableSystemAction {
+
+    public void performAction() {
+        FilterTopComponent.findInstance().addFilterSetting();
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(SaveFilterSettingsAction.class, "CTL_SaveFilterSettingsAction");
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    public SaveFilterSettingsAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Create new filter profile");
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/filterwindow/images/add.gif";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/customRightTopWsmode.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mode version="2.1">
+    <name unique="customRightTopMode" />
+    <kind type="view" />
+    <state type="joined" />
+    <constraints>
+        <path orientation="horizontal" number="45" weight="0.21761006289308177"/>
+        <path orientation="vertical" number="0" weight="0.2510122989593188"/>
+    </constraints>
+    <bounds x="0" y="0" width="0" height="0" />
+    <frame state="0"/>
+    <active-tc id="FilterTopComponent"/>
+    <empty-behavior permanent="false"/>
+</mode>
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/delete.gif 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/minus.gif 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/up.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/layer.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,42 @@
+<?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="Edit">
+        <file name="com-sun-hotspot-igv-filterwindow-actions-MoveFilterDownAction.instance">
+            <attr name="position" intvalue="300"/>
+        </file>
+        <file name="com-sun-hotspot-igv-filterwindow-actions-MoveFilterUpAction.instance">
+            <attr name="position" intvalue="400"/>
+        </file>
+        <file name="com-sun-hotspot-igv-filterwindow-actions-RemoveFilterAction.instance">
+            <attr name="position" intvalue="500"/>
+        </file>
+        <file name="com-sun-hotspot-igv-filterwindow-actions-RemoveFilterSettingsAction.instance">
+            <attr name="position" intvalue="600"/>
+        </file>
+        <file name="com-sun-hotspot-igv-filterwindow-actions-SaveFilterSettingsAction.instance">
+            <attr name="position" intvalue="900"/>
+        </file>
+    </folder>
+    <folder name="Window">
+        <file name="com-sun-hotspot-igv-coordinator-actions-FilterAction.instance"/>
+    </folder>
+    <folder name="Menu">
+        <folder name="Window">
+            <file name="FilterAction.shadow">
+                <attr name="originalFile" stringvalue="Actions/Window/com-sun-hotspot-igv-filterwindow-actions-FilterAction.instance"/>
+            </file>
+        </folder>
+    </folder>
+    <folder name="Windows2">
+        <folder name="Components">
+            <file name="FilterTopComponent.settings" url="FilterTopComponentSettings.xml"/>
+        </folder>
+        <folder name="Modes">
+            <file name="customRightTopMode.wsmode" url="customRightTopWsmode.xml"/>
+            <folder name="customRightTopMode">
+                <file name="FilterTopComponent.wstcref" url="FilterTopComponentWstcref.xml"/>
+            </folder>
+        </folder>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/build.xml	Wed Jul 05 16:38:46 2017 +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.graph" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.graph.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.graph
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/graph/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.graph-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=b2bc2f02
+build.xml.script.CRC32=486d5dab
+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=b2bc2f02
+nbproject/build-impl.xml.script.CRC32=17fa0f49
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,31 @@
+<?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.graph</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.layout</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.graph</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/AndSelector.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class AndSelector implements Selector {
+
+    private Selector selector1;
+    private Selector selector2;
+
+    public AndSelector(Selector s1, Selector s2) {
+        this.selector1 = s1;
+        this.selector2 = s2;
+    }
+
+    public List<Figure> selected(Diagram d) {
+        List<Figure> l1 = selector1.selected(d);
+        List<Figure> l2 = selector2.selected(d);
+        List<Figure> result = new ArrayList<Figure>();
+        for (Figure f : l2) {
+            if (l1.contains(f)) {
+                result.add(f);
+            }
+        }
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Block.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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.layout.Cluster;
+import java.awt.Rectangle;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Block implements Cluster {
+
+    private InputBlock inputBlock;
+    private Rectangle bounds;
+    private Diagram diagram;
+
+    public Block(InputBlock inputBlock, Diagram diagram) {
+        this.inputBlock = inputBlock;
+        this.diagram = diagram;
+    }
+
+    public Cluster getOuter() {
+        return null;
+    }
+
+    public InputBlock getInputBlock() {
+        return inputBlock;
+    }
+
+    public Set<? extends Cluster> getSuccessors() {
+        Set<Block> succs = new HashSet<Block>();
+        for (InputBlock b : inputBlock.getSuccessors()) {
+            succs.add(diagram.getBlock(b));
+        }
+        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;
+    }
+
+    public Rectangle getBounds() {
+        return bounds;
+    }
+
+    public int compareTo(Cluster o) {
+        return toString().compareTo(o.toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Graph
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Connection.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.graph;
+
+import com.sun.hotspot.igv.layout.Link;
+import com.sun.hotspot.igv.layout.Port;
+import java.awt.Color;
+import java.awt.Point;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Connection implements Source.Provider, Link {
+
+    public enum ConnectionStyle {
+
+        NORMAL,
+        DASHED,
+        BOLD
+    }
+    private InputSlot inputSlot;
+    private OutputSlot outputSlot;
+    private Source source;
+    private Color color;
+    private ConnectionStyle style;
+    private List<Point> controlPoints;
+
+    protected Connection(InputSlot inputSlot, OutputSlot outputSlot) {
+        this.inputSlot = inputSlot;
+        this.outputSlot = outputSlot;
+        this.inputSlot.connections.add(this);
+        this.outputSlot.connections.add(this);
+        controlPoints = new ArrayList<Point>();
+        Figure sourceFigure = this.outputSlot.getFigure();
+        Figure destFigure = this.inputSlot.getFigure();
+        sourceFigure.addSuccessor(destFigure);
+        destFigure.addPredecessor(sourceFigure);
+        source = new Source();
+
+        this.color = Color.BLACK;
+        this.style = ConnectionStyle.NORMAL;
+    }
+
+    public InputSlot getInputSlot() {
+        return inputSlot;
+    }
+
+    public OutputSlot getOutputSlot() {
+        return outputSlot;
+    }
+
+    public Color getColor() {
+        return color;
+    }
+
+    public ConnectionStyle getStyle() {
+        return style;
+    }
+
+    public void setColor(Color c) {
+        color = c;
+    }
+
+    public void setStyle(ConnectionStyle s) {
+        style = s;
+    }
+
+    public Source getSource() {
+        return source;
+    }
+
+    public void remove() {
+        inputSlot.getFigure().removePredecessor(outputSlot.getFigure());
+        inputSlot.connections.remove(this);
+        outputSlot.getFigure().removeSuccessor(inputSlot.getFigure());
+        outputSlot.connections.remove(this);
+    }
+
+    @Override
+    public String toString() {
+        return "Connection(" + getFrom().getVertex() + " to " + getTo().getVertex() + ")";
+    }
+
+    public Port getFrom() {
+        return outputSlot;
+    }
+
+    public Port getTo() {
+        return inputSlot;
+    }
+
+    public List<Point> getControlPoints() {
+        return controlPoints;
+    }
+
+    public void setControlPoints(List<Point> list) {
+        controlPoints = list;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,294 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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.InputEdge;
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.InputNode;
+import com.sun.hotspot.igv.data.Properties;
+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.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Diagram {
+
+    private List<Figure> figures;
+    private Map<InputBlock, Block> blocks;
+    private InputGraph graph;
+    private int curId;
+    private String nodeText;
+    private Font font;
+
+    public Font getFont() {
+        return font;
+    }
+
+    private Diagram() {
+        figures = new ArrayList<Figure>();
+        blocks = new HashMap<InputBlock, Block>();
+        this.nodeText = "";
+        this.font = new Font("Serif", Font.PLAIN, 14);
+    }
+
+    public Block getBlock(InputBlock b) {
+        return blocks.get(b);
+    }
+
+    public String getNodeText() {
+        return nodeText;
+    }
+
+    public void schedule(Collection<InputBlock> newBlocks) {
+        graph.schedule(newBlocks);
+        updateBlocks();
+    }
+
+    private void updateBlocks() {
+        blocks.clear();
+        for (InputBlock b : graph.getBlocks()) {
+            Block curBlock = new Block(b, this);
+            blocks.put(b, curBlock);
+        }
+    }
+
+    public Diagram getNext() {
+        return Diagram.createDiagram(graph.getNext(), nodeText);
+    }
+
+    public Collection<Block> getBlocks() {
+        return Collections.unmodifiableCollection(blocks.values());
+    }
+
+    public Diagram getPrev() {
+        return Diagram.createDiagram(graph.getPrev(), nodeText);
+    }
+
+    public List<Figure> getFigures() {
+        return Collections.unmodifiableList(figures);
+    }
+
+    public Figure createFigure() {
+        Figure f = new Figure(this, curId);
+        curId++;
+        this.figures.add(f);
+        return f;
+    }
+
+    public Connection createConnection(InputSlot inputSlot, OutputSlot outputSlot) {
+        assert inputSlot.getFigure().getDiagram() == this;
+        assert outputSlot.getFigure().getDiagram() == this;
+        return new Connection(inputSlot, outputSlot);
+    }
+
+    public static Diagram createDiagram(InputGraph graph, String nodeText) {
+        if (graph == null) {
+            return null;
+        }
+
+        Diagram d = new Diagram();
+        d.graph = graph;
+        d.nodeText = nodeText;
+
+        d.updateBlocks();
+
+        Collection<InputNode> nodes = graph.getNodes();
+        Hashtable<Integer, Figure> figureHash = new Hashtable<Integer, Figure>();
+        for (InputNode n : nodes) {
+            Figure f = d.createFigure();
+            f.getSource().addSourceNode(n);
+            f.getProperties().add(n.getProperties());
+            figureHash.put(n.getId(), f);
+        }
+
+        for (InputEdge e : graph.getEdges()) {
+
+            int from = e.getFrom();
+            int to = e.getTo();
+            Figure fromFigure = figureHash.get(from);
+            Figure toFigure = figureHash.get(to);
+            assert fromFigure != null && toFigure != null;
+
+            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);
+
+            if (e.getState() == InputEdge.State.NEW) {
+                c.setStyle(Connection.ConnectionStyle.BOLD);
+            } else if (e.getState() == InputEdge.State.DELETED) {
+                c.setStyle(Connection.ConnectionStyle.DASHED);
+            }
+        }
+
+
+        return d;
+    }
+
+    public void removeAllFigures(Set<Figure> figuresToRemove) {
+        for (Figure f : figuresToRemove) {
+            freeFigure(f);
+        }
+
+        ArrayList<Figure> newFigures = new ArrayList<Figure>();
+        for (Figure f : this.figures) {
+            if (!figuresToRemove.contains(f)) {
+                newFigures.add(f);
+            }
+        }
+        figures = newFigures;
+    }
+
+    private void freeFigure(Figure succ) {
+
+        List<InputSlot> inputSlots = new ArrayList<InputSlot>(succ.getInputSlots());
+        for (InputSlot s : inputSlots) {
+            succ.removeInputSlot(s);
+        }
+
+        List<OutputSlot> outputSlots = new ArrayList<OutputSlot>(succ.getOutputSlots());
+        for (OutputSlot s : outputSlots) {
+            succ.removeOutputSlot(s);
+        }
+
+        assert succ.getInputSlots().size() == 0;
+        assert succ.getOutputSlots().size() == 0;
+        assert succ.getPredecessors().size() == 0;
+        assert succ.getSuccessors().size() == 0;
+
+    }
+
+    public void removeFigure(Figure succ) {
+
+        assert this.figures.contains(succ);
+        freeFigure(succ);
+        this.figures.remove(succ);
+    }
+
+    public String getName() {
+        return graph.getName();
+    }
+
+    public InputGraph getGraph() {
+        return graph;
+    }
+
+    public Set<Connection> getConnections() {
+
+        Set<Connection> connections = new HashSet<Connection>();
+        for (Figure f : figures) {
+
+            for (InputSlot s : f.getInputSlots()) {
+                connections.addAll(s.getConnections());
+            }
+        }
+
+        return connections;
+    }
+
+    public Figure getRootFigure() {
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(figures);
+        Figure root = selector.selectSingle("name", "Root");
+        if (root == null) {
+            root = selector.selectSingle("name", "Start");
+        }
+        if (root == null) {
+            List<Figure> rootFigures = getRootFigures();
+            if (rootFigures.size() > 0) {
+                root = rootFigures.get(0);
+            } else if (figures.size() > 0) {
+                root = figures.get(0);
+            }
+        }
+
+        return root;
+    }
+
+    public void printStatistics() {
+        System.out.println("=============================================================");
+        System.out.println("Diagram statistics");
+
+        List<Figure> tmpFigures = getFigures();
+        Set<Connection> connections = getConnections();
+
+        System.out.println("Number of figures: " + tmpFigures.size());
+        System.out.println("Number of connections: " + connections.size());
+
+        List<Figure> figuresSorted = new ArrayList<Figure>(tmpFigures);
+        Collections.sort(figuresSorted, new Comparator<Figure>() {
+
+            public int compare(Figure a, Figure b) {
+                return b.getPredecessors().size() + b.getSuccessors().size() - a.getPredecessors().size() - a.getSuccessors().size();
+            }
+        });
+
+        final int COUNT = 10;
+        int z = 0;
+        for (Figure f : figuresSorted) {
+
+            z++;
+            int sum = f.getPredecessors().size() + f.getSuccessors().size();
+            System.out.println("#" + z + ": " + f + ", predCount=" + f.getPredecessors().size() + " succCount=" + f.getSuccessors().size());
+            if (sum < COUNT) {
+                break;
+            }
+
+        }
+
+        System.out.println("=============================================================");
+    }
+
+    public List<Figure> getRootFigures() {
+        ArrayList<Figure> rootFigures = new ArrayList<Figure>();
+        for (Figure f : figures) {
+            if (f.getPredecessors().size() == 0) {
+                rootFigures.add(f);
+            }
+        }
+        return rootFigures;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,328 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.graph;
+
+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.image.BufferedImage;
+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 Figure extends Properties.Object 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 boolean VERTICAL_LAYOUT = true;
+    protected List<InputSlot> inputSlots;
+    protected List<OutputSlot> outputSlots;
+    private Source source;
+    private Diagram diagram;
+    private Point position;
+    private List<Figure> predecessors;
+    private List<Figure> successors;
+    private Color color;
+    private int id;
+    private String idString;
+    private String[] lines;
+    private int heightCash = -1;
+    private int widthCash = -1;
+
+    public int getHeight() {
+        if (heightCash == -1) {
+            BufferedImage image = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
+            Graphics g = image.getGraphics();
+            g.setFont(diagram.getFont());
+            FontMetrics metrics = g.getFontMetrics();
+            String nodeText = diagram.getNodeText();
+            heightCash = nodeText.split("\n").length * metrics.getHeight() + INSET;
+        }
+        return heightCash;
+    }
+
+    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());
+            FontMetrics metrics = g.getFontMetrics();
+            for (String s : lines) {
+                int cur = metrics.stringWidth(s);
+                if (cur > max) {
+                    max = cur;
+                }
+            }
+            widthCash = max + INSET;
+        }
+        return widthCash;
+    }
+
+    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);
+        this.id = id;
+        idString = Integer.toString(id);
+
+        this.position = new Point(0, 0);
+        this.color = Color.WHITE;
+    }
+
+    public int getId() {
+        return id;
+    }
+
+    public void setColor(Color color) {
+        this.color = color;
+    }
+
+    public Color getColor() {
+        return color;
+    }
+
+    public List<Figure> getPredecessors() {
+        return Collections.unmodifiableList(predecessors);
+    }
+
+    public Set<Figure> getPredecessorSet() {
+        Set<Figure> result = new HashSet<Figure>();
+        for (Figure f : getPredecessors()) {
+            result.add(f);
+        }
+        return Collections.unmodifiableSet(result);
+    }
+
+    public Set<Figure> getSuccessorSet() {
+        Set<Figure> result = new HashSet<Figure>();
+        for (Figure f : getSuccessors()) {
+            result.add(f);
+        }
+        return Collections.unmodifiableSet(result);
+    }
+
+    public List<Figure> getSuccessors() {
+        return Collections.unmodifiableList(successors);
+    }
+
+    protected void addPredecessor(Figure f) {
+        this.predecessors.add(f);
+    }
+
+    protected void addSuccessor(Figure f) {
+        this.successors.add(f);
+    }
+
+    protected void removePredecessor(Figure f) {
+        assert predecessors.contains(f);
+        predecessors.remove(f);
+    }
+
+    protected void removeSuccessor(Figure f) {
+        assert successors.contains(f);
+        successors.remove(f);
+    }
+
+    public void setPosition(Point p) {
+        this.position = p;
+    }
+
+    public Point getPosition() {
+        return position;
+    }
+
+    public Diagram getDiagram() {
+        return diagram;
+    }
+
+    public Source getSource() {
+        return source;
+    }
+
+    public InputSlot createInputSlot() {
+        InputSlot slot = new InputSlot(this, -1);
+        inputSlots.add(slot);
+        return slot;
+    }
+
+    public InputSlot createInputSlot(int index) {
+        InputSlot slot = new InputSlot(this, index);
+        inputSlots.add(slot);
+        Collections.sort(inputSlots, Slot.slotIndexComparator);
+        return slot;
+    }
+
+    public void removeSlot(Slot s) {
+
+        assert inputSlots.contains(s) || outputSlots.contains(s);
+
+        List<Connection> connections = new ArrayList<Connection>(s.getConnections());
+        for (Connection c : connections) {
+            c.remove();
+        }
+
+        if (inputSlots.contains(s)) {
+            inputSlots.remove(s);
+        } else if (outputSlots.contains(s)) {
+            outputSlots.remove(s);
+        }
+    }
+
+    public OutputSlot createOutputSlot() {
+        OutputSlot slot = new OutputSlot(this, -1);
+        outputSlots.add(slot);
+        return slot;
+    }
+
+    public OutputSlot createOutputSlot(int index) {
+        OutputSlot slot = new OutputSlot(this, index);
+        outputSlots.add(slot);
+        Collections.sort(outputSlots, Slot.slotIndexComparator);
+        return slot;
+    }
+
+    public List<InputSlot> getInputSlots() {
+        return Collections.unmodifiableList(inputSlots);
+    }
+
+    public List<OutputSlot> getOutputSlots() {
+        return Collections.unmodifiableList(outputSlots);
+    }
+
+    void removeInputSlot(InputSlot s) {
+        s.removeAllConnections();
+        inputSlots.remove(s);
+    }
+
+    void removeOutputSlot(OutputSlot s) {
+        s.removeAllConnections();
+        outputSlots.remove(s);
+    }
+
+    public String[] getLines() {
+        if (lines == null) {
+            updateLines();
+        }
+        return lines;
+    }
+
+    public void updateLines() {
+        String[] strings = diagram.getNodeText().split("\n");
+        String[] result = new String[strings.length];
+
+        for (int i = 0; i < strings.length; i++) {
+            result[i] = resolveString(strings[i]);
+        }
+
+        lines = result;
+    }
+
+    private String resolveString(String string) {
+
+        StringBuilder sb = new StringBuilder();
+        boolean inBrackets = false;
+        StringBuilder curIdent = new StringBuilder();
+
+        for (int i = 0; i < string.length(); i++) {
+            char c = string.charAt(i);
+            if (inBrackets) {
+                if (c == ']') {
+                    String value = getProperties().get(curIdent.toString());
+                    if (value == null) {
+                        value = "";
+                    }
+                    sb.append(value);
+                    inBrackets = false;
+                } else {
+                    curIdent.append(c);
+                }
+            } else {
+                if (c == '[') {
+                    inBrackets = true;
+                    curIdent = new StringBuilder();
+                } else {
+                    sb.append(c);
+                }
+            }
+        }
+
+        return sb.toString();
+    }
+
+    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;
+            return new Dimension(width, height);
+        } else {
+            int width = getWidth() + 2 * Figure.SLOT_WIDTH;
+            int height = Figure.SLOT_WIDTH * (Math.max(inputSlots.size(), outputSlots.size()) + 1);
+            return new Dimension(width, height);
+        }
+    }
+
+    @Override
+    public String toString() {
+        return idString;
+    }
+
+    public Cluster getCluster() {
+        if (getSource().getSourceNodes().size() == 0) {
+            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)));
+            assert result != null;
+            return result;
+        }
+    }
+
+    public boolean isRoot() {
+        if (source.getSourceNodes().size() > 0 && source.getSourceNodes().get(0).getProperties().get("name").equals("Root")) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    public int compareTo(Vertex f) {
+        return toString().compareTo(f.toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InputSlot.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.graph;
+
+import java.awt.Point;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputSlot extends Slot {
+
+    protected InputSlot(Figure figure, int wantedIndex) {
+        super(figure, wantedIndex);
+    }
+
+    public int getPosition() {
+        return getFigure().getInputSlots().indexOf(this);
+    }
+
+    public void setPosition(int position) {
+        List<InputSlot> inputSlots = getFigure().inputSlots;
+        InputSlot s = inputSlots.remove(position);
+        inputSlots.add(position, s);
+    }
+
+    public Point getRelativePosition() {
+        return new Point(getFigure().getWidth() * (getPosition() + 1) / (getFigure().getInputSlots().size() + 1), Figure.SLOT_WIDTH - Figure.SLOT_START);
+    }
+
+    @Override
+    public String toString() {
+        return "InputSlot[figure=" + this.getFigure().toString() + ", position=" + getPosition() + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InvertSelector.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InvertSelector implements Selector {
+
+    private Selector selector;
+
+    public InvertSelector(Selector selector) {
+        this.selector = selector;
+    }
+
+    public List<Figure> selected(Diagram d) {
+
+        List<Figure> result = new ArrayList<Figure>();
+        List<Figure> otherResult = selector.selected(d);
+        for (Figure f : d.getFigures()) {
+            if (!otherResult.contains(f)) {
+                result.add(f);
+            }
+        }
+
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/MatcherSelector.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.graph;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Properties.PropertyMatcher;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class MatcherSelector implements Selector {
+
+    private PropertyMatcher matcher;
+
+    public MatcherSelector(PropertyMatcher matcher) {
+        this.matcher = matcher;
+    }
+
+    public List<Figure> selected(Diagram d) {
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(d.getFigures());
+        List<Figure> list = selector.selectMultiple(matcher);
+        return list;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OrSelector.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.graph;
+
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class OrSelector implements Selector {
+
+    private Selector selector1;
+    private Selector selector2;
+
+    /** Creates a new instance of OrSelector */
+    public OrSelector(Selector s1, Selector s2) {
+        this.selector1 = s1;
+        this.selector2 = s2;
+    }
+
+    public List<Figure> selected(Diagram d) {
+
+        List<Figure> l1 = selector1.selected(d);
+        List<Figure> l2 = selector2.selected(d);
+
+        for (Figure f : l2) {
+            if (!l1.contains(f)) {
+                l1.add(f);
+            }
+        }
+
+        return l1;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OutputSlot.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.graph;
+
+import java.awt.Point;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class OutputSlot extends Slot {
+
+    protected OutputSlot(Figure figure, int wantedIndex) {
+        super(figure, wantedIndex);
+    }
+
+    public int getPosition() {
+        return getFigure().getOutputSlots().indexOf(this);
+    }
+
+    public void setPosition(int position) {
+        OutputSlot s = getFigure().outputSlots.remove(position);
+        getFigure().outputSlots.add(position, s);
+    }
+
+    public Point getRelativePosition() {
+        return new Point(getFigure().getWidth() * (getPosition() + 1) / (getFigure().getOutputSlots().size() + 1), getFigure().getSize().height - Figure.SLOT_WIDTH + Figure.SLOT_START);
+    }
+
+    @Override
+    public String toString() {
+        return "OutputSlot[figure=" + this.getFigure().toString() + ", position=" + getPosition() + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/PredecessorSelector.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PredecessorSelector implements Selector {
+
+    private Selector innerSelector;
+
+    public PredecessorSelector(Selector innerSelector) {
+        this.innerSelector = innerSelector;
+    }
+
+    public List<Figure> selected(Diagram d) {
+        List<Figure> inner = innerSelector.selected(d);
+        List<Figure> result = new ArrayList<Figure>();
+        for (Figure f : d.getFigures()) {
+            boolean saved = false;
+            for (Figure f2 : f.getSuccessors()) {
+                if (inner.contains(f2)) {
+                    saved = true;
+                }
+            }
+
+            if (saved) {
+                result.add(f);
+            }
+        }
+
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Selector.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.graph;
+
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface Selector {
+
+    List<Figure> selected(Diagram d);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.graph;
+
+import com.sun.hotspot.igv.layout.Port;
+import com.sun.hotspot.igv.layout.Vertex;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Comparator;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public abstract class Slot implements Port, Source.Provider {
+
+    private int wantedIndex;
+    private String name;
+    private String shortName; // 1 - 2 characters
+    private Source source;
+    protected List<Connection> connections;
+    private Figure figure;
+
+    protected Slot(Figure figure, int wantedIndex) {
+        this.figure = figure;
+        connections = new ArrayList<Connection>(2);
+        source = new Source();
+        this.wantedIndex = wantedIndex;
+        name = "";
+        shortName = "";
+        assert figure != null;
+    }
+    public static final Comparator<Slot> slotIndexComparator = new Comparator<Slot>() {
+
+        public int compare(Slot o1, Slot o2) {
+            return o1.wantedIndex - o2.wantedIndex;
+        }
+    };
+    public static final Comparator<Slot> slotFigureComparator = new Comparator<Slot>() {
+
+        public int compare(Slot o1, Slot o2) {
+            return o1.figure.getId() - o2.figure.getId();
+        }
+    };
+
+    public int getWantedIndex() {
+        return wantedIndex;
+    }
+
+    public Source getSource() {
+        return source;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setShortName(String s) {
+        assert s != null;
+        assert s.length() <= 2;
+        this.shortName = s;
+
+    }
+
+    public String getShortName() {
+        return shortName;
+    }
+
+    public boolean getShowName() {
+        return getShortName() != null && getShortName().length() > 0;
+    }
+
+    public void setName(String s) {
+        if (s == null) {
+            s = "";
+        }
+        this.name = s;
+    }
+
+    public Figure getFigure() {
+        assert figure != null;
+        return figure;
+    }
+
+    public List<Connection> getConnections() {
+        return Collections.unmodifiableList(connections);
+    }
+
+    public void removeAllConnections() {
+        List<Connection> connectionsCopy = new ArrayList<Connection>(this.connections);
+        for (Connection c : connectionsCopy) {
+            c.remove();
+        }
+    }
+
+    public Vertex getVertex() {
+        return figure;
+    }
+
+    public abstract int getPosition();
+
+    public abstract void setPosition(int position);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Source.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/SuccessorSelector.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.graph;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class SuccessorSelector implements Selector {
+
+    private Selector innerSelector;
+
+    public SuccessorSelector(Selector innerSelector) {
+        this.innerSelector = innerSelector;
+    }
+
+    public List<Figure> selected(Diagram d) {
+        List<Figure> inner = innerSelector.selected(d);
+        List<Figure> result = new ArrayList<Figure>();
+        for (Figure f : d.getFigures()) {
+            boolean saved = false;
+            for (Figure f2 : f.getPredecessors()) {
+                if (inner.contains(f2)) {
+                    saved = true;
+                }
+            }
+
+            if (saved) {
+                result.add(f);
+            }
+        }
+
+        return result;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/build.xml	Wed Jul 05 16:38:46 2017 +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.hierarchicallayout" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.hierarchicallayout.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.hierarchicallayout
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/hierarchicallayout/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.hierarchicallayout-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=de087df9
+build.xml.script.CRC32=98977c36
+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=de087df9
+nbproject/build-impl.xml.script.CRC32=0d734625
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +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.hierarchicallayout</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <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>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.hierarchicallayout</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=HierarchicalLayout
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterEdge.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.hierarchicallayout;
+
+import com.sun.hotspot.igv.layout.Link;
+import com.sun.hotspot.igv.layout.Port;
+import java.awt.Point;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ClusterEdge implements Link {
+
+    private ClusterNode from;
+    private ClusterNode to;
+    private List<Point> points;
+
+    public ClusterEdge(ClusterNode from, ClusterNode to) {
+        assert from != null;
+        assert to != null;
+        this.from = from;
+        this.to = to;
+    }
+
+    public Port getTo() {
+        return to.getInputSlot();
+    }
+
+    public Port getFrom() {
+        return from.getInputSlot();
+    }
+
+    public void setControlPoints(List<Point> p) {
+        this.points = p;
+    }
+
+    public List<Point> getControlPoints() {
+        return points;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterIngoingConnection.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.hierarchicallayout;
+
+import com.sun.hotspot.igv.layout.Link;
+import com.sun.hotspot.igv.layout.Port;
+import java.awt.Point;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ClusterIngoingConnection implements Link {
+
+    private List<Point> controlPoints;
+    private ClusterInputSlotNode inputSlotNode;
+    private Link connection;
+    private Port inputSlot;
+    private Port outputSlot;
+
+    public ClusterIngoingConnection(ClusterInputSlotNode inputSlotNode, Link c) {
+        this.inputSlotNode = inputSlotNode;
+        this.connection = c;
+        this.controlPoints = new ArrayList<Point>();
+
+        inputSlot = c.getTo();
+        outputSlot = inputSlotNode.getOutputSlot();
+    }
+
+    public Link getConnection() {
+        return connection;
+    }
+
+    public ClusterInputSlotNode getInputSlotNode() {
+        return inputSlotNode;
+    }
+
+    public Port getTo() {
+        return inputSlot;
+    }
+
+    public Port getFrom() {
+        return outputSlot;
+    }
+
+    public void setControlPoints(List<Point> p) {
+        this.controlPoints = p;
+    }
+
+    public List<Point> getControlPoints() {
+        return controlPoints;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterInputSlotNode.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.hierarchicallayout;
+
+import com.sun.hotspot.igv.layout.Cluster;
+import com.sun.hotspot.igv.layout.Port;
+import com.sun.hotspot.igv.layout.Vertex;
+import java.awt.Dimension;
+import java.awt.Point;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ClusterInputSlotNode implements Vertex {
+
+    private final int SIZE = 0;
+    private Point position;
+    private Port inputSlot;
+    private Port outputSlot;
+    private ClusterNode blockNode;
+    private InterClusterConnection interBlockConnection;
+    private Cluster cluster;
+    private ClusterIngoingConnection conn;
+
+    public void setIngoingConnection(ClusterIngoingConnection c) {
+        conn = c;
+    }
+
+    public ClusterIngoingConnection getIngoingConnection() {
+        return conn;
+    }
+    private String id;
+
+    @Override
+    public String toString() {
+        return id;
+    }
+
+    public ClusterInputSlotNode(ClusterNode n, String id) {
+        this.blockNode = n;
+        this.id = id;
+
+        n.addSubNode(this);
+
+        final Vertex thisNode = this;
+        final ClusterNode thisBlockNode = blockNode;
+
+        outputSlot = new Port() {
+
+            public Point getRelativePosition() {
+                return new Point(0, 0);
+            }
+
+            public Vertex getVertex() {
+                return thisNode;
+            }
+
+            @Override
+            public String toString() {
+                return "OutPort of " + thisNode.toString();
+            }
+        };
+
+        inputSlot = new Port() {
+
+            public Point getRelativePosition() {
+                Point p = new Point(thisNode.getPosition());
+                p.x += ClusterNode.BORDER;
+                p.y = 0;
+                return p;
+            }
+
+            public Vertex getVertex() {
+                return thisBlockNode;
+            }
+
+            @Override
+            public String toString() {
+                return "InPort of " + thisNode.toString();
+            }
+        };
+    }
+
+    public Port getInputSlot() {
+        return inputSlot;
+    }
+
+    public InterClusterConnection getInterBlockConnection() {
+        return interBlockConnection;
+    }
+
+    public Port getOutputSlot() {
+        return outputSlot;
+    }
+
+    public Dimension getSize() {
+        return new Dimension(SIZE, SIZE);
+    }
+
+    public void setPosition(Point p) {
+        this.position = p;
+    }
+
+    public Point getPosition() {
+        return position;
+    }
+
+    public void setInterBlockConnection(InterClusterConnection interBlockConnection) {
+        this.interBlockConnection = interBlockConnection;
+    }
+
+    public Cluster getCluster() {
+        return cluster;
+    }
+
+    public boolean isRoot() {
+        return true;
+    }
+
+    public int compareTo(Vertex o) {
+        return toString().compareTo(o.toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,233 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.hierarchicallayout;
+
+import com.sun.hotspot.igv.layout.Cluster;
+import com.sun.hotspot.igv.layout.Link;
+import com.sun.hotspot.igv.layout.Port;
+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.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ClusterNode implements Vertex {
+
+    private Cluster cluster;
+    private Port inputSlot;
+    private Port outputSlot;
+    private Set<Vertex> subNodes;
+    private Dimension size;
+    private Point position;
+    private Set<Link> subEdges;
+    private boolean dirty;
+    private boolean root;
+    private String name;
+    public static final int BORDER = 20;
+
+    public ClusterNode(Cluster cluster, String name) {
+        this.subNodes = new HashSet<Vertex>();
+        this.subEdges = new HashSet<Link>();
+        this.cluster = cluster;
+        position = new Point(0, 0);
+        this.name = name;
+    }
+
+    public void addSubNode(Vertex v) {
+        subNodes.add(v);
+    }
+
+    public void addSubEdge(Link l) {
+        subEdges.add(l);
+    }
+
+    public Set<Link> getSubEdges() {
+        return Collections.unmodifiableSet(subEdges);
+    }
+
+    public void updateSize() {
+
+
+        calculateSize();
+
+        final ClusterNode widget = this;
+        inputSlot = new Port() {
+
+            public Point getRelativePosition() {
+                return new Point(size.width / 2, 0);
+            }
+
+            public Vertex getVertex() {
+                return widget;
+            }
+        };
+
+        outputSlot = new Port() {
+
+            public Point getRelativePosition() {
+                return new Point(size.width / 2, size.height);
+            }
+
+            public Vertex getVertex() {
+                return widget;
+            }
+        };
+    }
+
+    private void calculateSize() {
+
+        if (subNodes.size() == 0) {
+            size = new Dimension(0, 0);
+        }
+
+        int minX = Integer.MAX_VALUE;
+        int maxX = Integer.MIN_VALUE;
+        int minY = Integer.MAX_VALUE;
+        int maxY = Integer.MIN_VALUE;
+
+
+        for (Vertex n : subNodes) {
+            Point p = n.getPosition();
+            minX = Math.min(minX, p.x);
+            minY = Math.min(minY, p.y);
+            maxX = Math.max(maxX, p.x + n.getSize().width);
+            maxY = Math.max(maxY, p.y + n.getSize().height);
+        }
+
+        for (Link l : subEdges) {
+            List<Point> points = l.getControlPoints();
+            for (Point p : points) {
+                if (p != null) {
+                    minX = Math.min(minX, p.x);
+                    maxX = Math.max(maxX, p.x);
+                    minY = Math.min(minY, p.y);
+                    maxY = Math.max(maxY, p.y);
+                }
+            }
+        }
+
+        size = new Dimension(maxX - minX, maxY - minY);
+
+        // Normalize coordinates
+        for (Vertex n : subNodes) {
+            n.setPosition(new Point(n.getPosition().x - minX, n.getPosition().y - minY));
+        }
+
+        for (Link l : subEdges) {
+            List<Point> points = new ArrayList<Point>(l.getControlPoints());
+            for (Point p : points) {
+                p.x -= minX;
+                p.y -= minY;
+            }
+            l.setControlPoints(points);
+
+        }
+
+        size.width += 2 * BORDER;
+        size.height += 2 * BORDER;
+    }
+
+    public Port getInputSlot() {
+        return inputSlot;
+
+    }
+
+    public Port getOutputSlot() {
+        return outputSlot;
+    }
+
+    public Dimension getSize() {
+        return size;
+    }
+
+    public Point getPosition() {
+        return position;
+    }
+
+    public void setPosition(Point pos) {
+
+        this.position = pos;
+        for (Vertex n : subNodes) {
+            Point cur = new Point(n.getPosition());
+            cur.translate(pos.x + BORDER, pos.y + BORDER);
+            n.setPosition(cur);
+        }
+
+        for (Link e : subEdges) {
+            List<Point> arr = e.getControlPoints();
+            ArrayList<Point> newArr = new ArrayList<Point>();
+            for (Point p : arr) {
+                if (p != null) {
+                    Point p2 = new Point(p);
+                    p2.translate(pos.x + BORDER, pos.y + BORDER);
+                    newArr.add(p2);
+                } else {
+                    newArr.add(null);
+                }
+            }
+
+            e.setControlPoints(newArr);
+        }
+    }
+
+    public Cluster getCluster() {
+        return cluster;
+    }
+
+    public void setCluster(Cluster c) {
+        cluster = c;
+    }
+
+    public void setDirty(boolean b) {
+        dirty = b;
+    }
+
+    public void setRoot(boolean b) {
+        root = b;
+    }
+
+    public boolean isRoot() {
+        return root;
+    }
+
+    public int compareTo(Vertex o) {
+        return toString().compareTo(o.toString());
+    }
+
+    @Override
+    public String toString() {
+        return name;
+    }
+
+    public Set<? extends Vertex> getSubNodes() {
+        return subNodes;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterOutgoingConnection.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.hierarchicallayout;
+
+import com.sun.hotspot.igv.layout.Link;
+import com.sun.hotspot.igv.layout.Port;
+import java.awt.Point;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ClusterOutgoingConnection implements Link {
+
+    private List<Point> intermediatePoints;
+    private ClusterOutputSlotNode outputSlotNode;
+    private Link connection;
+    private Port inputSlot;
+    private Port outputSlot;
+
+    public ClusterOutgoingConnection(ClusterOutputSlotNode outputSlotNode, Link c) {
+        this.outputSlotNode = outputSlotNode;
+        this.connection = c;
+        this.intermediatePoints = new ArrayList<Point>();
+
+        outputSlot = c.getFrom();
+        inputSlot = outputSlotNode.getInputSlot();
+    }
+
+    public Port getTo() {
+        return inputSlot;
+    }
+
+    public Port getFrom() {
+        return outputSlot;
+    }
+
+    public void setControlPoints(List<Point> p) {
+        this.intermediatePoints = p;
+    }
+
+    public List<Point> getControlPoints() {
+        return intermediatePoints;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterOutputSlotNode.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.hierarchicallayout;
+
+import com.sun.hotspot.igv.layout.Cluster;
+import com.sun.hotspot.igv.layout.Port;
+import com.sun.hotspot.igv.layout.Vertex;
+import java.awt.Dimension;
+import java.awt.Point;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ClusterOutputSlotNode implements Vertex {
+
+    private final int SIZE = 0;
+    private Point position;
+    private Port inputSlot;
+    private Port outputSlot;
+    private ClusterNode blockNode;
+    private boolean root;
+    private Cluster cluster;
+    private ClusterOutgoingConnection conn;
+    private String id;
+
+    public void setOutgoingConnection(ClusterOutgoingConnection c) {
+        this.conn = c;
+    }
+
+    public ClusterOutgoingConnection getOutgoingConnection() {
+        return conn;
+    }
+
+    @Override
+    public String toString() {
+        return id;
+    }
+
+    public ClusterOutputSlotNode(ClusterNode n, String id) {
+        this.blockNode = n;
+        this.id = id;
+
+        n.addSubNode(this);
+
+        final Vertex thisNode = this;
+        final ClusterNode thisBlockNode = blockNode;
+
+        inputSlot = new Port() {
+
+            public Point getRelativePosition() {
+                return new Point(0, 0);
+            }
+
+            public Vertex getVertex() {
+                return thisNode;
+            }
+
+            @Override
+            public String toString() {
+                return "InPort of " + thisNode.toString();
+            }
+        };
+
+        outputSlot = new Port() {
+
+            public Point getRelativePosition() {
+                Point p = new Point(thisNode.getPosition());
+                p.x += ClusterNode.BORDER;
+                p.y = thisBlockNode.getSize().height;
+                return p;
+            }
+
+            public Vertex getVertex() {
+                return thisBlockNode;
+            }
+
+            @Override
+            public String toString() {
+                return "OutPort of " + thisNode.toString();
+            }
+        };
+    }
+
+    public Dimension getSize() {
+        return new Dimension(SIZE, SIZE);
+    }
+
+    public void setPosition(Point p) {
+        this.position = p;
+    }
+
+    public Point getPosition() {
+        return position;
+    }
+
+    public Port getInputSlot() {
+        return inputSlot;
+    }
+
+    public Port getOutputSlot() {
+        return outputSlot;
+    }
+
+    public void setCluster(Cluster c) {
+        cluster = c;
+    }
+
+    public void setRoot(boolean b) {
+        root = b;
+    }
+
+    public Cluster getCluster() {
+        return cluster;
+    }
+
+    public boolean isRoot() {
+        return root;
+    }
+
+    public int compareTo(Vertex o) {
+        return toString().compareTo(o.toString());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Edge.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.hierarchicallayout;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Edge<N, E> {
+
+    private E data;
+    private Node<N, E> source;
+    private Node<N, E> dest;
+
+    protected Edge(Graph<N, E> graph, Node<N, E> source, Node<N, E> dest, E data) {
+        setData(data);
+        this.source = source;
+        this.dest = dest;
+        assert source != null;
+        assert dest != null;
+        assert source.getGraph() == dest.getGraph();
+        assert source.getGraph() != null;
+        assert dest.getGraph() != null;
+    }
+
+    public Node<N, E> getSource() {
+        return source;
+    }
+
+    public Node<N, E> getDest() {
+        return dest;
+    }
+
+    public E getData() {
+        return data;
+    }
+
+    public void setData(E e) {
+        data = e;
+    }
+
+    public void remove() {
+        source.getGraph().removeEdge(this, null);
+    }
+
+    public boolean isSelfLoop() {
+        return source == dest;
+    }
+
+    public void reverse() {
+
+        // Remove from current source / dest
+        source.removeOutEdge(this);
+        dest.removeInEdge(this);
+
+        Node<N, E> tmp = source;
+        source = dest;
+        dest = tmp;
+
+        // Add to new source / dest
+        source.addOutEdge(this);
+        dest.addInEdge(this);
+    }
+
+    public String toString() {
+        return "Edge (" + source + " -- " + dest + "): " + data;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Graph.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,298 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.hierarchicallayout;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Hashtable;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Graph<N, E> {
+
+    private Hashtable<Object, Node<N, E>> nodes;
+    private Hashtable<Object, Edge<N, E>> edges;
+    private List<Node<N, E>> nodeList;
+
+    public Graph() {
+        nodes = new Hashtable<Object, Node<N, E>>();
+        edges = new Hashtable<Object, Edge<N, E>>();
+        nodeList = new ArrayList<Node<N, E>>();
+    }
+
+    public Node<N, E> createNode(N data, Object key) {
+        Node<N, E> n = new Node<N, E>(this, data);
+        assert key == null || !nodes.containsKey(key);
+        if (key != null) {
+            nodes.put(key, n);
+        }
+        nodeList.add(n);
+        return n;
+    }
+
+    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);
+        source.addOutEdge(e);
+        dest.addInEdge(e);
+        if (key != null) {
+            edges.put(key, e);
+        }
+        return e;
+    }
+
+    public Node<N, E> getNode(Object key) {
+        return nodes.get(key);
+    }
+
+    public Edge<N, E> getEdge(Object key) {
+        return edges.get(key);
+    }
+
+    public Collection<Edge<N, E>> getEdges() {
+        return Collections.unmodifiableCollection(edges.values());
+    }
+
+    public Collection<Node<N, E>> getNodes() {
+        return Collections.unmodifiableList(nodeList);
+    }
+
+    public void removeEdge(Edge<N, E> e, Object key) {
+        assert key == null || edges.containsKey(key);
+        if (key != null) {
+            edges.remove(key);
+        }
+        e.getSource().removeOutEdge(e);
+        e.getDest().removeInEdge(e);
+    }
+
+    public class DFSTraversalVisitor {
+
+        public void visitNode(Node<N, E> n) {
+        }
+
+        public boolean visitEdge(Edge<N, E> e, boolean backEdge) {
+            return true;
+        }
+    }
+
+    public class BFSTraversalVisitor {
+
+        public void visitNode(Node<N, E> n, int depth) {
+        }
+    }
+
+    public List<Node<N, E>> getNodesWithInDegree(int x) {
+        return getNodesWithInDegree(x, true);
+    }
+
+    public List<Node<N, E>> getNodesWithInDegree(int x, boolean countSelfLoops) {
+
+        List<Node<N, E>> result = new ArrayList<Node<N, E>>();
+        for (Node<N, E> n : getNodes()) {
+            if (n.getInDegree(countSelfLoops) == x) {
+                result.add(n);
+            }
+        }
+
+        return result;
+
+    }
+
+    private void markReachable(Node<N, E> startingNode) {
+        ArrayList<Node<N, E>> arr = new ArrayList<Node<N, E>>();
+        arr.add(startingNode);
+        for (Node<N, E> n : getNodes()) {
+            n.setReachable(false);
+        }
+        traverseDFS(arr, new DFSTraversalVisitor() {
+
+            @Override
+            public void visitNode(Node<N, E> n) {
+                n.setReachable(true);
+            }
+        });
+    }
+
+    public void traverseBFS(Node<N, E> startingNode, BFSTraversalVisitor tv, boolean longestPath) {
+
+        if (longestPath) {
+            markReachable(startingNode);
+        }
+
+        for (Node<N, E> n : getNodes()) {
+            n.setVisited(false);
+            n.setActive(false);
+        }
+
+        Queue<Node<N, E>> queue = new LinkedList<Node<N, E>>();
+        queue.add(startingNode);
+        startingNode.setVisited(true);
+        int layer = 0;
+        Node<N, E> lastOfLayer = startingNode;
+        Node<N, E> lastAdded = null;
+
+        while (!queue.isEmpty()) {
+
+            Node<N, E> current = queue.poll();
+            tv.visitNode(current, layer);
+            current.setActive(false);
+
+
+            for (Edge<N, E> e : current.getOutEdges()) {
+                if (!e.getDest().isVisited()) {
+
+                    boolean allow = true;
+                    if (longestPath) {
+                        for (Node<N, E> pred : e.getDest().getPredecessors()) {
+                            if ((!pred.isVisited() || pred.isActive()) && pred.isReachable()) {
+                                allow = false;
+                                break;
+                            }
+                        }
+                    }
+
+                    if (allow) {
+                        queue.offer(e.getDest());
+                        lastAdded = e.getDest();
+                        e.getDest().setVisited(true);
+                        e.getDest().setActive(true);
+                    }
+                }
+            }
+
+            if (current == lastOfLayer && !queue.isEmpty()) {
+                lastOfLayer = lastAdded;
+                layer++;
+            }
+        }
+    }
+
+    public void traverseDFS(DFSTraversalVisitor tv) {
+        traverseDFS(getNodes(), tv);
+    }
+
+    public void traverseDFS(Collection<Node<N, E>> startingNodes, DFSTraversalVisitor tv) {
+
+        for (Node<N, E> n : getNodes()) {
+            n.setVisited(false);
+            n.setActive(false);
+        }
+
+        boolean result = false;
+        for (Node<N, E> n : startingNodes) {
+            traverse(tv, n);
+        }
+    }
+
+    private void traverse(DFSTraversalVisitor tv, Node<N, E> n) {
+
+        if (!n.isVisited()) {
+            n.setVisited(true);
+            n.setActive(true);
+            tv.visitNode(n);
+
+            for (Edge<N, E> e : n.getOutEdges()) {
+
+                Node<N, E> next = e.getDest();
+                if (next.isActive()) {
+                    tv.visitEdge(e, true);
+                } else {
+                    if (tv.visitEdge(e, false)) {
+                        traverse(tv, next);
+                    }
+                }
+            }
+
+            n.setActive(false);
+        }
+
+    }
+
+    public boolean hasCycles() {
+
+        for (Node<N, E> n : getNodes()) {
+            n.setVisited(false);
+            n.setActive(false);
+        }
+
+        boolean result = false;
+        for (Node<N, E> n : getNodes()) {
+            result |= checkCycles(n);
+            if (result) {
+                break;
+            }
+        }
+        return result;
+    }
+
+    private boolean checkCycles(Node<N, E> n) {
+
+        if (n.isActive()) {
+            return true;
+        }
+
+        if (!n.isVisited()) {
+
+            n.setVisited(true);
+            n.setActive(true);
+
+            for (Node<N, E> succ : n.getSuccessors()) {
+                if (checkCycles(succ)) {
+                    return true;
+                }
+            }
+
+            n.setActive(false);
+
+        }
+
+        return false;
+    }
+
+    @Override
+    public String toString() {
+
+        StringBuilder s = new StringBuilder();
+        s.append("Nodes: ");
+        for (Node<N, E> n : getNodes()) {
+            s.append(n.toString());
+            s.append("\n");
+        }
+
+        s.append("Edges: ");
+
+        for (Edge<N, E> e : getEdges()) {
+            s.append(e.toString());
+            s.append("\n");
+        }
+
+        return s.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.hierarchicallayout;
+
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Set;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.TreeSet;
+import com.sun.hotspot.igv.layout.Cluster;
+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 HierarchicalClusterLayoutManager implements LayoutManager {
+
+    private OldHierarchicalLayoutManager.Combine combine;
+    private LayoutManager subManager = new OldHierarchicalLayoutManager(combine);
+    private LayoutManager manager = new OldHierarchicalLayoutManager(combine, 150);
+    private static final boolean TRACE = false;
+
+    public HierarchicalClusterLayoutManager(OldHierarchicalLayoutManager.Combine combine) {
+        this.combine = combine;
+    }
+
+    public void doLayout(LayoutGraph graph) {
+        doLayout(graph, new HashSet<Vertex>(), new HashSet<Vertex>(), new HashSet<Link>());
+    }
+
+    public void setSubManager(LayoutManager manager) {
+        this.subManager = manager;
+    }
+
+    public void setManager(LayoutManager manager) {
+        this.manager = manager;
+    }
+
+    public void doLayout(LayoutGraph graph, Set<? extends Vertex> firstLayerHint, Set<? extends Vertex> lastLayerHint, Set<? extends Link> importantLinks) {
+
+        assert graph.verify();
+
+        Hashtable<Cluster, List<Vertex>> lists = new Hashtable<Cluster, List<Vertex>>();
+        Hashtable<Cluster, List<Link>> listsConnection = new Hashtable<Cluster, List<Link>>();
+        Hashtable<Cluster, Hashtable<Port, ClusterInputSlotNode>> clusterInputSlotHash = new Hashtable<Cluster, Hashtable<Port, ClusterInputSlotNode>>();
+        Hashtable<Cluster, Hashtable<Port, ClusterOutputSlotNode>> clusterOutputSlotHash = new Hashtable<Cluster, Hashtable<Port, ClusterOutputSlotNode>>();
+
+        Hashtable<Cluster, ClusterNode> clusterNodes = new Hashtable<Cluster, ClusterNode>();
+        Hashtable<Cluster, Set<ClusterInputSlotNode>> clusterInputSlotSet = new Hashtable<Cluster, Set<ClusterInputSlotNode>>();
+        Hashtable<Cluster, Set<ClusterOutputSlotNode>> clusterOutputSlotSet = new Hashtable<Cluster, Set<ClusterOutputSlotNode>>();
+        Set<Link> clusterEdges = new HashSet<Link>();
+        Set<Link> interClusterEdges = new HashSet<Link>();
+        Hashtable<Link, ClusterOutgoingConnection> linkClusterOutgoingConnection = new Hashtable<Link, ClusterOutgoingConnection>();
+        Hashtable<Link, InterClusterConnection> linkInterClusterConnection = new Hashtable<Link, InterClusterConnection>();
+        Hashtable<Link, ClusterIngoingConnection> linkClusterIngoingConnection = new Hashtable<Link, ClusterIngoingConnection>();
+        Set<ClusterNode> clusterNodeSet = new HashSet<ClusterNode>();
+
+        Set<Cluster> cluster = graph.getClusters();
+        int z = 0;
+        for (Cluster c : cluster) {
+            lists.put(c, new ArrayList<Vertex>());
+            listsConnection.put(c, new ArrayList<Link>());
+            clusterInputSlotHash.put(c, new Hashtable<Port, ClusterInputSlotNode>());
+            clusterOutputSlotHash.put(c, new Hashtable<Port, ClusterOutputSlotNode>());
+            clusterOutputSlotSet.put(c, new TreeSet<ClusterOutputSlotNode>());
+            clusterInputSlotSet.put(c, new TreeSet<ClusterInputSlotNode>());
+            ClusterNode cn = new ClusterNode(c, "" + z);
+            clusterNodes.put(c, cn);
+            clusterNodeSet.add(cn);
+            z++;
+        }
+
+        // Add cluster edges
+        for (Cluster c : cluster) {
+
+            ClusterNode start = clusterNodes.get(c);
+
+            for (Cluster succ : c.getSuccessors()) {
+                ClusterNode end = clusterNodes.get(succ);
+                if (end != null && start != end) {
+                    ClusterEdge e = new ClusterEdge(start, end);
+                    clusterEdges.add(e);
+                    interClusterEdges.add(e);
+                }
+            }
+        }
+
+        for (Vertex v : graph.getVertices()) {
+            Cluster c = v.getCluster();
+            assert c != null;
+            clusterNodes.get(c).addSubNode(v);
+        }
+
+        for (Link l : graph.getLinks()) {
+
+            Port fromPort = l.getFrom();
+            Port toPort = l.getTo();
+            Vertex fromVertex = fromPort.getVertex();
+            Vertex toVertex = toPort.getVertex();
+            Cluster fromCluster = fromVertex.getCluster();
+            Cluster toCluster = toVertex.getCluster();
+
+            Port samePort = null;
+            if (combine == OldHierarchicalLayoutManager.Combine.SAME_INPUTS) {
+                samePort = toPort;
+            } else if (combine == OldHierarchicalLayoutManager.Combine.SAME_OUTPUTS) {
+                samePort = fromPort;
+            }
+
+            assert listsConnection.containsKey(fromCluster);
+            assert listsConnection.containsKey(toCluster);
+
+            if (fromCluster == toCluster) {
+                listsConnection.get(fromCluster).add(l);
+                clusterNodes.get(fromCluster).addSubEdge(l);
+            } else {
+                ClusterInputSlotNode inputSlotNode = null;
+                ClusterOutputSlotNode outputSlotNode = null;
+
+                if (samePort != null) {
+                    outputSlotNode = clusterOutputSlotHash.get(fromCluster).get(samePort);
+                    inputSlotNode = clusterInputSlotHash.get(toCluster).get(samePort);
+                }
+
+                if (outputSlotNode == null) {
+                    outputSlotNode = new ClusterOutputSlotNode(clusterNodes.get(fromCluster), "Out " + fromCluster.toString() + " " + samePort.toString());
+                    clusterOutputSlotSet.get(fromCluster).add(outputSlotNode);
+                    ClusterOutgoingConnection conn = new ClusterOutgoingConnection(outputSlotNode, l);
+                    outputSlotNode.setOutgoingConnection(conn);
+                    clusterNodes.get(fromCluster).addSubEdge(conn);
+                    if (samePort != null) {
+                        clusterOutputSlotHash.get(fromCluster).put(samePort, outputSlotNode);
+                    }
+
+                    linkClusterOutgoingConnection.put(l, conn);
+                } else {
+                    linkClusterOutgoingConnection.put(l, outputSlotNode.getOutgoingConnection());
+                }
+
+                if (inputSlotNode == null) {
+                    inputSlotNode = new ClusterInputSlotNode(clusterNodes.get(toCluster), "In " + toCluster.toString() + " " + samePort.toString());
+                    clusterInputSlotSet.get(toCluster).add(inputSlotNode);
+                }
+
+                ClusterIngoingConnection conn = new ClusterIngoingConnection(inputSlotNode, l);
+                inputSlotNode.setIngoingConnection(conn);
+                clusterNodes.get(toCluster).addSubEdge(conn);
+                if (samePort != null) {
+                    clusterInputSlotHash.get(toCluster).put(samePort, inputSlotNode);
+                }
+
+                linkClusterIngoingConnection.put(l, conn);
+
+
+                InterClusterConnection interConn = new InterClusterConnection(outputSlotNode, inputSlotNode);
+                linkInterClusterConnection.put(l, interConn);
+                clusterEdges.add(interConn);
+            }
+        }
+
+        Timing t = null;
+
+        if (TRACE) {
+            new Timing("Child timing");
+            t.start();
+        }
+
+        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>());
+            n.updateSize();
+        }
+
+        Set<Vertex> roots = new LayoutGraph(interClusterEdges).findRootVertices();
+        for (Vertex v : roots) {
+            assert v instanceof ClusterNode;
+            ((ClusterNode) v).setRoot(true);
+        }
+
+        manager.doLayout(new LayoutGraph(clusterEdges, clusterNodeSet), new HashSet<Vertex>(), new HashSet<Vertex>(), interClusterEdges);
+
+        for (Cluster c : cluster) {
+            ClusterNode n = clusterNodes.get(c);
+            c.setBounds(new Rectangle(n.getPosition(), n.getSize()));
+        }
+
+        // TODO: handle case where blocks are not fully connected
+
+        if (TRACE) {
+            t.stop();
+            t.print();
+        }
+
+        for (Link l : graph.getLinks()) {
+
+            if (linkInterClusterConnection.containsKey(l)) {
+                ClusterOutgoingConnection conn1 = linkClusterOutgoingConnection.get(l);
+                InterClusterConnection conn2 = linkInterClusterConnection.get(l);
+                ClusterIngoingConnection conn3 = linkClusterIngoingConnection.get(l);
+
+                assert conn1 != null;
+                assert conn2 != null;
+                assert conn3 != null;
+
+                List<Point> points = new ArrayList<Point>();
+
+                points.addAll(conn1.getControlPoints());
+                points.addAll(conn2.getControlPoints());
+                points.addAll(conn3.getControlPoints());
+
+                l.setControlPoints(points);
+            }
+        }
+    }
+
+    public void doRouting(LayoutGraph graph) {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2110 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.hierarchicallayout;
+
+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.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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class HierarchicalLayoutManager implements LayoutManager {
+
+    public static final boolean TRACE = false;
+    public static final boolean CHECK = false;
+    public static final int SWEEP_ITERATIONS = 1;
+    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 MAX_LAYER_LENGTH = -1;
+    public static final int MIN_LAYER_DIFFERENCE = 1;
+
+    public enum Combine {
+
+        NONE,
+        SAME_INPUTS,
+        SAME_OUTPUTS
+    }
+    // Options
+    private Combine combine;
+    private int dummyWidth;
+    private int dummyHeight;
+    private int xOffset;
+    private int layerOffset;
+    private int maxLayerLength;
+    private int minLayerDifference;
+    // Algorithm global datastructures
+    private Set<Link> reversedLinks;
+    private List<LayoutNode> nodes;
+    private HashMap<Vertex, LayoutNode> vertexToLayoutNode;
+    private HashMap<Link, List<Point>> reversedLinkStartPoints;
+    private HashMap<Link, List<Point>> reversedLinkEndPoints;
+    private HashMap<LayoutEdge, LayoutEdge> bottomEdgeHash;
+    private HashMap<Link, List<Point>> splitStartPoints;
+    private HashMap<Link, List<Point>> splitEndPoints;
+    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;
+
+    private class LayoutNode {
+
+        public int x;
+        public int y;
+        public int width;
+        public int height;
+        public int layer = -1;
+        public int xOffset;
+        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 int pos = -1; // Position within layer
+        public int crossingNumber;
+
+        @Override
+        public String toString() {
+            return "Node " + vertex;
+        }
+    }
+
+    private class LayoutEdge {
+
+        public LayoutNode from;
+        public LayoutNode to;
+        public int relativeFrom;
+        public int relativeTo;
+        public Link link;
+    }
+
+    private abstract class AlgorithmPart {
+
+        public void start() {
+            if (CHECK) {
+                preCheck();
+            }
+
+            long start = 0;
+            if (TRACE) {
+                System.out.println("##################################################");
+                System.out.println("Starting part " + this.getClass().getName());
+                start = System.currentTimeMillis();
+            }
+            run();
+            if (TRACE) {
+                System.out.println("Timing for " + this.getClass().getName() + " is " + (System.currentTimeMillis() - start));
+                printStatistics();
+            }
+
+            if (CHECK) {
+                postCheck();
+            }
+        }
+
+        protected abstract void run();
+
+        protected void printStatistics() {
+        }
+
+        protected void postCheck() {
+        }
+
+        protected void preCheck() {
+        }
+    }
+
+    public HierarchicalLayoutManager() {
+        this(Combine.NONE);
+    }
+
+    public HierarchicalLayoutManager(Combine b) {
+        this.combine = b;
+        this.dummyWidth = DUMMY_WIDTH;
+        this.dummyHeight = DUMMY_HEIGHT;
+        this.xOffset = X_OFFSET;
+        this.layerOffset = LAYER_OFFSET;
+        this.maxLayerLength = MAX_LAYER_LENGTH;
+        this.minLayerDifference = MIN_LAYER_DIFFERENCE;
+        this.linksToFollow = new HashSet<Link>();
+    }
+
+    public int getMaxLayerLength() {
+        return maxLayerLength;
+    }
+
+    public void setMaxLayerLength(int v) {
+        maxLayerLength = v;
+    }
+
+    public void setMinLayerDifference(int v) {
+        minLayerDifference = v;
+    }
+
+    public void doLayout(LayoutGraph graph) {
+        doLayout(graph, new HashSet<Vertex>(), new HashSet<Vertex>(), new HashSet<Link>());
+
+    }
+
+    public void doLayout(LayoutGraph graph, Set<? extends Vertex> firstLayerHint, Set<? extends Vertex> lastLayerHint, 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>>();
+
+        // #############################################################
+        // Step 1: Build up data structure
+        new BuildDatastructure().start();
+
+        // #############################################################
+        // STEP 2: Reverse edges, handle backedges
+        new ReverseEdges().start();
+
+        for (LayoutNode n : nodes) {
+            ArrayList<LayoutEdge> tmpArr = new ArrayList<LayoutEdge>();
+            for (LayoutEdge e : n.succs) {
+                if (importantLinks.contains(e.link)) {
+                    tmpArr.add(e);
+                }
+            }
+
+            for (LayoutEdge e : tmpArr) {
+                //System.out.println("Removed " + e);
+                e.from.succs.remove(e);
+                e.to.preds.remove(e);
+            }
+        }
+
+        // #############################################################
+        // STEP 3: Assign layers
+        new AssignLayers().start();
+
+        // #############################################################
+        // STEP 4: Create dummy nodes
+        new CreateDummyNodes().start();
+
+        // #############################################################
+        // STEP 5: Crossing Reduction
+        new CrossingReduction().start();
+
+        // #############################################################
+        // STEP 7: Assign X coordinates
+        //new AssignXCoordinates().start();
+        new AssignXCoordinates2().start();
+
+        // #############################################################
+        // STEP 6: Assign Y coordinates
+        new AssignYCoordinates().start();
+
+        // #############################################################
+        // STEP 8: Write back to interface
+        new WriteResult().start();
+    }
+
+    private class WriteResult extends AlgorithmPart {
+
+        private int pointCount;
+
+        protected void run() {
+
+            HashMap<Vertex, Point> vertexPositions = new HashMap<Vertex, Point>();
+            HashMap<Link, List<Point>> linkPositions = new HashMap<Link, List<Point>>();
+            for (Vertex v : graph.getVertices()) {
+                LayoutNode n = vertexToLayoutNode.get(v);
+                assert !vertexPositions.containsKey(v);
+                vertexPositions.put(v, new Point(n.x + n.xOffset, n.y + n.yOffset));
+            }
+
+            for (LayoutNode n : nodes) {
+
+                for (LayoutEdge e : n.preds) {
+                    if (e.link != null) {
+                        ArrayList<Point> points = new ArrayList<Point>();
+
+                        Point p = new Point(e.to.x + e.relativeTo, e.to.y + e.to.yOffset);
+                        points.add(p);
+                        if (e.to.inOffsets.containsKey(e.relativeTo)) {
+                            points.add(new Point(p.x, p.y + e.to.inOffsets.get(e.relativeTo)));
+                        }
+
+                        LayoutNode cur = e.from;
+                        LayoutNode other = e.to;
+                        LayoutEdge curEdge = e;
+                        while (cur.vertex == null && cur.preds.size() != 0) {
+                            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);
+                            }
+                            points.add(new Point(cur.x + cur.width / 2, cur.y + cur.height));
+                            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);
+                            }
+                            points.add(new Point(cur.x + cur.width / 2, cur.y));
+                            assert cur.preds.size() == 1;
+                            curEdge = cur.preds.get(0);
+                            cur = curEdge.from;
+                        }
+
+                        p = new Point(cur.x + curEdge.relativeFrom, cur.y + cur.height - cur.bottomYOffset);
+                        if (curEdge.from.outOffsets.containsKey(curEdge.relativeFrom)) {
+                            points.add(new Point(p.x, p.y + curEdge.from.outOffsets.get(curEdge.relativeFrom)));
+                        }
+                        points.add(p);
+
+                        Collections.reverse(points);
+
+
+
+                        if (cur.vertex == null && cur.preds.size() == 0) {
+
+                            if (reversedLinkEndPoints.containsKey(e.link)) {
+                                for (Point p1 : reversedLinkEndPoints.get(e.link)) {
+                                    points.add(new Point(p1.x + e.to.x, p1.y + e.to.y));
+                                }
+                            }
+
+                            if (splitStartPoints.containsKey(e.link)) {
+                                points.add(0, null);
+                                points.addAll(0, splitStartPoints.get(e.link));
+
+                                //checkPoints(points);
+                                if (reversedLinks.contains(e.link)) {
+                                    Collections.reverse(points);
+                                }
+                                assert !linkPositions.containsKey(e.link);
+                                linkPositions.put(e.link, points);
+                            } else {
+                                splitEndPoints.put(e.link, points);
+                            }
+
+                        } else {
+                            if (reversedLinks.contains(e.link)) {
+                                Collections.reverse(points);
+                            }
+                            if (reversedLinkStartPoints.containsKey(e.link)) {
+                                for (Point p1 : reversedLinkStartPoints.get(e.link)) {
+                                    points.add(new Point(p1.x + cur.x, p1.y + cur.y));
+                                }
+                            }
+
+                            if (reversedLinkEndPoints.containsKey(e.link)) {
+                                for (Point p1 : reversedLinkEndPoints.get(e.link)) {
+                                    points.add(0, new Point(p1.x + other.x, p1.y + other.y));
+                                }
+                            }
+
+                            assert !linkPositions.containsKey(e.link);
+                            linkPositions.put(e.link, points);
+                        }
+                        pointCount += points.size();
+
+                        // No longer needed!
+                        e.link = null;
+                    }
+                }
+
+                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);
+                        points.add(p);
+                        if (e.from.outOffsets.containsKey(e.relativeFrom)) {
+                            points.add(new Point(p.x, p.y + e.from.outOffsets.get(e.relativeFrom)));
+                        }
+
+                        LayoutNode cur = e.to;
+                        LayoutNode other = e.from;
+                        LayoutEdge curEdge = e;
+                        while (cur.vertex == null && cur.succs.size() != 0) {
+                            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);
+                            }
+                            points.add(new Point(cur.x + cur.width / 2, cur.y));
+                            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);
+                            }
+                            points.add(new Point(cur.x + cur.width / 2, cur.y + cur.height));
+                            if (cur.succs.size() == 0) {
+                                break;
+                            }
+                            assert cur.succs.size() == 1;
+                            curEdge = cur.succs.get(0);
+                            cur = curEdge.to;
+                        }
+
+
+                        p = new Point(cur.x + curEdge.relativeTo, cur.y + cur.yOffset);
+                        points.add(p);
+                        if (curEdge.to.inOffsets.containsKey(curEdge.relativeTo)) {
+                            points.add(new Point(p.x, p.y + curEdge.to.inOffsets.get(curEdge.relativeTo)));
+                        }
+
+
+                        if (cur.succs.size() == 0 && 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));
+                                }
+                            }
+
+                            if (splitEndPoints.containsKey(e.link)) {
+                                points.add(null);
+                                points.addAll(splitEndPoints.get(e.link));
+
+                                //checkPoints(points);
+                                if (reversedLinks.contains(e.link)) {
+                                    Collections.reverse(points);
+                                }
+                                assert !linkPositions.containsKey(e.link);
+                                linkPositions.put(e.link, points);
+                            } else {
+                                splitStartPoints.put(e.link, points);
+                            }
+                        } else {
+
+                            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));
+                                }
+                            }
+                            if (reversedLinkEndPoints.containsKey(e.link)) {
+                                for (Point p1 : reversedLinkEndPoints.get(e.link)) {
+                                    points.add(new Point(p1.x + cur.x, p1.y + cur.y));
+                                }
+                            }
+                            if (reversedLinks.contains(e.link)) {
+                                Collections.reverse(points);
+                            }
+                            //checkPoints(points);
+                            assert !linkPositions.containsKey(e.link);
+                            linkPositions.put(e.link, points);
+                        }
+
+                        pointCount += points.size();
+                        e.link = null;
+                    }
+                }
+            }
+
+            int minX = Integer.MAX_VALUE;
+            int minY = Integer.MAX_VALUE;
+            for (Vertex v : vertexPositions.keySet()) {
+                Point p = vertexPositions.get(v);
+                minX = Math.min(minX, p.x);
+                minY = Math.min(minY, p.y);
+            }
+
+            for (Link l : linkPositions.keySet()) {
+                List<Point> points = linkPositions.get(l);
+                for (Point p : points) {
+                    if (p != null) {
+                        minX = Math.min(minX, p.x);
+                        minY = Math.min(minY, p.y);
+                    }
+                }
+
+            }
+
+            for (Vertex v : vertexPositions.keySet()) {
+                Point p = vertexPositions.get(v);
+                p.x -= minX;
+                p.y -= minY;
+                v.setPosition(p);
+            }
+
+            for (Link l : linkPositions.keySet()) {
+                List<Point> points = linkPositions.get(l);
+                for (Point p : points) {
+                    if (p != null) {
+                        p.x -= minX;
+                        p.y -= minY;
+                    }
+                }
+                l.setControlPoints(points);
+
+            }
+        }
+
+        @Override
+        protected void printStatistics() {
+            System.out.println("Number of nodes: " + nodes.size());
+            int edgeCount = 0;
+            for (LayoutNode n : nodes) {
+                edgeCount += n.succs.size();
+            }
+            System.out.println("Number of edges: " + edgeCount);
+            System.out.println("Number of points: " + pointCount);
+        }
+    }
+
+    private static class Segment {
+
+        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 Region region;
+    }
+    private static final Comparator<Segment> segmentComparator = new Comparator<Segment>() {
+
+        public int compare(Segment s1, Segment s2) {
+            return s1.orderNumber - s2.orderNumber;
+        }
+    };
+
+    private static class Region {
+
+        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);
+    }
+    private static final Comparator<Region> regionComparator = new Comparator<Region>() {
+
+        public int compare(Region r1, Region r2) {
+            return r1.minOrderNumber - r2.minOrderNumber;
+        }
+    };
+    private static final Comparator<LayoutNode> nodePositionComparator = new Comparator<LayoutNode>() {
+
+        public int compare(LayoutNode n1, LayoutNode n2) {
+            return n1.pos - n2.pos;
+        }
+    };
+    private static final Comparator<LayoutNode> nodeProcessingDownComparator = new Comparator<LayoutNode>() {
+
+        public int compare(LayoutNode n1, LayoutNode n2) {
+            if (n1.vertex == null) {
+                return -1;
+            }
+            if (n2.vertex == null) {
+                return 1;
+            }
+            return n1.preds.size() - n2.preds.size();
+        }
+    };
+    private static final Comparator<LayoutNode> nodeProcessingUpComparator = new Comparator<LayoutNode>() {
+
+        public int compare(LayoutNode n1, LayoutNode n2) {
+            if (n1.vertex == null) {
+                return -1;
+            }
+            if (n2.vertex == null) {
+                return 1;
+            }
+            return n1.succs.size() - n2.succs.size();
+        }
+    };
+
+    private class AssignXCoordinates2 extends AlgorithmPart {
+
+        private ArrayList<Integer>[] space;
+        private ArrayList<LayoutNode>[] downProcessingOrder;
+        private ArrayList<LayoutNode>[] upProcessingOrder;
+
+        private void initialPositions() {
+            for (LayoutNode n : nodes) {
+                n.x = space[n.layer].get(n.pos);
+            }
+        }
+
+        protected void run() {
+
+            space = new ArrayList[layers.length];
+            downProcessingOrder = new ArrayList[layers.length];
+            upProcessingOrder = new ArrayList[layers.length];
+
+            for (int i = 0; i < layers.length; i++) {
+                space[i] = new ArrayList<Integer>();
+                downProcessingOrder[i] = new ArrayList<LayoutNode>();
+                upProcessingOrder[i] = new ArrayList<LayoutNode>();
+
+                int curX = 0;
+                for (LayoutNode n : layers[i]) {
+                    space[i].add(curX);
+                    curX += n.width + xOffset;
+                    downProcessingOrder[i].add(n);
+                    upProcessingOrder[i].add(n);
+                }
+
+                Collections.sort(downProcessingOrder[i], nodeProcessingDownComparator);
+                Collections.sort(upProcessingOrder[i], nodeProcessingUpComparator);
+            }
+
+            initialPositions();
+            for (int i = 0; i < SWEEP_ITERATIONS; i++) {
+                sweepDown();
+                sweepUp();
+            }
+
+            for (int i = 0; i < SWEEP_ITERATIONS; i++) {
+                doubleSweep();
+            }
+        }
+
+        private int calculateOptimalDown(LayoutNode n) {
+
+            List<Integer> values = new ArrayList<Integer>();
+            if (n.preds.size() == 0) {
+                return n.x;
+            }
+            for (LayoutEdge e : n.preds) {
+                int cur = e.from.x + e.relativeFrom - e.relativeTo;
+                values.add(cur);
+            }
+            return median(values);
+        }
+
+        private int calculateOptimalBoth(LayoutNode n) {
+
+            List<Integer> values = new ArrayList<Integer>();
+            if (n.preds.size() == 0 + n.succs.size()) {
+                return n.x;
+            }
+            for (LayoutEdge e : n.preds) {
+                int cur = e.from.x + e.relativeFrom - e.relativeTo;
+                values.add(cur);
+            }
+
+            for (LayoutEdge e : n.succs) {
+                int cur = e.to.x + e.relativeTo - e.relativeFrom;
+                values.add(cur);
+            }
+
+            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;
+            } 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);
+            }
+        }
+
+        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() {
+            for (int i = layers.length - 1; i >= 0; i--) {
+                NodeRow r = new NodeRow(space[i]);
+                for (LayoutNode n : upProcessingOrder[i]) {
+                    int optimal = calculateOptimalUp(n);
+                    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() {
+            for (int i = layers.length - 2; i >= 0; i--) {
+                NodeRow r = new NodeRow(space[i]);
+                for (LayoutNode n : upProcessingOrder[i]) {
+                    int optimal = calculateOptimalBoth(n);
+                    r.insert(n, optimal);
+                }
+            }
+        }
+
+        private void sweepDown() {
+            for (int i = 1; i < layers.length; i++) {
+                NodeRow r = new NodeRow(space[i]);
+                for (LayoutNode n : downProcessingOrder[i]) {
+                    int optimal = calculateOptimalDown(n);
+                    r.insert(n, optimal);
+                }
+            }
+        }
+    }
+
+    private static class NodeRow {
+
+        private TreeSet<LayoutNode> treeSet;
+        private ArrayList<Integer> space;
+
+        public NodeRow(ArrayList<Integer> space) {
+            treeSet = new TreeSet<LayoutNode>(nodePositionComparator);
+            this.space = space;
+        }
+
+        public int offset(LayoutNode n1, LayoutNode n2) {
+            int v1 = space.get(n1.pos) + n1.width;
+            int v2 = space.get(n2.pos);
+            return v2 - v1;
+        }
+
+        public void insert(LayoutNode n, int pos) {
+
+            SortedSet<LayoutNode> headSet = treeSet.headSet(n);
+
+            LayoutNode leftNeighbor = null;
+            int minX = Integer.MIN_VALUE;
+            if (!headSet.isEmpty()) {
+                leftNeighbor = headSet.last();
+                minX = leftNeighbor.x + leftNeighbor.width + offset(leftNeighbor, n);
+            }
+
+            if (pos < minX) {
+                n.x = minX;
+            } else {
+
+                LayoutNode rightNeighbor = null;
+                SortedSet<LayoutNode> tailSet = treeSet.tailSet(n);
+                int maxX = Integer.MAX_VALUE;
+                if (!tailSet.isEmpty()) {
+                    rightNeighbor = tailSet.first();
+                    maxX = rightNeighbor.x - offset(n, rightNeighbor) - n.width;
+                }
+
+                if (pos > maxX) {
+                    n.x = maxX;
+                } else {
+                    n.x = pos;
+                }
+
+                assert minX <= 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>() {
+
+        public int compare(LayoutNode n1, LayoutNode n2) {
+            return n1.crossingNumber - n2.crossingNumber;
+        }
+    };
+
+    private class CrossingReduction extends AlgorithmPart {
+
+        @Override
+        public void preCheck() {
+            for (LayoutNode n : nodes) {
+                assert n.layer < layerCount;
+            }
+        }
+
+        protected void run() {
+
+            layers = new List[layerCount];
+
+            for (int i = 0; i < layerCount; i++) {
+                layers[i] = new ArrayList<LayoutNode>();
+            }
+
+
+            // Generate initial ordering
+            HashSet<LayoutNode> visited = new HashSet<LayoutNode>();
+            for (LayoutNode n : nodes) {
+                if (n.layer == 0) {
+                    layers[0].add(n);
+                    visited.add(n);
+                } else if (n.preds.size() == 0) {
+                    layers[n.layer].add(n);
+                    visited.add(n);
+                }
+            }
+
+            for (int i = 0; i < layers.length - 1; i++) {
+                for (LayoutNode n : layers[i]) {
+                    for (LayoutEdge e : n.succs) {
+                        if (!visited.contains(e.to)) {
+                            visited.add(e.to);
+                            layers[i + 1].add(e.to);
+                        }
+                    }
+                }
+            }
+
+
+            updatePositions();
+
+            initX();
+
+            // Optimize
+            for (int i = 0; i < CROSSING_ITERATIONS; i++) {
+                downSweep();
+                upSweep();
+            }
+
+        /*for(int i=0; i<CROSSING_ITERATIONS; i++) {
+        doubleSweep();
+        }*/
+        }
+
+        private void initX() {
+
+            for (int i = 0; i < layers.length; i++) {
+                updateXOfLayer(i);
+            }
+        }
+
+        private void updateXOfLayer(int index) {
+            int x = 0;
+
+            for (LayoutNode n : layers[index]) {
+                n.x = x;
+                x += n.width + X_OFFSET;
+            }
+        }
+
+        private void updatePositions() {
+
+            for (int i = 0; i < layers.length; i++) {
+                int z = 0;
+                for (LayoutNode n : layers[i]) {
+                    n.pos = z;
+                    z++;
+                }
+            }
+        }
+
+        private void downSweep() {
+
+            // Downsweep
+            for (int i = 1; i < layerCount; i++) {
+
+                for (LayoutNode n : layers[i]) {
+                    n.crossingNumber = 0;
+                }
+
+                for (LayoutNode n : layers[i]) {
+
+                    int sum = 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;
+                    }
+
+                    if (n.preds.size() > 0) {
+                        sum /= n.preds.size();
+                        n.crossingNumber = sum;
+                    //if(n.vertex == null) n.crossingNumber += layers[i].size();
+                    }
+                }
+
+
+                updateCrossingNumbers(i, true);
+                Collections.sort(layers[i], crossingNodeComparator);
+                updateXOfLayer(i);
+
+                int z = 0;
+                for (LayoutNode n : layers[i]) {
+                    n.pos = z;
+                    z++;
+                }
+            }
+        }
+
+        private void updateCrossingNumbers(int index, boolean down) {
+            for (int i = 0; i < layers[index].size(); i++) {
+                LayoutNode n = layers[index].get(i);
+                LayoutNode prev = null;
+                if (i > 0) {
+                    prev = layers[index].get(i - 1);
+                }
+                LayoutNode next = null;
+                if (i < layers[index].size() - 1) {
+                    next = layers[index].get(i + 1);
+                }
+
+                boolean cond = (n.succs.size() == 0);
+                if (down) {
+                    cond = (n.preds.size() == 0);
+                }
+
+                if (cond) {
+
+                    if (prev != null && next != null) {
+                        n.crossingNumber = (prev.crossingNumber + next.crossingNumber) / 2;
+                    } else if (prev != null) {
+                        n.crossingNumber = prev.crossingNumber;
+                    } else if (next != null) {
+                        n.crossingNumber = next.crossingNumber;
+                    }
+                }
+            }
+        }
+        /*
+        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
+            for (int i = layerCount - 2; i >= 0; i--) {
+
+                for (LayoutNode n : layers[i]) {
+                    n.crossingNumber = 0;
+                }
+
+                for (LayoutNode n : layers[i]) {
+
+                    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;
+                    }
+
+                    if (n.succs.size() > 0) {
+                        sum /= n.succs.size();
+                        n.crossingNumber = sum;
+                    //if(n.vertex == null) n.crossingNumber += layers[i].size();
+                    }
+
+                }
+
+                updateCrossingNumbers(i, false);
+                Collections.sort(layers[i], crossingNodeComparator);
+                updateXOfLayer(i);
+
+                int z = 0;
+                for (LayoutNode n : layers[i]) {
+                    n.pos = z;
+                    z++;
+                }
+            }
+        }
+
+        private int evaluate() {
+            // TODO: Implement efficient evaluate / crossing min
+            return 0;
+        }
+
+        @Override
+        public void postCheck() {
+
+            HashSet<LayoutNode> visited = new HashSet<LayoutNode>();
+            for (int i = 0; i < layers.length; i++) {
+                for (LayoutNode n : layers[i]) {
+                    assert !visited.contains(n);
+                    assert n.layer == i;
+                    visited.add(n);
+                }
+            }
+
+        }
+    }
+
+    private class AssignYCoordinates extends AlgorithmPart {
+
+        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;
+                int bottomBaseLine = 0;
+                for (LayoutNode n : layers[i]) {
+                    maxHeight = Math.max(maxHeight, n.height - n.yOffset - n.bottomYOffset);
+                    baseLine = Math.max(baseLine, n.yOffset);
+                    bottomBaseLine = Math.max(bottomBaseLine, n.bottomYOffset);
+                }
+
+                int maxXOffset = 0;
+                for (LayoutNode n : layers[i]) {
+                    if (n.vertex == null) {
+                        // Dummy node
+                        n.y = curY;
+                        n.height = maxHeight + baseLine + bottomBaseLine;
+
+                    } else {
+                        n.y = curY + baseLine + (maxHeight - (n.height - n.yOffset - n.bottomYOffset)) / 2 - n.yOffset;
+                    }
+
+                    for (LayoutEdge e : n.succs) {
+                        int curXOffset = Math.abs(n.x - e.to.x);
+                        maxXOffset = Math.max(curXOffset, maxXOffset);
+                    }
+                }
+
+                //maxLayerHeight[i] = maxHeight + baseLine + bottomBaseLine;
+
+                curY += maxHeight + baseLine + bottomBaseLine;
+                curY += layerOffset + (int) Math.sqrt(maxXOffset);
+            }
+        }
+    }
+
+    private class CreateDummyNodes extends AlgorithmPart {
+
+        private int oldNodeCount;
+
+        @Override
+        protected void preCheck() {
+            for (LayoutNode n : nodes) {
+                for (LayoutEdge e : n.succs) {
+                    assert e.from != null;
+                    assert e.from == n;
+                    assert e.from.layer < e.to.layer;
+                }
+
+                for (LayoutEdge e : n.preds) {
+                    assert e.to != null;
+                    assert e.to == n;
+                }
+            }
+        }
+
+        protected void run() {
+            oldNodeCount = nodes.size();
+
+
+            if (combine == Combine.SAME_OUTPUTS) {
+
+                Comparator<LayoutEdge> comparator = new Comparator<LayoutEdge>() {
+
+                    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);
+                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>>();
+                    for (LayoutEdge e : succs) {
+                        assert e.from.layer < e.to.layer;
+                        if (e.from.layer != e.to.layer - 1) {
+                            if (maxLayerLength != -1 && e.to.layer - e.from.layer > maxLayerLength/* && e.to.preds.size() > 1 && e.from.succs.size() > 1*/) {
+                                assert maxLayerLength > 2;
+                                e.to.preds.remove(e);
+                                e.from.succs.remove(e);
+
+                                LayoutEdge topEdge = null;
+
+                                if (combine == Combine.SAME_OUTPUTS && topNodeHash.containsKey(e.relativeFrom)) {
+                                    LayoutNode topNode = topNodeHash.get(e.relativeFrom);
+                                    topEdge = new LayoutEdge();
+                                    topEdge.relativeFrom = e.relativeFrom;
+                                    topEdge.from = e.from;
+                                    topEdge.relativeTo = topNode.width / 2;
+                                    topEdge.to = topNode;
+                                    topEdge.link = e.link;
+                                    e.from.succs.add(topEdge);
+                                    topNode.preds.add(topEdge);
+                                } else {
+
+                                    LayoutNode topNode = new LayoutNode();
+                                    topNode.layer = e.from.layer + 1;
+                                    topNode.width = DUMMY_WIDTH;
+                                    topNode.height = DUMMY_HEIGHT;
+                                    nodes.add(topNode);
+                                    topEdge = new LayoutEdge();
+                                    topEdge.relativeFrom = e.relativeFrom;
+                                    topEdge.from = e.from;
+                                    topEdge.relativeTo = topNode.width / 2;
+                                    topEdge.to = topNode;
+                                    topEdge.link = e.link;
+                                    e.from.succs.add(topEdge);
+                                    topNode.preds.add(topEdge);
+                                    topNodeHash.put(e.relativeFrom, topNode);
+                                    bottomNodeHash.put(e.relativeFrom, new HashMap<Integer, LayoutNode>());
+                                }
+
+                                HashMap<Integer, LayoutNode> hash = bottomNodeHash.get(e.relativeFrom);
+
+                                LayoutNode bottomNode = null;
+                                if (hash.containsKey(e.to.layer)) {
+                                    bottomNode = hash.get(e.to.layer);
+                                } else {
+
+                                    bottomNode = new LayoutNode();
+                                    bottomNode.layer = e.to.layer - 1;
+                                    bottomNode.width = DUMMY_WIDTH;
+                                    bottomNode.height = DUMMY_HEIGHT;
+                                    nodes.add(bottomNode);
+                                    hash.put(e.to.layer, bottomNode);
+                                }
+
+                                LayoutEdge bottomEdge = new LayoutEdge();
+                                bottomEdge.relativeTo = e.relativeTo;
+                                bottomEdge.to = e.to;
+                                bottomEdge.relativeFrom = bottomNode.width / 2;
+                                bottomEdge.from = bottomNode;
+                                bottomEdge.link = e.link;
+                                e.to.preds.add(bottomEdge);
+                                bottomEdgeHash.put(topEdge, bottomEdge);
+                                bottomNode.succs.add(bottomEdge);
+
+                            } else {
+                                Integer i = e.relativeFrom;
+                                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);
+                    for (LayoutEdge e : succs) {
+
+                        Integer i = e.relativeFrom;
+                        if (portHash.containsKey(i)) {
+
+                            List<LayoutEdge> list = portHash.get(i);
+                            Collections.sort(list, comparator);
+
+                            if (list.size() == 1) {
+                                processSingleEdge(list.get(0));
+                            } else {
+
+                                int maxLayer = list.get(0).to.layer;
+                                for (LayoutEdge curEdge : list) {
+                                    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;
+                                n.succs.add(edges[0]);
+
+                                nodes[0] = new LayoutNode();
+                                nodes[0].width = dummyWidth;
+                                nodes[0].height = dummyHeight;
+                                nodes[0].layer = n.layer + 1;
+                                nodes[0].preds.add(edges[0]);
+                                edges[0].to = nodes[0];
+                                edges[0].relativeTo = nodes[0].width / 2;
+                                for (int j = 1; j < cnt; j++) {
+                                    edges[j] = new LayoutEdge();
+                                    edges[j].from = nodes[j - 1];
+                                    edges[j].relativeFrom = nodes[j - 1].width / 2;
+                                    nodes[j - 1].succs.add(edges[j]);
+                                    nodes[j] = new LayoutNode();
+                                    nodes[j].width = dummyWidth;
+                                    nodes[j].height = dummyHeight;
+                                    nodes[j].layer = n.layer + j + 1;
+                                    nodes[j].preds.add(edges[j]);
+                                    edges[j].to = nodes[j];
+                                    edges[j].relativeTo = nodes[j].width / 2;
+                                }
+
+                                for (LayoutEdge curEdge : list) {
+                                    assert curEdge.to.layer - n.layer - 2 >= 0;
+                                    assert curEdge.to.layer - n.layer - 2 < cnt;
+                                    LayoutNode anchor = nodes[curEdge.to.layer - n.layer - 2];
+                                    anchor.succs.add(curEdge);
+                                    curEdge.from = anchor;
+                                    curEdge.relativeFrom = anchor.width / 2;
+                                    n.succs.remove(curEdge);
+                                }
+
+                            }
+
+                            portHash.remove(i);
+                        }
+                    }
+                }
+            } else if (combine == Combine.SAME_INPUTS) {
+                throw new UnsupportedOperationException("Currently not supported");
+            } else {
+                ArrayList<LayoutNode> currentNodes = new ArrayList<LayoutNode>(nodes);
+                for (LayoutNode n : currentNodes) {
+                    for (LayoutEdge e : n.succs) {
+                        processSingleEdge(e);
+                    }
+                }
+            }
+        }
+
+        private void processSingleEdge(LayoutEdge e) {
+            LayoutNode n = e.from;
+            if (e.to.layer > n.layer + 1) {
+                LayoutEdge last = e;
+                for (int i = n.layer + 1; i < last.to.layer; i++) {
+                    last = addBetween(last, i);
+                }
+            }
+        }
+
+        private LayoutEdge addBetween(LayoutEdge e, int layer) {
+            LayoutNode n = new LayoutNode();
+            n.width = dummyWidth;
+            n.height = dummyHeight;
+            n.layer = layer;
+            n.preds.add(e);
+            nodes.add(n);
+            LayoutEdge result = new LayoutEdge();
+            n.succs.add(result);
+            result.from = n;
+            result.relativeFrom = n.width / 2;
+            result.to = e.to;
+            result.relativeTo = e.relativeTo;
+            e.relativeTo = n.width / 2;
+            e.to.preds.remove(e);
+            e.to.preds.add(result);
+            e.to = n;
+            return result;
+        }
+
+        @Override
+        public void printStatistics() {
+            System.out.println("Dummy nodes created: " + (nodes.size() - oldNodeCount));
+        }
+
+        @Override
+        public void postCheck() {
+            ArrayList<LayoutNode> currentNodes = new ArrayList<LayoutNode>(nodes);
+            for (LayoutNode n : currentNodes) {
+                for (LayoutEdge e : n.succs) {
+                    assert e.from.layer == e.to.layer - 1;
+                }
+            }
+
+            for (int i = 0; i < layers.length; i++) {
+                assert layers[i].size() > 0;
+                for (LayoutNode n : layers[i]) {
+                    assert n.layer == i;
+                }
+            }
+        }
+    }
+
+    private class AssignLayers extends AlgorithmPart {
+
+        @Override
+        public void preCheck() {
+            for (LayoutNode n : nodes) {
+                assert n.layer == -1;
+            }
+        }
+
+        protected void run() {
+            HashSet<LayoutNode> set = new HashSet<LayoutNode>();
+            for (LayoutNode n : nodes) {
+                if (n.preds.size() == 0) {
+                    set.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) {
+
+                    for (LayoutEdge se : n.succs) {
+                        LayoutNode s = se.to;
+                        if (!newSet.contains(s) && !failed.contains(s)) {
+                            boolean ok = true;
+                            for (LayoutEdge pe : s.preds) {
+                                LayoutNode p = pe.from;
+                                if (p.layer == -1) {
+                                    ok = false;
+                                    break;
+                                }
+                            }
+
+                            if (ok) {
+                                newSet.add(s);
+                            } else {
+                                failed.add(s);
+                            }
+                        }
+                    }
+
+                }
+
+                for (LayoutNode n : newSet) {
+                    n.layer = z;
+                }
+
+                // Swap sets
+                HashSet<LayoutNode> tmp = set;
+                set = newSet;
+                newSet = tmp;
+                z += minLayerDifference;
+            }
+
+            optimize(set);
+
+            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;
+            }
+        }
+
+        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) {
+                assert n.layer >= 0;
+                assert n.layer < layerCount;
+                for (LayoutEdge e : n.succs) {
+                    assert e.from.layer < e.to.layer;
+                }
+            }
+        }
+    }
+
+    private class ReverseEdges extends AlgorithmPart {
+
+        private HashSet<LayoutNode> visited;
+        private HashSet<LayoutNode> active;
+
+        protected void run() {
+
+            // Remove self-edges, TODO: Special treatment
+            for (LayoutNode node : nodes) {
+                ArrayList<LayoutEdge> succs = new ArrayList<LayoutEdge>(node.succs);
+                for (LayoutEdge e : succs) {
+                    assert e.from == node;
+                    if (e.to == node) {
+                        node.succs.remove(e);
+                        node.preds.remove(e);
+                    }
+                }
+            }
+
+            // Reverse inputs of roots
+            for (LayoutNode node : nodes) {
+                if (node.vertex.isRoot()) {
+                    boolean ok = true;
+                    for (LayoutEdge e : node.preds) {
+                        if (e.from.vertex.isRoot()) {
+                            ok = false;
+                            break;
+                        }
+                    }
+                    if (ok) {
+                        reverseAllInputs(node);
+                    }
+                }
+            }
+
+
+            // Start DFS and reverse back edges
+            visited = new HashSet<LayoutNode>();
+            active = new HashSet<LayoutNode>();
+            for (LayoutNode node : nodes) {
+                DFS(node);
+            }
+
+
+            for (LayoutNode node : nodes) {
+
+                SortedSet<Integer> reversedDown = new TreeSet<Integer>();
+
+                for (LayoutEdge e : node.succs) {
+                    if (reversedLinks.contains(e.link)) {
+                        reversedDown.add(e.relativeFrom);
+                    }
+                }
+
+
+                SortedSet<Integer> reversedUp = null;
+                if (reversedDown.size() == 0) {
+                    reversedUp = new TreeSet<Integer>(Collections.reverseOrder());
+                } else {
+                    reversedUp = new TreeSet<Integer>();
+                }
+
+                for (LayoutEdge e : node.preds) {
+                    if (reversedLinks.contains(e.link)) {
+                        reversedUp.add(e.relativeTo);
+                    }
+                }
+
+                final int offset = X_OFFSET + DUMMY_WIDTH;
+
+                int curX = 0;
+                int curWidth = node.width + reversedDown.size() * offset;
+                for (int pos : reversedDown) {
+                    ArrayList<LayoutEdge> reversedSuccs = new ArrayList<LayoutEdge>();
+                    for (LayoutEdge e : node.succs) {
+                        if (e.relativeFrom == pos && reversedLinks.contains(e.link)) {
+                            reversedSuccs.add(e);
+                            e.relativeFrom = curWidth;
+                        }
+                    }
+
+                    ArrayList<Point> startPoints = new ArrayList<Point>();
+                    startPoints.add(new Point(curWidth, curX));
+                    startPoints.add(new Point(pos, curX));
+                    startPoints.add(new Point(pos, reversedDown.size() * offset));
+                    for (LayoutEdge e : reversedSuccs) {
+                        reversedLinkStartPoints.put(e.link, startPoints);
+                    }
+
+                    node.inOffsets.put(pos, -curX);
+                    curX += offset;
+                    node.height += offset;
+                    node.yOffset += offset;
+                    curWidth -= offset;
+                }
+                node.width += reversedDown.size() * offset;
+
+                if (reversedDown.size() == 0) {
+                    curX = offset;
+                } else {
+                    curX = -offset;
+                }
+
+                curX = 0;
+                int minX = 0;
+                if (reversedDown.size() != 0) {
+                    minX = -offset * reversedUp.size();
+                }
+
+                int oldNodeHeight = node.height;
+                for (int pos : reversedUp) {
+                    ArrayList<LayoutEdge> reversedPreds = new ArrayList<LayoutEdge>();
+                    for (LayoutEdge e : node.preds) {
+                        if (e.relativeTo == pos && reversedLinks.contains(e.link)) {
+                            if (reversedDown.size() == 0) {
+                                e.relativeTo = node.width + offset;
+                            } else {
+                                e.relativeTo = curX - offset;
+                            }
+
+                            reversedPreds.add(e);
+                        }
+                    }
+                    node.height += offset;
+                    ArrayList<Point> endPoints = new ArrayList<Point>();
+
+                    if (reversedDown.size() == 0) {
+
+                        curX += offset;
+                        node.width += offset;
+                        endPoints.add(new Point(node.width, node.height));
+
+                    } else {
+                        curX -= offset;
+                        node.width += offset;
+                        endPoints.add(new Point(curX, node.height));
+                    }
+
+                    node.outOffsets.put(pos - minX, curX);
+                    curX += offset;
+                    node.bottomYOffset += offset;
+
+
+                    endPoints.add(new Point(pos, node.height));
+                    endPoints.add(new Point(pos, oldNodeHeight));
+                    for (LayoutEdge e : reversedPreds) {
+                        reversedLinkEndPoints.put(e.link, endPoints);
+                    }
+                }
+
+
+                if (minX < 0) {
+                    for (LayoutEdge e : node.preds) {
+                        e.relativeTo -= minX;
+                    }
+
+                    for (LayoutEdge e : node.succs) {
+                        e.relativeFrom -= minX;
+                    }
+
+                    node.xOffset = -minX;
+                    node.width += -minX;
+                }
+            }
+
+        }
+
+        private void DFS(LayoutNode startNode) {
+            if (visited.contains(startNode)) {
+                return;
+            }
+
+            Stack<LayoutNode> stack = new Stack<LayoutNode>();
+            stack.push(startNode);
+
+            while (!stack.empty()) {
+                LayoutNode node = stack.pop();
+
+                if (visited.contains(node)) {
+                    // Node no longer active
+                    active.remove(node);
+                    continue;
+                }
+
+                // Repush immediately to know when no longer active
+                stack.push(node);
+                visited.add(node);
+                active.add(node);
+
+                ArrayList<LayoutEdge> succs = new ArrayList<LayoutEdge>(node.succs);
+                for (LayoutEdge e : succs) {
+                    if (active.contains(e.to)) {
+                        assert visited.contains(e.to);
+                        // Encountered back edge
+                        reverseEdge(e);
+                    } else if (!visited.contains(e.to) && (linksToFollow.size() == 0 || linksToFollow.contains(e.link))) {
+                        stack.push(e.to);
+                    }
+                }
+            }
+        }
+
+        private void reverseAllInputs(LayoutNode node) {
+            for (LayoutEdge e : node.preds) {
+                assert !reversedLinks.contains(e.link);
+                reversedLinks.add(e.link);
+                node.succs.add(e);
+                e.from.preds.add(e);
+                e.from.succs.remove(e);
+                int oldRelativeFrom = e.relativeFrom;
+                int oldRelativeTo = e.relativeTo;
+                e.to = e.from;
+                e.from = node;
+                e.relativeFrom = oldRelativeTo;
+                e.relativeTo = oldRelativeFrom;
+            }
+            node.preds.clear();
+        }
+
+        private void reverseEdge(LayoutEdge e) {
+            assert !reversedLinks.contains(e.link);
+            reversedLinks.add(e.link);
+
+            LayoutNode oldFrom = e.from;
+            LayoutNode oldTo = e.to;
+            int oldRelativeFrom = e.relativeFrom;
+            int oldRelativeTo = e.relativeTo;
+
+            e.from = oldTo;
+            e.to = oldFrom;
+            e.relativeFrom = oldRelativeTo;
+            e.relativeTo = oldRelativeFrom;
+
+            oldFrom.succs.remove(e);
+            oldFrom.preds.add(e);
+            oldTo.preds.remove(e);
+            oldTo.succs.add(e);
+        }
+
+        @Override
+        public void postCheck() {
+
+            for (LayoutNode n : nodes) {
+
+                HashSet<LayoutNode> curVisited = new HashSet<LayoutNode>();
+                Queue<LayoutNode> queue = new LinkedList<LayoutNode>();
+                for (LayoutEdge e : n.succs) {
+                    LayoutNode s = e.to;
+                    queue.add(s);
+                    curVisited.add(s);
+                }
+
+                while (!queue.isEmpty()) {
+                    LayoutNode curNode = queue.remove();
+
+                    for (LayoutEdge e : curNode.succs) {
+                        assert e.to != n;
+                        if (!curVisited.contains(e.to)) {
+                            queue.add(e.to);
+                            curVisited.add(e.to);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    private Comparator<Link> linkComparator = new Comparator<Link>() {
+
+        public int compare(Link l1, Link l2) {
+
+            int result = l1.getFrom().getVertex().compareTo(l2.getFrom().getVertex());
+            if (result != 0) {
+                return result;
+            }
+            result = l1.getTo().getVertex().compareTo(l2.getTo().getVertex());
+            if (result != 0) {
+                return result;
+            }
+            result = l1.getFrom().getRelativePosition().x - l2.getFrom().getRelativePosition().x;
+            if (result != 0) {
+                return result;
+            }
+            result = l1.getTo().getRelativePosition().x - l2.getTo().getRelativePosition().x;
+            return result;
+        }
+    };
+
+    private class BuildDatastructure extends AlgorithmPart {
+
+        protected void run() {
+            // Set up nodes
+            List<Vertex> vertices = new ArrayList<Vertex>(graph.getVertices());
+            Collections.sort(vertices);
+
+            for (Vertex v : vertices) {
+                LayoutNode node = new LayoutNode();
+                Dimension size = v.getSize();
+                node.width = (int) size.getWidth();
+                node.height = (int) size.getHeight();
+                node.vertex = v;
+                nodes.add(node);
+                vertexToLayoutNode.put(v, node);
+            }
+
+            // Set up edges
+            List<Link> links = new ArrayList<Link>(graph.getLinks());
+            Collections.sort(links, linkComparator);
+            for (Link l : links) {
+                LayoutEdge edge = new LayoutEdge();
+                assert vertexToLayoutNode.containsKey(l.getFrom().getVertex());
+                assert vertexToLayoutNode.containsKey(l.getTo().getVertex());
+                edge.from = vertexToLayoutNode.get(l.getFrom().getVertex());
+                edge.to = vertexToLayoutNode.get(l.getTo().getVertex());
+                edge.relativeFrom = l.getFrom().getRelativePosition().x;
+                edge.relativeTo = l.getTo().getRelativePosition().x;
+                edge.link = l;
+                edge.from.succs.add(edge);
+                edge.to.preds.add(edge);
+            //assert edge.from != edge.to; // No self-loops allowed
+            }
+
+            for (Link l : importantLinks) {
+                if (!vertexToLayoutNode.containsKey(l.getFrom().getVertex()) ||
+                        vertexToLayoutNode.containsKey(l.getTo().getVertex())) {
+                    continue;
+                }
+                LayoutNode from = vertexToLayoutNode.get(l.getFrom().getVertex());
+                LayoutNode to = vertexToLayoutNode.get(l.getTo().getVertex());
+                for (LayoutEdge e : from.succs) {
+                    if (e.to == to) {
+                        linksToFollow.add(e.link);
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void postCheck() {
+
+            assert vertexToLayoutNode.keySet().size() == nodes.size();
+            assert nodes.size() == graph.getVertices().size();
+
+            for (Vertex v : graph.getVertices()) {
+
+                LayoutNode node = vertexToLayoutNode.get(v);
+                assert node != null;
+
+                for (LayoutEdge e : node.succs) {
+                    assert e.from == node;
+                }
+
+                for (LayoutEdge e : node.preds) {
+                    assert e.to == node;
+                }
+
+            }
+        }
+    }
+
+    public void doRouting(LayoutGraph graph) {
+    // Do nothing for now
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/InterClusterConnection.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.hierarchicallayout;
+
+import com.sun.hotspot.igv.layout.Link;
+import com.sun.hotspot.igv.layout.Port;
+import java.awt.Point;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InterClusterConnection implements Link {
+
+    private Port inputSlot;
+    private Port outputSlot;
+    private List<Point> intermediatePoints;
+    private ClusterInputSlotNode inputSlotNode;
+    private ClusterOutputSlotNode outputSlotNode;
+
+    public InterClusterConnection(ClusterOutputSlotNode outputSlotNode, ClusterInputSlotNode inputSlotNode) {
+        this.outputSlotNode = outputSlotNode;
+        this.inputSlotNode = inputSlotNode;
+        this.inputSlot = inputSlotNode.getInputSlot();
+        this.outputSlot = outputSlotNode.getOutputSlot();
+        intermediatePoints = new ArrayList<Point>();
+    }
+
+    public ClusterOutputSlotNode getOutputSlotNode() {
+        return outputSlotNode;
+    }
+
+    public Port getTo() {
+        return inputSlot;
+    }
+
+    public Port getFrom() {
+        return outputSlot;
+    }
+
+    public void setControlPoints(List<Point> p) {
+        this.intermediatePoints = p;
+    }
+
+    public List<Point> getControlPoints() {
+        return intermediatePoints;
+    }
+
+    @Override
+    public String toString() {
+        return "InterClusterConnection[from=" + getFrom() + ", to=" + getTo() + "]";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Node.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.hierarchicallayout;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Node<N, E> {
+
+    private N data;
+    private List<Edge<N, E>> inEdges;
+    private List<Edge<N, E>> outEdges;
+    private boolean visited;
+    private boolean active;
+    private boolean reachable;
+    private Graph<N, E> graph;
+
+    protected boolean isVisited() {
+        return visited;
+    }
+
+    protected void setVisited(boolean b) {
+        visited = b;
+    }
+
+    protected boolean isReachable() {
+        return reachable;
+    }
+
+    protected void setReachable(boolean b) {
+        reachable = b;
+    }
+
+    protected boolean isActive() {
+        return active;
+    }
+
+    protected void setActive(boolean b) {
+        active = b;
+    }
+
+    public int getInDegree() {
+        return getInDegree(true);
+    }
+
+    public int getInDegree(boolean countSelfLoops) {
+        if (countSelfLoops) {
+            return inEdges.size();
+        } else {
+            int cnt = 0;
+            for (Edge<N, E> e : inEdges) {
+                if (e.getSource() != this) {
+                    cnt++;
+                }
+            }
+            return cnt;
+        }
+    }
+
+    public int getOutDegree() {
+        return outEdges.size();
+    }
+
+    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>>();
+    }
+
+    protected void addInEdge(Edge<N, E> e) {
+        inEdges.add(e);
+    }
+
+    public Graph<N, E> getGraph() {
+        return graph;
+    }
+
+    protected void addOutEdge(Edge<N, E> e) {
+        outEdges.add(e);
+    }
+
+    protected void removeInEdge(Edge<N, E> e) {
+        //assert inEdges.contains(e);
+        inEdges.remove(e);
+    }
+
+    protected void removeOutEdge(Edge<N, E> e) {
+        //assert outEdges.contains(e);
+        outEdges.remove(e);
+    }
+
+    public List<Edge<N, E>> getInEdges() {
+        return Collections.unmodifiableList(inEdges);
+    }
+
+    public List<Edge<N, E>> getOutEdges() {
+        return Collections.unmodifiableList(outEdges);
+    }
+
+    public List<Node<N, E>> getSuccessors() {
+        ArrayList<Node<N, E>> succ = new ArrayList<Node<N, E>>();
+        for (Edge<N, E> e : getOutEdges()) {
+            Node<N, E> n = e.getDest();
+            if (!succ.contains(n)) {
+                succ.add(n);
+            }
+        }
+        return succ;
+    }
+
+    public List<Node<N, E>> getPredecessors() {
+        ArrayList<Node<N, E>> pred = new ArrayList<Node<N, E>>();
+        for (Edge<N, E> e : getInEdges()) {
+            Node<N, E> n = e.getSource();
+            if (!pred.contains(n)) {
+                pred.add(n);
+            }
+        }
+        return pred;
+    }
+
+    public N getData() {
+        return data;
+    }
+
+    public void setData(N d) {
+        data = d;
+    }
+
+    @Override
+    public String toString() {
+        return "Node: " + data;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/OldHierarchicalLayoutManager.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1222 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Timing.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.hierarchicallayout;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Timing {
+
+    private long lastValue;
+    private long sum;
+    private String name;
+
+    public Timing(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String toString() {
+        long val = sum;
+        if (lastValue != 0) {
+            // Timer running
+            long newValue = System.nanoTime();
+            val += (newValue - lastValue);
+        }
+        return "Timing for " + name + " is: " + val / 1000000 + " ms";
+    }
+
+    public void print() {
+        System.out.println(toString());
+    }
+
+    public void start() {
+        lastValue = System.nanoTime();
+    }
+
+    public void stop() {
+        if (lastValue == 0) {
+            throw new IllegalStateException("You must call start before stop");
+        }
+        long newValue = System.nanoTime();
+        sum += newValue - lastValue;
+        lastValue = 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/build.xml	Wed Jul 05 16:38:46 2017 +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.layout" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.layout.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.layout
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/layout/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.layout-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=cb0889d9
+build.xml.script.CRC32=d65fccb9
+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=cb0889d9
+nbproject/build-impl.xml.script.CRC32=7f82736d
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,14 @@
+<?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.layout</code-name-base>
+            <suite-component/>
+            <module-dependencies/>
+            <public-packages>
+                <package>com.sun.hotspot.igv.layout</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Layout
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Cluster.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.layout;
+
+import java.awt.Rectangle;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface Cluster extends Comparable<Cluster> {
+
+    public Cluster getOuter();
+
+    public void setBounds(Rectangle r);
+
+    public Set<? extends Cluster> getSuccessors();
+
+    public Set<? extends Cluster> getPredecessors();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,202 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.layout;
+
+import java.util.HashSet;
+import java.util.Hashtable;
+import java.util.Set;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class LayoutGraph {
+
+    private Set<? extends Link> links;
+    private SortedSet<Vertex> vertices;
+    private Hashtable<Vertex, Set<Port>> inputPorts;
+    private Hashtable<Vertex, Set<Port>> outputPorts;
+    private Hashtable<Port, Set<Link>> portLinks;
+
+    public LayoutGraph(Set<? extends Link> links) {
+        this(links, new HashSet<Vertex>());
+    }
+
+    public LayoutGraph(Set<? extends Link> links, Set<? extends Vertex> additionalVertices) {
+        this.links = links;
+        assert verify();
+
+        vertices = new TreeSet<Vertex>();
+        portLinks = new Hashtable<Port, Set<Link>>();
+        inputPorts = new Hashtable<Vertex, Set<Port>>();
+        outputPorts = new Hashtable<Vertex, Set<Port>>();
+
+        for (Link l : links) {
+            Port p = l.getFrom();
+            Port p2 = l.getTo();
+            Vertex v1 = p.getVertex();
+            Vertex v2 = p2.getVertex();
+
+            if (!vertices.contains(v1)) {
+
+                outputPorts.put(v1, new HashSet<Port>(1));
+                inputPorts.put(v1, new HashSet<Port>(3));
+                vertices.add(v1);
+                assert vertices.contains(v1);
+            }
+
+            if (!vertices.contains(v2)) {
+                vertices.add(v2);
+                assert vertices.contains(v2);
+                outputPorts.put(v2, new HashSet<Port>(1));
+                inputPorts.put(v2, new HashSet<Port>(3));
+            }
+
+            if (!portLinks.containsKey(p)) {
+                HashSet<Link> hashSet = new HashSet<Link>(3);
+                portLinks.put(p, hashSet);
+            }
+
+            if (!portLinks.containsKey(p2)) {
+                portLinks.put(p2, new HashSet<Link>(3));
+            }
+
+            outputPorts.get(v1).add(p);
+            inputPorts.get(v2).add(p2);
+
+            portLinks.get(p).add(l);
+            portLinks.get(p2).add(l);
+        }
+
+        for (Vertex v : additionalVertices) {
+            if (!vertices.contains(v)) {
+                outputPorts.put(v, new HashSet<Port>(1));
+                inputPorts.put(v, new HashSet<Port>(3));
+                vertices.add(v);
+                vertices.contains(v);
+            }
+        }
+    }
+
+    public Set<Port> getInputPorts(Vertex v) {
+        return this.inputPorts.get(v);
+    }
+
+    public Set<Port> getOutputPorts(Vertex v) {
+        return this.outputPorts.get(v);
+    }
+
+    public Set<Link> getPortLinks(Port p) {
+        return portLinks.get(p);
+    }
+
+    public Set<? extends Link> getLinks() {
+        return links;
+    }
+
+    public boolean verify() {
+        return true;
+    }
+
+    public SortedSet<Vertex> getVertices() {
+        return vertices;
+    }
+
+    private void markNotRoot(Set<Vertex> notRootSet, Vertex v, Vertex startingVertex) {
+
+        if (notRootSet.contains(v)) {
+            return;
+        }
+        if (v != startingVertex) {
+            notRootSet.add(v);
+        }
+        Set<Port> outPorts = getOutputPorts(v);
+        for (Port p : outPorts) {
+            Set<Link> portLinks = getPortLinks(p);
+            for (Link l : portLinks) {
+                Port other = l.getTo();
+                Vertex otherVertex = other.getVertex();
+                if (otherVertex != startingVertex) {
+                    markNotRoot(notRootSet, otherVertex, startingVertex);
+                }
+            }
+        }
+    }
+
+    // Returns a set of vertices with the following properties:
+    // - All Vertices in the set startingRoots are elements of the set.
+    // - When starting a DFS at every vertex in the set, every vertex of the
+    //   whole graph is visited.
+    public Set<Vertex> findRootVertices(Set<Vertex> startingRoots) {
+
+        Set<Vertex> notRootSet = new HashSet<Vertex>();
+        for (Vertex v : startingRoots) {
+            if (!notRootSet.contains(v)) {
+                markNotRoot(notRootSet, v, v);
+            }
+        }
+
+        Set<Vertex> tmpVertices = getVertices();
+        for (Vertex v : tmpVertices) {
+            if (!notRootSet.contains(v)) {
+                if (this.getInputPorts(v).size() == 0) {
+                    markNotRoot(notRootSet, v, v);
+                }
+            }
+        }
+
+        for (Vertex v : tmpVertices) {
+            if (!notRootSet.contains(v)) {
+                markNotRoot(notRootSet, v, v);
+            }
+        }
+
+        Set<Vertex> result = new HashSet<Vertex>();
+        for (Vertex v : tmpVertices) {
+            if (!notRootSet.contains(v)) {
+                result.add(v);
+            }
+        }
+        assert tmpVertices.size() == 0 || result.size() > 0;
+        return result;
+    }
+
+    public Set<Vertex> findRootVertices() {
+        return findRootVertices(new HashSet<Vertex>());
+    }
+
+    public SortedSet<Cluster> getClusters() {
+
+        SortedSet<Cluster> clusters = new TreeSet<Cluster>();
+        for (Vertex v : getVertices()) {
+            if (v.getCluster() != null) {
+                clusters.add(v.getCluster());
+            }
+        }
+
+        return clusters;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutManager.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.layout;
+
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface LayoutManager {
+
+    public void doLayout(LayoutGraph graph);
+
+    public void doLayout(LayoutGraph graph, Set<? extends Vertex> firstLayerHint, Set<? extends Vertex> lastLayerHint, Set<? extends Link> importantLinks);
+
+    public void doRouting(LayoutGraph graph);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Link.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.layout;
+
+import java.awt.Point;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface Link {
+
+    public Port getFrom();
+
+    public Port getTo();
+
+    public List<Point> getControlPoints();
+
+    public void setControlPoints(List<Point> list);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Port.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.layout;
+
+import java.awt.Point;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface Port {
+
+    public Vertex getVertex();
+
+    public Point getRelativePosition();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Vertex.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.layout;
+
+import java.awt.Dimension;
+import java.awt.Point;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface Vertex extends Comparable<Vertex> {
+
+    public Cluster getCluster();
+
+    public Dimension getSize();
+
+    public Point getPosition();
+
+    public void setPosition(Point p);
+
+    public boolean isRoot();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/build.xml	Wed Jul 05 16:38:46 2017 +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.connection" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.connection.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.connection
+OpenIDE-Module-Layer: com/sun/hotspot/igv/connection/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/connection/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.connection-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,55 @@
+<?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.connection</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.settings</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>1.0</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.1.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.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.10.1.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.connection</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupReceiver	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+com.sun.hotspot.igv.connection.Server
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=NetworkConnection
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Client.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,96 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+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.serialization.Parser;
+import com.sun.hotspot.igv.data.Properties.RegexpPropertyMatcher;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.Socket;
+import javax.swing.JTextField;
+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 {
+
+    private Socket socket;
+    private JTextField networkTextField;
+    private GroupCallback callback;
+
+    public Client(Socket socket, JTextField networkTextField, GroupCallback callback) {
+        this.callback = callback;
+        this.socket = socket;
+        this.networkTextField = networkTextField;
+    }
+
+    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();
+                }
+            } else {
+                socket.getOutputStream().write('n');
+            }
+
+            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');
+            }
+        } catch (IOException e) {
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Server.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,145 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+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.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.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;
+
+/**
+ *
+ * @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;
+    private int port;
+    private Runnable serverRunnable;
+
+    public Component init(GroupCallback callback) {
+
+        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());
+    }
+
+    public void preferenceChange(PreferenceChangeEvent e) {
+
+        int curPort = Integer.parseInt(Settings.get().get(Settings.PORT, Settings.PORT_DEFAULT));
+        if (curPort != port) {
+            initializeNetwork();
+        }
+    }
+
+    private void initializeNetwork() {
+
+        int curPort = Integer.parseInt(Settings.get().get(Settings.PORT, 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);
+            DialogDisplayer.getDefault().notifyLater(message);
+            return;
+        }
+
+        Runnable runnable = new Runnable() {
+
+            public void run() {
+                while (true) {
+                    try {
+                        Socket clientSocket = serverSocket.accept();
+                        if (serverRunnable != this) {
+                            clientSocket.close();
+                            return;
+                        }
+                        RequestProcessor.getDefault().post(new Client(clientSocket, networkTextField, Server.this), 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);
+                        DialogDisplayer.getDefault().notifyLater(message);
+                        return;
+                    }
+                }
+            }
+        };
+
+        serverRunnable = runnable;
+
+        RequestProcessor.getDefault().post(runnable, 0, Thread.MAX_PRIORITY);
+    }
+
+    public void started(final Group g) {
+        SwingUtilities.invokeLater(new Runnable() {
+
+            public void run() {
+                callback.started(g);
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/layer.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,4 @@
+<?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/README	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,45 @@
+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.0 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 whit NetBeans 6 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.1 if you change the required
+modules to be platform8 instead of platform7.  The tool could run on
+JDK 1.5 with some reworking of the how the JavaScript support is
+enabled but currently it requires some tweaking of the setup.  This
+will be fixed in a later setup.
+
+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/RhinoScriptEngineProxy/build.xml	Wed Jul 05 16:38:46 2017 +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.rhino" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.rhino.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,6 @@
+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
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,31 @@
+<?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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+com.sun.hotspot.igv.rhino.RhinoScriptEngine
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=RhinoScriptEngineProxy
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/RhinoScriptEngine.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,85 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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) {
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/layer.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,4 @@
+<?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/ServerCompiler/build.xml	Wed Jul 05 16:38:46 2017 +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.servercompilerscheduler" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.servercompilerscheduler.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.servercompiler
+OpenIDE-Module-Layer: com/sun/hotspot/igv/servercompiler/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/servercompiler/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.servercompilerscheduler-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=d1360a65
+build.xml.script.CRC32=a9d94ef8
+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=d1360a65
+nbproject/build-impl.xml.script.CRC32=52847236
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,21 @@
+<?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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupOrganizer	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+com.sun.hotspot.igv.servercompiler.JavaGroupOrganizer
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/META-INF/services/com.sun.hotspot.igv.data.services.Scheduler	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+com.sun.hotspot.igv.servercompiler.ServerCompilerScheduler
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=ServerCompiler
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/JavaGroupOrganizer.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,200 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+        }
+    };
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/ServerCompilerScheduler.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,597 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.hotspot.igv.servercompiler;
+
+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.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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ServerCompilerScheduler implements Scheduler {
+
+    private static class Node {
+
+        public InputNode inputNode;
+        public Set<Node> succs = new HashSet<Node>();
+        public List<Node> preds = new ArrayList<Node>();
+        public InputBlock block;
+        public boolean isBlockProjection;
+        public boolean isBlockStart;
+    }
+    private InputGraph graph;
+    private Collection<Node> nodes;
+    private Map<InputNode, Node> inputNodeToNode;
+    private Vector<InputBlock> blocks;
+    private Map<InputBlock, InputBlock> dominatorMap;
+    private Map<InputBlock, Integer> blockIndex;
+    private InputBlock[][] commonDominator;
+    private static final Comparator<InputEdge> edgeComparator = new Comparator<InputEdge>() {
+
+        public int compare(InputEdge o1, InputEdge o2) {
+            return o1.getToIndex() - o2.getToIndex();
+        }
+    };
+
+    public void buildBlocks() {
+
+        blocks = new Vector<InputBlock>();
+        Node root = findRoot();
+        if (root == null) {
+            return;
+        }
+        Stack<Node> stack = new Stack<Node>();
+        Set<Node> visited = new HashSet<Node>();
+        stack.add(root);
+        int blockCount = 0;
+        InputBlock rootBlock = null;
+
+
+        while (!stack.isEmpty()) {
+            Node proj = stack.pop();
+            Node parent = proj;
+            if (proj.isBlockProjection && proj.preds.size() > 0) {
+                parent = proj.preds.get(0);
+            }
+
+            if (!visited.contains(parent)) {
+                visited.add(parent);
+                InputBlock block = new InputBlock(graph, "" + blockCount);
+                blocks.add(block);
+                if (parent == root) {
+                    rootBlock = block;
+                }
+                blockCount++;
+                parent.block = block;
+                if (proj != parent && proj.succs.size() == 1 && proj.succs.contains(root)) {
+                    // Special treatment of Halt-nodes
+                    proj.block = block;
+                }
+
+                Node p = proj;
+                do {
+                    if (p.preds.size() == 0 || p.preds.get(0) == null) {
+                        p = parent;
+                        break;
+                    }
+                    p = p.preds.get(0);
+
+                    if (p.block == null) {
+                        p.block = block;
+                    }
+                } while (!p.isBlockProjection && !p.isBlockStart);
+
+                if (block != rootBlock) {
+                    for (Node n : p.preds) {
+                        if (n != null && n != p) {
+                            if (n.isBlockProjection) {
+                                n = n.preds.get(0);
+                            }
+                            if (n.block != null) {
+                                n.block.addSuccessor(block);
+                            }
+                        }
+                    }
+                }
+
+                for (Node n : parent.succs) {
+                    if (n != root && n.isBlockProjection) {
+                        for (Node n2 : n.succs) {
+
+                            if (n2 != parent && n2.block != null && n2.block != rootBlock) {
+                                block.addSuccessor(n2.block);
+                            }
+                        }
+                    } else {
+                        if (n != parent && n.block != null && n.block != rootBlock) {
+                            block.addSuccessor(n.block);
+                        }
+                    }
+                }
+
+                int num_preds = p.preds.size();
+                int bottom = -1;
+                if (isRegion(p) || isPhi(p)) {
+                    bottom = 0;
+                }
+
+                int pushed = 0;
+                for (int i = num_preds - 1; i > bottom; i--) {
+                    if (p.preds.get(i) != null && p.preds.get(i) != p) {
+                        stack.push(p.preds.get(i));
+                        pushed++;
+                    }
+                }
+
+                if (pushed == 0 && p == root) {
+                // TODO: special handling when root backedges are not built yet
+                }
+            }
+        }
+
+        for (Node n : nodes) {
+            InputBlock block = n.block;
+            if (block != null) {
+                block.addNode(n.inputNode.getId());
+            }
+        }
+
+        int z = 0;
+        blockIndex = new HashMap<InputBlock, Integer>();
+        for (InputBlock b : blocks) {
+            blockIndex.put(b, z);
+            z++;
+        }
+    }
+
+    private String getBlockName(InputNode n) {
+        return n.getProperties().get("block");
+    }
+
+    public Collection<InputBlock> schedule(InputGraph graph) {
+        if (graph.getBlocks().size() > 0) {
+            Collection<InputNode> tmpNodes = new ArrayList<InputNode>(graph.getNodes());
+            for (InputNode n : tmpNodes) {
+                String block = getBlockName(n);
+                if (graph.getBlock(n) == null) {
+                    graph.getBlock(block).addNode(n);
+                    assert graph.getBlock(n) != null;
+                }
+            }
+            return graph.getBlocks();
+        } else {
+            nodes = new ArrayList<Node>();
+            inputNodeToNode = new HashMap<InputNode, Node>();
+
+            this.graph = graph;
+            buildUpGraph();
+            buildBlocks();
+            buildDominators();
+            buildCommonDominators();
+            scheduleLatest();
+
+            for (InputNode n : graph.getNodes()) {
+                assert graph.getBlock(n) != null;
+            }
+
+            return blocks;
+        }
+    }
+
+    public void scheduleLatest() {
+
+
+        Node root = findRoot();
+
+        // Mark all nodes reachable in backward traversal from root
+        Set<Node> reachable = new HashSet<Node>();
+        reachable.add(root);
+        Stack<Node> stack = new Stack<Node>();
+        stack.push(root);
+        while (!stack.isEmpty()) {
+            Node cur = stack.pop();
+            for (Node n : cur.preds) {
+                if (!reachable.contains(n)) {
+                    reachable.add(n);
+                    stack.push(n);
+                }
+            }
+        }
+
+        Set<Node> unscheduled = new HashSet<Node>();
+        for (Node n : this.nodes) {
+            if (n.block == null && reachable.contains(n)) {
+                unscheduled.add(n);
+            }
+        }
+
+        while (unscheduled.size() > 0) {
+            boolean progress = false;
+
+            Set<Node> newUnscheduled = new HashSet<Node>();
+            for (Node n : unscheduled) {
+
+                InputBlock block = null;
+                if (this.isPhi(n) && n.preds.get(0) != null) {
+                    // Phi nodes in same block as region nodes
+                    block = n.preds.get(0).block;
+                } else {
+                    for (Node s : n.succs) {
+                        if (reachable.contains(s)) {
+                            if (s.block == null) {
+                                block = null;
+                                break;
+                            } else {
+                                if (block == null) {
+                                    block = s.block;
+                                } else {
+                                    block = commonDominator[this.blockIndex.get(block)][blockIndex.get(s.block)];
+                                }
+                            }
+                        }
+                    }
+                }
+
+                if (block != null) {
+                    n.block = block;
+                    block.addNode(n.inputNode.getId());
+                    progress = true;
+                } else {
+                    newUnscheduled.add(n);
+                }
+            }
+
+            unscheduled = newUnscheduled;
+
+            if (!progress) {
+                break;
+            }
+        }
+
+        Set<Node> curReachable = new HashSet<Node>(reachable);
+        for (Node n : curReachable) {
+            if (n.block != null) {
+                for (Node s : n.succs) {
+                    if (!reachable.contains(s)) {
+                        markWithBlock(s, n.block, reachable);
+                    }
+                }
+            }
+        }
+
+    }
+
+    private void markWithBlock(Node n, InputBlock b, Set<Node> reachable) {
+        assert !reachable.contains(n);
+        Stack<Node> stack = new Stack<Node>();
+        stack.push(n);
+        n.block = b;
+        b.addNode(n.inputNode.getId());
+        reachable.add(n);
+
+        while (!stack.isEmpty()) {
+            Node cur = stack.pop();
+            for (Node s : cur.succs) {
+                if (!reachable.contains(s)) {
+                    reachable.add(s);
+                    s.block = b;
+                    b.addNode(s.inputNode.getId());
+                    stack.push(s);
+                }
+            }
+
+            for (Node s : cur.preds) {
+                if (!reachable.contains(s)) {
+                    reachable.add(s);
+                    s.block = b;
+                    b.addNode(s.inputNode.getId());
+                    stack.push(s);
+                }
+            }
+        }
+    }
+
+    private class BlockIntermediate {
+
+        InputBlock block;
+        int index;
+        int dominator;
+        int semi;
+        int parent;
+        int label;
+        int ancestor;
+        List<Integer> pred;
+        List<Integer> bucket;
+    }
+
+    public void buildCommonDominators() {
+        commonDominator = new InputBlock[this.blocks.size()][this.blocks.size()];
+        for (int i = 0; i < blocks.size(); i++) {
+            for (int j = 0; j < blocks.size(); j++) {
+                commonDominator[i][j] = getCommonDominator(i, j);
+            }
+        }
+    }
+
+    public InputBlock getCommonDominator(int a, int b) {
+        InputBlock ba = blocks.get(a);
+        InputBlock bb = blocks.get(b);
+        if (ba == bb) {
+            return ba;
+        }
+        Set<InputBlock> visited = new HashSet<InputBlock>();
+        while (ba != null) {
+            visited.add(ba);
+            ba = dominatorMap.get(ba);
+        }
+
+        while (bb != null) {
+            if (visited.contains(bb)) {
+                return bb;
+            }
+            bb = dominatorMap.get(bb);
+        }
+
+        assert false;
+        return null;
+    }
+
+    public void buildDominators() {
+        dominatorMap = new HashMap<InputBlock, InputBlock>();
+        if (blocks.size() == 0) {
+            return;
+        }
+        Vector<BlockIntermediate> intermediate = new Vector<BlockIntermediate>();
+        Map<InputBlock, BlockIntermediate> map = new HashMap<InputBlock, BlockIntermediate>();
+        int z = 0;
+        for (InputBlock b : blocks) {
+            BlockIntermediate bi = new BlockIntermediate();
+            bi.block = b;
+            bi.index = z;
+            bi.dominator = -1;
+            bi.semi = -1;
+            bi.parent = -1;
+            bi.label = z;
+            bi.ancestor = -1;
+            bi.pred = new ArrayList<Integer>();
+            bi.bucket = new ArrayList<Integer>();
+            intermediate.add(bi);
+            map.put(b, bi);
+            z++;
+        }
+        Stack<Integer> stack = new Stack<Integer>();
+        stack.add(0);
+
+        Vector<BlockIntermediate> array = new Vector<BlockIntermediate>();
+        intermediate.get(0).dominator = 0;
+
+        int n = 0;
+        while (!stack.isEmpty()) {
+            int index = stack.pop();
+            BlockIntermediate ib = intermediate.get(index);
+            ib.semi = n;
+            array.add(ib);
+            n = n + 1;
+            for (InputBlock b : ib.block.getSuccessors()) {
+                BlockIntermediate succ = map.get(b);
+                if (succ.semi == -1) {
+                    succ.parent = index;
+                    stack.push(succ.index); // TODO: check if same node could be pushed twice
+                }
+                succ.pred.add(index);
+            }
+        }
+
+        for (int i = n - 1; i > 0; i--) {
+            BlockIntermediate block = array.get(i);
+            int block_index = block.index;
+            for (int predIndex : block.pred) {
+                int curIndex = eval(predIndex, intermediate);
+                BlockIntermediate curBlock = intermediate.get(curIndex);
+                if (curBlock.semi < block.semi) {
+                    block.semi = curBlock.semi;
+                }
+            }
+
+
+            int semiIndex = block.semi;
+            BlockIntermediate semiBlock = array.get(semiIndex);
+            semiBlock.bucket.add(block_index);
+
+            link(block.parent, block_index, intermediate);
+            BlockIntermediate parentBlock = intermediate.get(block.parent);
+
+            for (int j = 0; j < parentBlock.bucket.size(); j++) {
+                for (int curIndex : parentBlock.bucket) {
+                    int newIndex = eval(curIndex, intermediate);
+                    BlockIntermediate curBlock = intermediate.get(curIndex);
+                    BlockIntermediate newBlock = intermediate.get(newIndex);
+                    int dom = block.parent;
+                    if (newBlock.semi < curBlock.semi) {
+                        dom = newIndex;
+                    }
+
+                    curBlock.dominator = dom;
+                }
+            }
+
+
+            parentBlock.bucket.clear();
+        }
+
+        for (int i = 1; i < n; i++) {
+
+            BlockIntermediate block = array.get(i);
+            int block_index = block.index;
+
+            int semi_index = block.semi;
+            BlockIntermediate semi_block = array.get(semi_index);
+
+            if (block.dominator != semi_block.index) {
+                int new_dom = intermediate.get(block.dominator).dominator;
+                block.dominator = new_dom;
+            }
+        }
+
+        for (BlockIntermediate ib : intermediate) {
+            if (ib.dominator == -1) {
+                ib.dominator = 0;
+            }
+        }
+
+        for (BlockIntermediate bi : intermediate) {
+            InputBlock b = bi.block;
+            int dominator = bi.dominator;
+            InputBlock dominatorBlock = null;
+            if (dominator != -1) {
+                dominatorBlock = intermediate.get(dominator).block;
+            }
+
+            if (dominatorBlock == b) {
+                dominatorBlock = null;
+            }
+            this.dominatorMap.put(b, dominatorBlock);
+        }
+    }
+
+    private void compress(int index, Vector<BlockIntermediate> blocks) {
+        BlockIntermediate block = blocks.get(index);
+
+        int ancestor = block.ancestor;
+        assert ancestor != -1;
+
+        BlockIntermediate ancestor_block = blocks.get(ancestor);
+        if (ancestor_block.ancestor != -1) {
+            compress(ancestor, blocks);
+
+            int label = block.label;
+            BlockIntermediate label_block = blocks.get(label);
+
+            int ancestor_label = ancestor_block.label;
+            BlockIntermediate ancestor_label_block = blocks.get(label);
+            if (ancestor_label_block.semi < label_block.semi) {
+                block.label = ancestor_label;
+            }
+
+            block.ancestor = ancestor_block.ancestor;
+        }
+    }
+
+    private int eval(int index, Vector<BlockIntermediate> blocks) {
+        BlockIntermediate block = blocks.get(index);
+        if (block.ancestor == -1) {
+            return index;
+        } else {
+            compress(index, blocks);
+            return block.label;
+        }
+    }
+
+    private void link(int index1, int index2, Vector<BlockIntermediate> blocks) {
+        BlockIntermediate block2 = blocks.get(index2);
+        block2.ancestor = index1;
+    }
+
+    private boolean isRegion(Node n) {
+        return n.inputNode.getProperties().get("name").equals("Region");
+    }
+
+    private boolean isPhi(Node n) {
+        return n.inputNode.getProperties().get("name").equals("Phi");
+    }
+
+    private Node findRoot() {
+
+        for (Node n : nodes) {
+            InputNode inputNode = n.inputNode;
+            if (inputNode.getProperties().get("name").equals("Root")) {
+                return n;
+            }
+        }
+
+        return null;
+    }
+
+    public void buildUpGraph() {
+
+        for (InputNode n : graph.getNodes()) {
+            Node node = new Node();
+            node.inputNode = n;
+            nodes.add(node);
+            String p = n.getProperties().get("is_block_proj");
+            node.isBlockProjection = (p != null && p.equals("true"));
+            p = n.getProperties().get("is_block_start");
+            node.isBlockStart = (p != null && p.equals("true"));
+            inputNodeToNode.put(n, node);
+        }
+
+        Map<Integer, List<InputEdge>> edgeMap = new HashMap<Integer, List<InputEdge>>();
+        for (InputEdge e : graph.getEdges()) {
+
+            int to = e.getTo();
+            if (!edgeMap.containsKey(to)) {
+                edgeMap.put(to, new ArrayList<InputEdge>());
+            }
+
+
+            List<InputEdge> list = edgeMap.get(to);
+            list.add(e);
+        }
+
+
+        for (Integer i : edgeMap.keySet()) {
+
+            List<InputEdge> list = edgeMap.get(i);
+            Collections.sort(list, edgeComparator);
+
+            int to = i;
+            InputNode toInputNode = graph.getNode(to);
+            Node toNode = inputNodeToNode.get(toInputNode);
+            for (InputEdge e : list) {
+                assert to == e.getTo();
+                int from = e.getFrom();
+                InputNode fromInputNode = graph.getNode(from);
+                Node fromNode = inputNodeToNode.get(fromInputNode);
+                fromNode.succs.add(toNode);
+                toNode.preds.add(fromNode);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/color.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,5 @@
+colorize("name", ".*", yellow);
+colorize("name", "Catch.*", blue);
+
+colorize("name", "Region|Loop|CountedLoop|Root", red);
+colorize("name", "CProj|IfFalse|IfTrue|JProj|CatchProj", magenta);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/combine.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,4 @@
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/difference.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,4 @@
+colorize("state", "same", white);
+colorize("state", "changed", orange);
+colorize("state", "new", green);
+colorize("state", "deleted", red);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/extendedColor.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,3 @@
+colorize("name", "Con.*", orange);
+colorize("name", "Parm|Proj", lightGray);
+colorize("bci", "..*", magenta);
\ 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/linestyle.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,7 @@
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/matchingFlags.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,3 @@
+colorize("is_dontcare", "false", white);
+colorize("is_shared", "true", green);
+colorize("is_dontcare", "true", red);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/onlyControlFlow.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,24 @@
+var f = new RemoveFilter("Show only control flow");
+f.addRule(
+  new RemoveFilter.RemoveRule(
+    new InvertSelector(
+      new OrSelector(
+        new OrSelector(
+          new SuccessorSelector(
+            new MatcherSelector(
+              new Properties.StringPropertyMatcher("type", "control")
+            )
+          ),
+	  new MatcherSelector(
+            new Properties.StringPropertyMatcher("type", "control")
+          )
+        ),
+	new MatcherSelector(
+          new Properties.StringPropertyMatcher("name", "Start")
+        )
+      )
+    ), false
+  )
+);
+f.addRule( new RemoveFilter.RemoveRule(new MatcherSelector(new Properties.RegexpPropertyMatcher("name", "Phi|Store.")), false));
+f.apply(graph);
\ 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/register.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,4 @@
+colorize("reg", "EAX", green);
+colorize("reg", "EFLAGS", gray);
+colorize("reg", "EBP", orange);
+colorize("reg", "ECX", cyan);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/remove.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+remove("dump_spec", "FramePtr|ReturnAdr|I_O"); 
\ 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/removeMemory.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,7 @@
+
+//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");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeRootInputs.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+removeInputs("name", "Root");
\ 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/removeSafepointInputs.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,4 @@
+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);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeSelfLoops.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+var f = new RemoveSelfLoopsFilter("Remove Self-Loops");
+f.apply(graph);
\ 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/split.filter	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+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/layer.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,61 @@
+<?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="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>
+        <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>
+        <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">
+            <attr name="enabled" boolvalue="false"/>
+            <attr name="after" stringvalue="Difference 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">
+            <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"/>
+        </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>
+        <file name="Combine" url="filters/combine.filter">
+            <attr name="enabled" boolvalue="true"/>
+            <attr name="after" stringvalue="Remove Self Loops"/>
+        </file>
+        <file name="Split" url="filters/split.filter">
+            <attr name="enabled" boolvalue="true"/>
+            <attr name="after" stringvalue="Combine"/>
+        </file>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/build.xml	Wed Jul 05 16:38:46 2017 +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.settings" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.settings.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.settings
+OpenIDE-Module-Layer: com/sun/hotspot/igv/settings/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/settings/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.settings-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=8869440a
+build.xml.script.CRC32=7ef09117
+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=8869440a
+nbproject/build-impl.xml.script.CRC32=1a0e7f21
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,49 @@
+<?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.settings</code-name-base>
+            <suite-component/>
+            <module-dependencies>
+                <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>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.options.api</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.5</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.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.9.0.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.settings</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,5 @@
+AdvancedOption_DisplayName_Settings=Settings
+AdvancedOption_Tooltip_Settings=Application Settings
+OpenIDE-Module-Name=Settings
+OptionsCategory_Name_View=General
+OptionsCategory_Title_View=View Settings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/Settings.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.hotspot.igv.settings;
+
+import java.util.prefs.Preferences;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class Settings {
+
+    public final static String NODE_TEXT = "nodeText";
+    public final static String NODE_TEXT_DEFAULT = "[idx] [name]";
+    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_DEFAULT = "4444";
+    public final static String DIRECTORY = "directory";
+    public final static String DIRECTORY_DEFAULT = System.getProperty("user.dir");
+
+    public static Preferences get() {
+        return Preferences.userNodeForPackage(Settings.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsCategory.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.settings;
+
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import org.netbeans.spi.options.OptionsCategory;
+import org.netbeans.spi.options.OptionsPanelController;
+import org.openide.util.NbBundle;
+import org.openide.util.Utilities;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class ViewOptionsCategory extends OptionsCategory {
+
+    @Override
+    public Icon getIcon() {
+        return new ImageIcon(Utilities.loadImage("com/sun/hotspot/igv/settings/settings.gif"));
+    }
+
+    public String getCategoryName() {
+        return NbBundle.getMessage(ViewOptionsCategory.class, "OptionsCategory_Name_View");
+    }
+
+    public String getTitle() {
+        return NbBundle.getMessage(ViewOptionsCategory.class, "OptionsCategory_Title_View");
+    }
+
+    public OptionsPanelController create() {
+        return new ViewOptionsPanelController();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsPanelController.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.settings;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import javax.swing.JComponent;
+import org.netbeans.spi.options.OptionsPanelController;
+import org.openide.util.HelpCtx;
+import org.openide.util.Lookup;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+final class ViewOptionsPanelController extends OptionsPanelController {
+
+    private ViewPanel panel;
+    private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
+    private boolean changed;
+
+    public void update() {
+        getPanel().load();
+        changed = false;
+    }
+
+    public void applyChanges() {
+        getPanel().store();
+        changed = false;
+    }
+
+    public void cancel() {
+    // need not do anything special, if no changes have been persisted yet
+    }
+
+    public boolean isValid() {
+        return getPanel().valid();
+    }
+
+    public boolean isChanged() {
+        return changed;
+    }
+
+    public HelpCtx getHelpCtx() {
+        return null; // new HelpCtx("...ID") if you have a help set
+    }
+
+    public JComponent getComponent(Lookup masterLookup) {
+        return getPanel();
+    }
+
+    public void addPropertyChangeListener(PropertyChangeListener l) {
+        pcs.addPropertyChangeListener(l);
+    }
+
+    public void removePropertyChangeListener(PropertyChangeListener l) {
+        pcs.removePropertyChangeListener(l);
+    }
+
+    private ViewPanel getPanel() {
+        if (panel == null) {
+            panel = new ViewPanel(this);
+        }
+        return panel;
+    }
+
+    void changed() {
+        if (!changed) {
+            changed = true;
+            pcs.firePropertyChange(OptionsPanelController.PROP_CHANGED, false, true);
+        }
+        pcs.firePropertyChange(OptionsPanelController.PROP_VALID, null, null);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewPanel.form	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,121 @@
+<?xml version="1.0" encoding="UTF-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_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"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jPanel1" max="32767" attributes="0"/>
+              <EmptySpace max="-2" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Group type="102" alignment="0" attributes="0">
+              <EmptySpace max="-2" attributes="0"/>
+              <Component id="jPanel1" min="-2" max="-2" attributes="0"/>
+              <EmptySpace pref="206" max="32767" attributes="0"/>
+          </Group>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="jPanel1">
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="1" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="jLabel1" min="-2" max="-2" attributes="0"/>
+                      <Component id="jLabel3" alignment="0" min="-2" max="-2" attributes="0"/>
+                      <Component id="jLabel2" alignment="0" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace min="-2" pref="39" max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Component id="portSpinner" alignment="0" min="-2" pref="63" max="-2" attributes="0"/>
+                      <Component id="nodeWidthSpinner" alignment="0" min="-2" pref="63" max="-2" attributes="0"/>
+                      <Component id="jScrollPane1" alignment="0" min="-2" pref="365" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" alignment="0" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Group type="102" alignment="0" attributes="0">
+                          <Component id="jScrollPane1" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace type="separate" max="-2" attributes="0"/>
+                          <Group type="103" groupAlignment="3" attributes="0">
+                              <Component id="nodeWidthSpinner" alignment="3" min="-2" max="-2" attributes="0"/>
+                              <Component id="jLabel2" alignment="3" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                          <EmptySpace type="separate" max="-2" attributes="0"/>
+                          <Group type="103" groupAlignment="3" attributes="0">
+                              <Component id="portSpinner" alignment="3" min="-2" max="-2" attributes="0"/>
+                              <Component id="jLabel3" alignment="3" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                      </Group>
+                      <Component id="jLabel1" alignment="0" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace min="-2" pref="73" max="-2" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JLabel" name="jLabel1">
+          <Properties>
+            <Property name="text" type="java.lang.String" value="Node Text"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="jLabel2">
+          <Properties>
+            <Property name="text" type="java.lang.String" value="Node Width"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JSpinner" name="portSpinner">
+        </Component>
+        <Container class="javax.swing.JScrollPane" name="jScrollPane1">
+          <AuxValues>
+            <AuxValue name="autoScrollPane" type="java.lang.Boolean" value="true"/>
+          </AuxValues>
+
+          <Layout class="org.netbeans.modules.form.compat2.layouts.support.JScrollPaneSupportLayout"/>
+          <SubComponents>
+            <Component class="javax.swing.JTextArea" name="nodeTextArea">
+              <Properties>
+                <Property name="columns" type="int" value="20"/>
+                <Property name="rows" type="int" value="5"/>
+              </Properties>
+            </Component>
+          </SubComponents>
+        </Container>
+        <Component class="javax.swing.JSpinner" name="nodeWidthSpinner">
+        </Component>
+        <Component class="javax.swing.JLabel" name="jLabel3">
+          <Properties>
+            <Property name="text" type="java.lang.String" value="Network Port"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewPanel.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.settings;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+final class ViewPanel extends javax.swing.JPanel {
+
+    private final ViewOptionsPanelController controller;
+
+    ViewPanel(ViewOptionsPanelController controller) {
+        this.controller = controller;
+        initComponents();
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        jPanel1 = new javax.swing.JPanel();
+        jLabel1 = new javax.swing.JLabel();
+        jLabel2 = new javax.swing.JLabel();
+        portSpinner = new javax.swing.JSpinner();
+        jScrollPane1 = new javax.swing.JScrollPane();
+        nodeTextArea = new javax.swing.JTextArea();
+        nodeWidthSpinner = new javax.swing.JSpinner();
+        jLabel3 = new javax.swing.JLabel();
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel1, "Node Text");
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel2, "Node Width");
+
+        nodeTextArea.setColumns(20);
+        nodeTextArea.setRows(5);
+        jScrollPane1.setViewportView(nodeTextArea);
+
+        org.openide.awt.Mnemonics.setLocalizedText(jLabel3, "Network Port");
+
+        org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
+        jPanel1.setLayout(jPanel1Layout);
+        jPanel1Layout.setHorizontalGroup(
+            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(org.jdesktop.layout.GroupLayout.TRAILING, jPanel1Layout.createSequentialGroup()
+                .addContainerGap()
+                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                    .add(jLabel1)
+                    .add(jLabel3)
+                    .add(jLabel2))
+                .add(39, 39, 39)
+                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                    .add(portSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 63, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                    .add(nodeWidthSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 63, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                    .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 365, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
+                .addContainerGap())
+        );
+        jPanel1Layout.setVerticalGroup(
+            jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(jPanel1Layout.createSequentialGroup()
+                .addContainerGap()
+                .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+                    .add(jPanel1Layout.createSequentialGroup()
+                        .add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                        .add(18, 18, 18)
+                        .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
+                            .add(nodeWidthSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                            .add(jLabel2))
+                        .add(18, 18, 18)
+                        .add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE)
+                            .add(portSpinner, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                            .add(jLabel3)))
+                    .add(jLabel1))
+                .add(73, 73, 73))
+        );
+
+        org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this);
+        this.setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(layout.createSequentialGroup()
+                .addContainerGap()
+                .add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                .addContainerGap())
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
+            .add(layout.createSequentialGroup()
+                .addContainerGap()
+                .add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 232, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
+                .addContainerGap(206, Short.MAX_VALUE))
+        );
+    }// </editor-fold>//GEN-END:initComponents
+    void load() {
+        nodeTextArea.setText(Settings.get().get(Settings.NODE_TEXT, Settings.NODE_TEXT_DEFAULT));
+        nodeWidthSpinner.setValue(Integer.parseInt(Settings.get().get(Settings.NODE_WIDTH, Settings.NODE_WIDTH_DEFAULT)));
+        portSpinner.setValue(Integer.parseInt(Settings.get().get(Settings.PORT, Settings.PORT_DEFAULT)));
+    }
+
+    void store() {
+        Settings.get().put(Settings.NODE_TEXT, nodeTextArea.getText());
+        Settings.get().put(Settings.NODE_WIDTH, nodeWidthSpinner.getValue().toString());
+        Settings.get().put(Settings.PORT, portSpinner.getValue().toString());
+    }
+
+    boolean valid() {
+        return true;
+    }
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JLabel jLabel1;
+    private javax.swing.JLabel jLabel2;
+    private javax.swing.JLabel jLabel3;
+    private javax.swing.JPanel jPanel1;
+    private javax.swing.JScrollPane jScrollPane1;
+    private javax.swing.JTextArea nodeTextArea;
+    private javax.swing.JSpinner nodeWidthSpinner;
+    private javax.swing.JSpinner portSpinner;
+    // End of variables declaration//GEN-END:variables
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/layer.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,9 @@
+<?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="OptionsDialog">
+        <file name="Advanced.instance_hidden"/>
+        <file name="General.instance_hidden"/>
+        <file name="com-sun-hotspot-igv-settings-ViewOptionsCategory.instance"/>
+    </folder>
+</filesystem>
Binary file hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/settings.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/build.xml	Wed Jul 05 16:38:46 2017 +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.util" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.util.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.util
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/util/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.util-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=a470a16f
+build.xml.script.CRC32=466cf03b
+build.xml.stylesheet.CRC32=05353c81
+# 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=a470a16f
+nbproject/build-impl.xml.script.CRC32=39f45e01
+nbproject/build-impl.xml.stylesheet.CRC32=3f8b4615
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,47 @@
+<?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.util</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>org.netbeans.api.visual</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>2.9</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.1.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.10.1.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>com.sun.hotspot.igv.util</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/BoundedZoomAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,182 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.util;
+
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
+import javax.swing.JComponent;
+import javax.swing.JScrollPane;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.action.WidgetAction.State;
+import org.netbeans.api.visual.action.WidgetAction.WidgetMouseWheelEvent;
+import org.netbeans.api.visual.animator.SceneAnimator;
+import org.netbeans.api.visual.widget.Scene;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class BoundedZoomAction extends WidgetAction.Adapter {
+
+    private double minFactor = 0.0;
+    private double maxFactor = Double.MAX_VALUE;
+    private double zoomMultiplier;
+    private boolean useAnimator;
+
+    public BoundedZoomAction(double zoomMultiplier, boolean useAnimator) {
+        this.zoomMultiplier = zoomMultiplier;
+        this.useAnimator = useAnimator;
+    }
+
+    public double getMinFactor() {
+        return minFactor;
+    }
+
+    public void setMinFactor(double d) {
+        minFactor = d;
+    }
+
+    public double getMaxFactor() {
+        return maxFactor;
+    }
+
+    public void setMaxFactor(double d) {
+        maxFactor = d;
+    }
+
+    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 mouseWheelMoved(Widget widget, WidgetMouseWheelEvent event) {
+        final Scene scene = widget.getScene();
+        int amount = event.getWheelRotation();
+        JScrollPane scrollPane = findScrollPane(scene.getView());
+        Point viewPosition = null;
+        Point mouseLocation = scene.convertSceneToView(event.getPoint());
+        int xOffset = 0;
+        int yOffset = 0;
+        Point oldViewPosition = null;
+        Rectangle bounds = new Rectangle(scene.getBounds());
+        Dimension componentSize = new Dimension(scene.getView().getPreferredSize());
+
+        if (scrollPane != null) {
+            viewPosition = new Point(scrollPane.getViewport().getViewPosition());
+            oldViewPosition = new Point(viewPosition);
+            xOffset = (mouseLocation.x - viewPosition.x);
+            yOffset = (mouseLocation.y - viewPosition.y);
+            viewPosition.x += xOffset;
+            viewPosition.y += yOffset;
+        }
+
+        if (useAnimator) {
+            SceneAnimator sceneAnimator = scene.getSceneAnimator();
+            synchronized (sceneAnimator) {
+                double zoom = sceneAnimator.isAnimatingZoomFactor() ? sceneAnimator.getTargetZoomFactor() : scene.getZoomFactor();
+                while (amount > 0 && zoom / zoomMultiplier >= minFactor && zoom / zoomMultiplier <= maxFactor) {
+                    zoom /= zoomMultiplier;
+                    if (viewPosition != null) {
+                        viewPosition.x /= zoomMultiplier;
+                        viewPosition.y /= zoomMultiplier;
+                        bounds.width /= zoomMultiplier;
+                        bounds.height /= zoomMultiplier;
+                        componentSize.width /= zoomMultiplier;
+                        componentSize.height /= zoomMultiplier;
+                    }
+                    amount--;
+                }
+                while (amount < 0 && zoom * zoomMultiplier >= minFactor && zoom * zoomMultiplier <= maxFactor) {
+                    zoom *= zoomMultiplier;
+                    if (viewPosition != null) {
+                        viewPosition.x *= zoomMultiplier;
+                        viewPosition.y *= zoomMultiplier;
+                        bounds.width *= zoomMultiplier;
+                        bounds.height *= zoomMultiplier;
+                        componentSize.width *= zoomMultiplier;
+                        componentSize.height *= zoomMultiplier;
+                    }
+                    amount++;
+                }
+                sceneAnimator.animateZoomFactor(zoom);
+            }
+        } else {
+            double zoom = scene.getZoomFactor();
+            while (amount > 0 && zoom / zoomMultiplier >= minFactor && zoom / zoomMultiplier <= maxFactor) {
+                zoom /= zoomMultiplier;
+                if (viewPosition != null) {
+                    viewPosition.x /= zoomMultiplier;
+                    viewPosition.y /= zoomMultiplier;
+                    bounds.width /= zoomMultiplier;
+                    bounds.height /= zoomMultiplier;
+                    componentSize.width /= zoomMultiplier;
+                    componentSize.height /= zoomMultiplier;
+                }
+                amount--;
+            }
+            while (amount < 0 && zoom * zoomMultiplier >= minFactor && zoom * zoomMultiplier <= maxFactor) {
+                zoom *= zoomMultiplier;
+                if (viewPosition != null) {
+                    viewPosition.x *= zoomMultiplier;
+                    viewPosition.y *= zoomMultiplier;
+                    bounds.width *= zoomMultiplier;
+                    bounds.height *= zoomMultiplier;
+                    componentSize.width *= zoomMultiplier;
+                    componentSize.height *= zoomMultiplier;
+                }
+                amount++;
+            }
+            scene.setZoomFactor(zoom);
+        }
+
+        if (scrollPane != null) {
+            scene.validate(); // Call validate to update size of scene
+            Dimension size = scrollPane.getViewport().getExtentSize();
+            viewPosition.x -= xOffset;
+            viewPosition.y -= yOffset;
+            scene.resolveBounds(scene.getLocation(), bounds);
+            scene.getView().setPreferredSize(componentSize);
+            scene.getView().revalidate();
+            scene.getView().addNotify();
+            scrollPane.getViewport().setViewPosition(viewPosition);
+        }
+
+        return WidgetAction.State.CONSUMED;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Util
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ColorIcon.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.util;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+import javax.swing.Icon;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ColorIcon implements Icon {
+
+    private Color color;
+
+    public ColorIcon(Color c) {
+        color = c;
+    }
+
+    public void paintIcon(Component c, Graphics g, int x, int y) {
+        g.setColor(color);
+        g.fillRect(x, y, 16, 16);
+    }
+
+    public int getIconWidth() {
+        return 16;
+    }
+
+    public int getIconHeight() {
+        return 16;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ContextAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,95 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+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.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public abstract class ContextAction<T> extends CallableSystemAction implements LookupListener, ContextAwareAction {
+
+    private Lookup context = null;
+    private Lookup.Result<T> result = null;
+
+    public ContextAction() {
+        this(Utilities.actionsGlobalContext());
+    }
+
+    public ContextAction(Lookup context) {
+        init(context);
+    }
+
+    private void init(Lookup context) {
+        this.context = context;
+        result = context.lookupResult(contextClass());
+        result.addLookupListener(this);
+        resultChanged(null);
+    }
+
+    public void resultChanged(LookupEvent e) {
+        if (result.allItems().size() != 0) {
+            update(result.allInstances().iterator().next());
+        } else {
+            update(null);
+        }
+    }
+
+    @Override
+    public void performAction() {
+        final T t = result.allInstances().iterator().next();
+
+        // Ensure it's AWT event thread
+        EventQueue.invokeLater(new Runnable() {
+
+            public void run() {
+                performAction(t);
+            }
+        });
+    }
+
+    public void update(T t) {
+        if (t == null) {
+            setEnabled(false);
+        } else {
+            setEnabled(isEnabled(t));
+        }
+    }
+
+    public boolean isEnabled(T context) {
+        return true;
+    }
+
+    public abstract Class<T> contextClass();
+
+    public abstract void performAction(T context);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/DoubleClickAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.util;
+
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class DoubleClickAction extends WidgetAction.Adapter {
+
+    private DoubleClickHandler handler;
+
+    public DoubleClickAction(DoubleClickHandler handler) {
+        this.handler = handler;
+    }
+
+    @Override
+    public WidgetAction.State mouseClicked(Widget widget, WidgetAction.WidgetMouseEvent event) {
+        if (event.getClickCount() > 1) {
+            handler.handleDoubleClick(widget, event);
+            return WidgetAction.State.CONSUMED;
+        }
+        return WidgetAction.State.REJECTED;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/DoubleClickHandler.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.util;
+
+import org.netbeans.api.visual.action.WidgetAction.WidgetMouseEvent;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface DoubleClickHandler {
+
+    public void handleDoubleClick(Widget w, WidgetMouseEvent e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ExtendedSatelliteComponent.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.util;
+
+import org.netbeans.api.visual.widget.Scene;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * @author David Kaspar
+ * @author Thomas Wuerthinger
+ */
+public class ExtendedSatelliteComponent extends JComponent implements MouseListener, MouseMotionListener, Scene.SceneListener, ComponentListener {
+
+    private Scene scene;
+    private Image image;
+    private int imageWidth;
+    private int imageHeight;
+
+    public ExtendedSatelliteComponent(Scene scene) {
+        this.scene = scene;
+        setDoubleBuffered(true);
+        setPreferredSize(new Dimension(128, 128));
+        addMouseListener(this);
+        addMouseMotionListener(this);
+    }
+
+    @Override
+    public void addNotify() {
+        super.addNotify();
+        scene.addSceneListener(this);
+        JComponent viewComponent = scene.getView();
+        if (viewComponent == null) {
+            viewComponent = scene.createView();
+        }
+        viewComponent.addComponentListener(this);
+        repaint();
+    }
+
+    @Override
+    public void removeNotify() {
+        scene.getView().removeComponentListener(this);
+        scene.removeSceneListener(this);
+        super.removeNotify();
+    }
+
+    public void update() {
+        this.image = null;
+        repaint();
+    }
+
+    @Override
+    public void paint(Graphics g) {
+        Graphics2D gr = (Graphics2D) g;
+        super.paint(g);
+        Rectangle bounds = scene.getBounds();
+        Dimension size = getSize();
+
+        double sx = bounds.width > 0 ? (double) size.width / bounds.width : 0.0;
+        double sy = bounds.width > 0 ? (double) size.height / bounds.height : 0.0;
+        double scale = Math.min(sx, sy);
+
+        int vw = (int) (scale * bounds.width);
+        int vh = (int) (scale * bounds.height);
+        int vx = (size.width - vw) / 2;
+        int vy = (size.height - vh) / 2;
+
+
+        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.paint(ig);
+        }
+
+        gr.drawImage(image, vx, vy, this);
+
+        JComponent component = scene.getView();
+        double zoomFactor = scene.getZoomFactor();
+        Rectangle viewRectangle = component != null ? component.getVisibleRect() : null;
+        if (viewRectangle != null) {
+            Rectangle window = new Rectangle(
+                    (int) ((double) viewRectangle.x * scale / zoomFactor),
+                    (int) ((double) viewRectangle.y * scale / zoomFactor),
+                    (int) ((double) viewRectangle.width * scale / zoomFactor),
+                    (int) ((double) viewRectangle.height * scale / zoomFactor));
+            window.translate(vx, vy);
+            gr.setColor(new Color(200, 200, 200, 128));
+            gr.fill(window);
+            gr.setColor(Color.BLACK);
+            gr.drawRect(window.x, window.y, window.width - 1, window.height - 1);
+        }
+    }
+
+    public void mouseClicked(MouseEvent e) {
+    }
+
+    public void mousePressed(MouseEvent e) {
+        moveVisibleRect(e.getPoint());
+    }
+
+    public void mouseReleased(MouseEvent e) {
+        moveVisibleRect(e.getPoint());
+    }
+
+    public void mouseEntered(MouseEvent e) {
+    }
+
+    public void mouseExited(MouseEvent e) {
+    }
+
+    public void mouseDragged(MouseEvent e) {
+        moveVisibleRect(e.getPoint());
+    }
+
+    public void mouseMoved(MouseEvent e) {
+    }
+
+    private void moveVisibleRect(Point center) {
+        JComponent component = scene.getView();
+        if (component == null) {
+            return;
+        }
+        double zoomFactor = scene.getZoomFactor();
+        Rectangle bounds = scene.getBounds();
+        Dimension size = getSize();
+
+        double sx = bounds.width > 0 ? (double) size.width / bounds.width : 0.0;
+        double sy = bounds.width > 0 ? (double) size.height / bounds.height : 0.0;
+        double scale = Math.min(sx, sy);
+
+        int vw = (int) (scale * bounds.width);
+        int vh = (int) (scale * bounds.height);
+        int vx = (size.width - vw) / 2;
+        int vy = (size.height - vh) / 2;
+
+        int cx = (int) ((double) (center.x - vx) / scale * zoomFactor);
+        int cy = (int) ((double) (center.y - vy) / scale * zoomFactor);
+
+        Rectangle visibleRect = component.getVisibleRect();
+        visibleRect.x = cx - visibleRect.width / 2;
+        visibleRect.y = cy - visibleRect.height / 2;
+        component.scrollRectToVisible(visibleRect);
+
+    }
+
+    public void sceneRepaint() {
+    }
+
+    public void sceneValidating() {
+    }
+
+    public void sceneValidated() {
+    }
+
+    public void componentResized(ComponentEvent e) {
+        repaint();
+    }
+
+    public void componentMoved(ComponentEvent e) {
+        repaint();
+    }
+
+    public void componentShown(ComponentEvent e) {
+    }
+
+    public void componentHidden(ComponentEvent e) {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ExtendedSelectAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.util;
+
+import java.awt.event.MouseEvent;
+import javax.swing.JPanel;
+import org.netbeans.api.visual.action.ActionFactory;
+import org.netbeans.api.visual.action.SelectProvider;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.action.WidgetAction.State;
+import org.netbeans.api.visual.action.WidgetAction.WidgetKeyEvent;
+import org.netbeans.api.visual.action.WidgetAction.WidgetMouseEvent;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class ExtendedSelectAction extends WidgetAction.Adapter {
+
+    private WidgetAction innerAction;
+    private JPanel panel;
+
+    public ExtendedSelectAction(SelectProvider provider) {
+        innerAction = ActionFactory.createSelectAction(provider);
+        panel = new JPanel();
+    }
+
+    @Override
+    public State mousePressed(Widget widget, WidgetMouseEvent event) {
+        // TODO: Solve this differently?
+        if (event.getButton() != MouseEvent.BUTTON2) {
+            return innerAction.mousePressed(widget, new WidgetMouseEvent(event.getEventID(), new MouseEvent(panel, (int) event.getEventID(), event.getWhen(), event.getModifiersEx(), event.getPoint().x, event.getPoint().y, event.getClickCount(), event.isPopupTrigger(), MouseEvent.BUTTON1)));
+        } else {
+            return super.mousePressed(widget, event);
+        }
+    }
+
+    @Override
+    public State mouseReleased(Widget widget, WidgetMouseEvent event) {
+        return innerAction.mouseReleased(widget, event);
+    }
+
+    @Override
+    public State keyTyped(Widget widget, WidgetKeyEvent event) {
+        return innerAction.keyTyped(widget, event);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/PropertiesSheet.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.hotspot.igv.util;
+
+import com.sun.hotspot.igv.data.Properties;
+import com.sun.hotspot.igv.data.Property;
+import java.lang.reflect.InvocationTargetException;
+import org.openide.nodes.Node;
+import org.openide.nodes.Sheet;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PropertiesSheet {
+
+    public static void initializeSheet(Properties properties, Sheet s) {
+
+        Sheet.Set set1 = Sheet.createPropertiesSet();
+        set1.setDisplayName("Properties");
+        for (final Property p : properties.getProperties()) {
+            Node.Property<String> prop = new Node.Property<String>(String.class) {
+
+                @Override
+                public boolean canRead() {
+                    return true;
+                }
+
+                @Override
+                public String getValue() throws IllegalAccessException, InvocationTargetException {
+                    return p.getValue();
+                }
+
+                @Override
+                public boolean canWrite() {
+                    return false;
+                }
+
+                @Override
+                public void setValue(String arg0) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
+                    p.setValue(arg0);
+                }
+            };
+            prop.setName(p.getName());
+            set1.put(prop);
+        }
+        s.put(set1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSlider.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,360 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+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.event.MouseEvent;
+import java.awt.event.MouseListener;
+import java.awt.event.MouseMotionListener;
+import java.util.List;
+import javax.swing.JComponent;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class RangeSlider extends JComponent implements ChangedListener<RangeSliderModel>, MouseListener, MouseMotionListener {
+
+    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 int MOUSE_ENDING_OFFSET = 3;
+    public static final Color BACKGROUND_COLOR = Color.white;
+    public static final Color BAR_COLOR = Color.black;
+    public static final Color BAR_SELECTION_COLOR = new Color(255, 0, 0, 120);
+    public static final Color BAR_SELECTION_COLOR_ROLLOVER = new Color(255, 0, 255, 120);
+    public static final Color BAR_SELECTION_COLOR_DRAG = new Color(0, 0, 255, 120);
+    private RangeSliderModel model;
+    private State state;
+    private Point startPoint;
+    private RangeSliderModel tempModel;
+    private boolean isOverBar;
+
+    private enum State {
+
+        Initial,
+        DragBar,
+        DragFirstPosition,
+        DragSecondPosition
+    }
+
+    public RangeSlider() {
+        state = State.Initial;
+        this.addMouseMotionListener(this);
+        this.addMouseListener(this);
+    }
+
+    public void setModel(RangeSliderModel newModel) {
+        if (model != null) {
+            model.getChangedEvent().removeListener(this);
+            model.getColorChangedEvent().removeListener(this);
+        }
+        if (newModel != null) {
+            newModel.getChangedEvent().addListener(this);
+            newModel.getColorChangedEvent().addListener(this);
+        }
+        this.model = newModel;
+        update();
+    }
+
+    private RangeSliderModel getPaintingModel() {
+        if (tempModel != null) {
+            return tempModel;
+        }
+        return model;
+    }
+
+    @Override
+    public Dimension getPreferredSize() {
+        Dimension d = super.getPreferredSize();
+        d.height = HEIGHT;
+        return d;
+    }
+
+    public void changed(RangeSliderModel source) {
+        update();
+    }
+
+    private void update() {
+        this.repaint();
+    }
+
+    private int getXPosition(int index) {
+        assert index >= 0 && index < getPaintingModel().getPositions().size();
+        return getXOffset() * (index + 1);
+    }
+
+    private int getXOffset() {
+        int size = getPaintingModel().getPositions().size();
+        int width = getWidth();
+        return (width / (size + 1));
+    }
+
+    private int getEndXPosition(int index) {
+        return getXPosition(index) + getXOffset() / 2;
+    }
+
+    private int getStartXPosition(int index) {
+        return getXPosition(index) - getXOffset() / 2;
+    }
+
+    @Override
+    public void paint(Graphics g) {
+        super.paint(g);
+        Graphics2D g2 = (Graphics2D) g;
+        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+                RenderingHints.VALUE_ANTIALIAS_ON);
+        int width = getWidth();
+        int height = getHeight();
+
+        g2.setColor(BACKGROUND_COLOR);
+        g2.fillRect(0, 0, width, height);
+
+        // Nothing to paint?
+        if (getPaintingModel() == null || getPaintingModel().getPositions().size() == 0) {
+            return;
+        }
+
+        int firstPos = getPaintingModel().getFirstPosition();
+        int secondPos = getPaintingModel().getSecondPosition();
+
+        paintSelected(g2, firstPos, secondPos);
+        paintBar(g2);
+
+    }
+
+    private int getBarStartY() {
+        return getHeight() - BAR_HEIGHT;
+    }
+
+    private void paintBar(Graphics2D g) {
+        List<String> list = getPaintingModel().getPositions();
+        int 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);
+
+        int circleCenterY = barStartY + BAR_HEIGHT / 2;
+        for (int i = 0; i < list.size(); i++) {
+            int 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.setColor(Color.black);
+            g.drawOval(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);
+                FontMetrics metrics = g.getFontMetrics();
+                Rectangle bounds = metrics.getStringBounds(curS, g).getBounds();
+                if (bounds.width < endX - startX && bounds.height < barStartY) {
+                    g.setColor(Color.black);
+                    g.drawString(curS, startX + (endX - startX) / 2 - bounds.width / 2, barStartY / 2 + bounds.height / 2);
+                }
+            }
+        }
+
+    }
+
+    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;
+        paintSelectedEnding(g, startX, barSelectionEndingStartY);
+        paintSelectedEnding(g, endX, barSelectionEndingStartY);
+
+        g.setColor(BAR_SELECTION_COLOR);
+        if (state == State.DragBar) {
+            g.setColor(BAR_SELECTION_COLOR_DRAG);
+        } 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);
+    }
+
+    private void paintSelectedEnding(Graphics g, int x, int y) {
+        g.setColor(BAR_COLOR);
+        g.fillRect(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);
+            return off <= MOUSE_ENDING_OFFSET;
+        }
+        return false;
+    }
+
+    private boolean isOverFirstPosition(Point p) {
+        if (p.y >= getBarStartY()) {
+            int destX = getStartXPosition(getPaintingModel().getFirstPosition());
+            int off = Math.abs(destX - p.x);
+            return off <= MOUSE_ENDING_OFFSET;
+        }
+        return false;
+    }
+
+    private boolean isOverSelection(Point p) {
+        if (p.y >= getBarStartY() && !isOverFirstPosition(p) && !isOverSecondPosition(p)) {
+            return p.x > getStartXPosition(getPaintingModel().getFirstPosition()) && p.x < getEndXPosition(getPaintingModel().getSecondPosition());
+        }
+        return false;
+    }
+
+    public void mouseDragged(MouseEvent e) {
+        if (state == State.DragBar) {
+            int firstX = this.getStartXPosition(model.getFirstPosition());
+            int 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;
+            }
+            int secondPosition = newIndex + model.getSecondPosition() - model.getFirstPosition();
+            tempModel.setPositions(newIndex, secondPosition);
+            update();
+        } else if (state == State.DragFirstPosition) {
+            int firstPosition = getIndexFromPosition(e.getPoint().x) + 1;
+            int secondPosition = model.getSecondPosition();
+            if (firstPosition > secondPosition) {
+                firstPosition--;
+            }
+            tempModel.setPositions(firstPosition, secondPosition);
+            update();
+        } else if (state == State.DragSecondPosition) {
+            int firstPosition = model.getFirstPosition();
+            int secondPosition = getIndexFromPosition(e.getPoint().x);
+            if (secondPosition < firstPosition) {
+                secondPosition++;
+            }
+            tempModel.setPositions(firstPosition, secondPosition);
+            update();
+        }
+    }
+
+    private int getIndexFromPosition(int 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);
+            if (x >= startX && x <= endX) {
+                return i;
+            }
+        }
+        return getPaintingModel().getPositions().size() - 1;
+    }
+
+    private int getCircleIndexFromPosition(int x) {
+        int result = 0;
+        for (int i = 1; i < getPaintingModel().getPositions().size() - 1; i++) {
+            if (x > getStartXPosition(i)) {
+                result = i;
+            }
+        }
+        return result;
+    }
+
+    public void mouseMoved(MouseEvent e) {
+        isOverBar = false;
+        if (model == null) {
+            return;
+        }
+
+
+        Point p = e.getPoint();
+        if (isOverFirstPosition(p) || isOverSecondPosition(p)) {
+            setCursor(Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
+        } else if (isOverSelection(p)) {
+            isOverBar = true;
+            setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
+        } else {
+            this.setCursor(Cursor.getDefaultCursor());
+        }
+        repaint();
+    }
+
+    public void mouseClicked(MouseEvent e) {
+        if (e.getClickCount() > 1) {
+            // Double click
+            int index = getCircleIndexFromPosition(e.getPoint().x);
+            model.setPositions(index, index);
+        }
+    }
+
+    public void mousePressed(MouseEvent e) {
+        if (model == null) {
+            return;
+        }
+
+        Point p = e.getPoint();
+        if (isOverFirstPosition(p)) {
+            state = State.DragFirstPosition;
+        } else if (isOverSecondPosition(p)) {
+            state = State.DragSecondPosition;
+        } else if (isOverSelection(p)) {
+            state = State.DragBar;
+        } else {
+            return;
+        }
+
+        startPoint = e.getPoint();
+        tempModel = model.copy();
+    }
+
+    public void mouseReleased(MouseEvent e) {
+        if (model == null || tempModel == null) {
+            return;
+        }
+        state = State.Initial;
+        model.setPositions(tempModel.getFirstPosition(), tempModel.getSecondPosition());
+        tempModel = null;
+    }
+
+    public void mouseEntered(MouseEvent e) {
+    }
+
+    public void mouseExited(MouseEvent e) {
+        isOverBar = false;
+        repaint();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,130 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.hotspot.igv.util;
+
+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;
+import java.util.List;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class RangeSliderModel implements ChangedEventProvider<RangeSliderModel> {
+
+    // Warning: Update setData method if fields are added
+    private ChangedEvent<RangeSliderModel> changedEvent;
+    private ChangedEvent<RangeSliderModel> colorChangedEvent;
+    private List<String> positions;
+    private int firstPosition;
+    private int secondPosition;
+    private List<Color> colors;
+
+    public void setData(RangeSliderModel model) {
+        boolean changed = false;
+        changed |= (positions != model.positions);
+        positions = model.positions;
+        changed |= (firstPosition != model.firstPosition);
+        firstPosition = model.firstPosition;
+        changed |= (secondPosition != model.secondPosition);
+        secondPosition = model.secondPosition;
+        boolean colorChanged = (colors != model.colors);
+        colors = model.colors;
+        if (changed) {
+            changedEvent.fire();
+        }
+        if (colorChanged) {
+            colorChangedEvent.fire();
+        }
+    }
+
+    public RangeSliderModel(List<String> positions) {
+        assert positions.size() > 0;
+        this.positions = positions;
+        this.changedEvent = new ChangedEvent<RangeSliderModel>(this);
+        this.colorChangedEvent = new ChangedEvent<RangeSliderModel>(this);
+        colors = new ArrayList<Color>();
+        for (int i = 0; i < positions.size(); i++) {
+            colors.add(Color.black);
+        }
+    }
+
+    public void setColors(List<Color> colors) {
+        this.colors = colors;
+        colorChangedEvent.fire();
+    }
+
+    public List<Color> getColors() {
+        return colors;
+    }
+
+    public RangeSliderModel copy() {
+        RangeSliderModel newModel = new RangeSliderModel(positions);
+        newModel.firstPosition = firstPosition;
+        newModel.secondPosition = secondPosition;
+        newModel.colors = colors;
+        return newModel;
+    }
+
+    public List<String> getPositions() {
+        return Collections.unmodifiableList(positions);
+    }
+
+    public int getFirstPosition() {
+        return firstPosition;
+    }
+
+    public int getSecondPosition() {
+        return secondPosition;
+    }
+
+    public void setPositions(int fp, int sp) {
+        assert fp >= 0 && fp < positions.size();
+        assert sp >= 0 && sp < positions.size();
+        firstPosition = fp;
+        secondPosition = sp;
+        ensureOrder();
+        changedEvent.fire();
+    }
+
+    private void ensureOrder() {
+        if (secondPosition < firstPosition) {
+            int tmp = secondPosition;
+            secondPosition = firstPosition;
+            firstPosition = tmp;
+        }
+    }
+
+    public ChangedEvent<RangeSliderModel> getColorChangedEvent() {
+        return colorChangedEvent;
+    }
+
+    public ChangedEvent<RangeSliderModel> getChangedEvent() {
+        return changedEvent;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/build.xml	Wed Jul 05 16:38:46 2017 +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.view" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project com.sun.hotspot.igv.view.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/manifest.mf	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: com.sun.hotspot.igv.view
+OpenIDE-Module-Layer: com/sun/hotspot/igv/view/layer.xml
+OpenIDE-Module-Localizing-Bundle: com/sun/hotspot/igv/view/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="com.sun.hotspot.igv.view-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>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=2de95ef6
+build.xml.script.CRC32=31afe4b1
+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=2de95ef6
+nbproject/build-impl.xml.script.CRC32=fa7a4119
+nbproject/build-impl.xml.stylesheet.CRC32=deb65f65
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=JDK_1.6
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,151 @@
+<?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.view</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.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>
+                <dependency>
+                    <code-name-base>com.sun.hotspot.igv.hierarchicallayout</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.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.svg</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.visual</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>2.9</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.0.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.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.1.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>
+                <package>com.sun.hotspot.igv.view</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/suite.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/META-INF/services/com.sun.hotspot.igv.data.services.GraphViewer	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+com.sun.hotspot.igv.view.GraphViewerImplementation
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/META-INF/services/com.sun.hotspot.igv.data.services.InputGraphProvider	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1 @@
+com.sun.hotspot.igv.view.EditorInputGraphProvider
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/BoundedZoomAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 java.awt.Rectangle;
+import javax.swing.JComponent;
+import javax.swing.JScrollPane;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.action.WidgetAction.State;
+import org.netbeans.api.visual.action.WidgetAction.WidgetMouseWheelEvent;
+import org.netbeans.api.visual.animator.SceneAnimator;
+import org.netbeans.api.visual.widget.Scene;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class BoundedZoomAction extends WidgetAction.Adapter {
+
+    private double minFactor = 0.0;
+    private double maxFactor = Double.MAX_VALUE;
+    private double zoomMultiplier;
+    private boolean useAnimator;
+
+    public BoundedZoomAction(double zoomMultiplier, boolean useAnimator) {
+        assert zoomMultiplier > 1.0;
+        this.zoomMultiplier = zoomMultiplier;
+        this.useAnimator = useAnimator;
+    }
+
+    public double getMinFactor() {
+        return minFactor;
+    }
+
+    public void setMinFactor(double d) {
+        minFactor = d;
+    }
+
+    public double getMaxFactor() {
+        return maxFactor;
+    }
+
+    public void setMaxFactor(double d) {
+        maxFactor = d;
+    }
+
+    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 mouseWheelMoved(Widget widget, WidgetMouseWheelEvent event) {
+        final Scene scene = widget.getScene();
+        int amount = event.getWheelRotation();
+        JScrollPane scrollPane = findScrollPane(scene.getView());
+        Point viewPosition = null;
+        Point mouseLocation = scene.convertSceneToView(event.getPoint());
+        int xOffset = 0;
+        int yOffset = 0;
+        Rectangle bounds = new Rectangle(scene.getBounds());
+        Dimension componentSize = new Dimension(scene.getView().getPreferredSize());
+        if (scrollPane != null) {
+            viewPosition = new Point(scrollPane.getViewport().getViewPosition());
+            xOffset = (mouseLocation.x - viewPosition.x);
+            yOffset = (mouseLocation.y - viewPosition.y);
+            viewPosition.x += xOffset;
+            viewPosition.y += yOffset;
+        }
+
+        if (useAnimator) {
+            SceneAnimator sceneAnimator = scene.getSceneAnimator();
+            synchronized (sceneAnimator) {
+                double zoom = sceneAnimator.isAnimatingZoomFactor() ? sceneAnimator.getTargetZoomFactor() : scene.getZoomFactor();
+                while (amount > 0 && zoom / zoomMultiplier >= minFactor) {
+                    zoom /= zoomMultiplier;
+                    if (viewPosition != null) {
+                        viewPosition.x /= zoomMultiplier;
+                        viewPosition.y /= zoomMultiplier;
+                        bounds.width /= zoomMultiplier;
+                        bounds.height /= zoomMultiplier;
+                        componentSize.width /= zoomMultiplier;
+                        componentSize.height /= zoomMultiplier;
+                    }
+                    amount--;
+                }
+                while (amount < 0 && zoom * zoomMultiplier <= maxFactor) {
+                    zoom *= zoomMultiplier;
+                    if (viewPosition != null) {
+                        viewPosition.x *= zoomMultiplier;
+                        viewPosition.y *= zoomMultiplier;
+                        bounds.width *= zoomMultiplier;
+                        bounds.height *= zoomMultiplier;
+                        componentSize.width *= zoomMultiplier;
+                        componentSize.height *= zoomMultiplier;
+                    }
+                    amount++;
+                }
+                sceneAnimator.animateZoomFactor(zoom);
+            }
+        } else {
+            double zoom = scene.getZoomFactor();
+            while (amount > 0 && zoom / zoomMultiplier >= minFactor) {
+                zoom /= zoomMultiplier;
+                if (viewPosition != null) {
+                    viewPosition.x /= zoomMultiplier;
+                    viewPosition.y /= zoomMultiplier;
+                    bounds.width /= zoomMultiplier;
+                    bounds.height /= zoomMultiplier;
+                    componentSize.width /= zoomMultiplier;
+                    componentSize.height /= zoomMultiplier;
+                }
+                amount--;
+            }
+            while (amount < 0 && zoom * zoomMultiplier <= maxFactor) {
+                zoom *= zoomMultiplier;
+                if (viewPosition != null) {
+                    viewPosition.x *= zoomMultiplier;
+                    viewPosition.y *= zoomMultiplier;
+                    bounds.width *= zoomMultiplier;
+                    bounds.height *= zoomMultiplier;
+                    componentSize.width *= zoomMultiplier;
+                    componentSize.height *= zoomMultiplier;
+                }
+                amount++;
+            }
+            scene.setZoomFactor(zoom);
+        }
+
+        if (scrollPane != null) {
+            viewPosition.x -= xOffset;
+            viewPosition.y -= yOffset;
+            scrollPane.getViewport().setViewPosition(viewPosition);
+        }
+
+
+        return WidgetAction.State.CONSUMED;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,3 @@
+HINT_EditorTopComponent=This is a Editor window
+OpenIDE-Module-Name=View
+CTL_EditorTopComponent=Editor Window
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ConnectionAnchor.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,1254 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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.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.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.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.Hashtable;
+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 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.animator.SceneAnimator;
+import org.netbeans.api.visual.layout.LayoutFactory;
+import org.netbeans.api.visual.widget.ConnectionWidget;
+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.util.Lookup;
+import org.openide.util.lookup.AbstractLookup;
+import org.openide.util.lookup.InstanceContent;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class DiagramScene extends Scene implements ChangedListener<DiagramViewModel> {
+
+    private Hashtable<Figure, FigureWidget> figureWidgets;
+    private Hashtable<Slot, SlotWidget> slotWidgets;
+    private Hashtable<Connection, ConnectionWidget> connectionWidgets;
+    private Hashtable<InputBlock, BlockWidget> blockWidgets;
+    private Widget hoverWidget;
+    private WidgetAction hoverAction;
+    private List<FigureWidget> selectedWidgets;
+    private Lookup lookup;
+    private InstanceContent content;
+    private Action[] actions;
+    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;
+    public static final float ALPHA = 0.4f;
+    public static final int GRID_SIZE = 30;
+    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 ANIMATION_LIMIT = 40;
+    private PopupMenuProvider popupMenuProvider = new PopupMenuProvider() {
+
+        public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
+            return DiagramScene.this.createPopupMenu();
+        }
+    };
+    private RectangularSelectDecorator rectangularSelectDecorator = new RectangularSelectDecorator() {
+
+        public Widget createSelectionWidget() {
+            Widget widget = new Widget(DiagramScene.this);
+            widget.setBorder(BorderFactory.createLineBorder(Color.black, 2));
+            widget.setForeground(Color.red);
+            return widget;
+        }
+    };
+    private RectangularSelectProvider rectangularSelectProvider = new RectangularSelectProvider() {
+
+        public void performSelection(Rectangle rectangle) {
+            if (rectangle.width < 0) {
+                rectangle.x += rectangle.width;
+                rectangle.width *= -1;
+            }
+
+            if (rectangle.height < 0) {
+                rectangle.y += rectangle.height;
+                rectangle.height *= -1;
+            }
+
+            boolean updated = false;
+            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;
+                    }
+                } 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();
+                }
+            }
+
+            if (updated) {
+                selectionUpdated();
+            }
+
+        }
+    };
+
+    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() {
+
+        public void mouseWheelMoved(MouseWheelEvent e) {
+            DiagramScene.this.zoomAction.mouseWheelMoved(DiagramScene.this, new WidgetAction.WidgetMouseWheelEvent(0, e));
+            DiagramScene.this.validate();
+        }
+    };
+    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();
+    }
+
+    public void setScrollPosition(Point p) {
+        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);
+
+        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();
+
+        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);
+
+        mainLayer = new LayerWidget(this);
+        this.addChild(mainLayer);
+
+        topLeft = new Widget(this);
+        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.getActions().addAction(ActionFactory.createPopupMenuAction(popupMenuProvider));
+
+        LayerWidget selectLayer = new LayerWidget(this);
+        this.addChild(selectLayer);
+        this.getActions().addAction(ActionFactory.createRectangularSelectAction(rectangularSelectDecorator, selectLayer, rectangularSelectProvider));
+
+        blockWidgets = new Hashtable<InputBlock, BlockWidget>();
+
+        boolean b = this.getUndoRedoEnabled();
+        this.setUndoRedoEnabled(false);
+        this.setNewModel(model);
+        this.setUndoRedoEnabled(b);
+    }
+
+    private void selectionUpdated() {
+        getModel().setSelectedNodes(this.getSelectedNodes());
+        addUndo();
+    }
+
+    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;
+    }
+
+    public boolean isAllVisible() {
+        return getModel().getHiddenNodes().size() == 0;
+    }
+
+    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 += " (";
+
+        if (f.getCluster() != null) {
+            name += "B" + f.getCluster().toString();
+        }
+        if (!this.getFigureWidget(f).isVisible()) {
+            if (f.getCluster() != null) {
+                name += ", ";
+            }
+            name += "hidden";
+        }
+        name += ")";
+        a.putValue(Action.NAME, name);
+        return a;
+    }
+
+    public void setNewModel(DiagramViewModel model) {
+        if (this.model != null) {
+            this.model.getDiagramChangedEvent().removeListener(this);
+            this.model.getViewPropertiesChangedEvent().removeListener(this);
+        }
+        this.model = model;
+
+        if (this.model == null) {
+            this.modelCopy = null;
+        } else {
+            this.modelCopy = this.model.copy();
+        }
+
+        model.getDiagramChangedEvent().addListener(this);
+        model.getViewPropertiesChangedEvent().addListener(this);
+
+        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 Hashtable<Figure, FigureWidget>();
+        slotWidgets = new Hashtable<Slot, SlotWidget>();
+        connectionWidgets = new Hashtable<Connection, ConnectionWidget>();
+
+        WidgetAction selectAction = new ExtendedSelectAction(selectProvider);
+        Diagram d = getModel().getDiagramToView();
+
+        if (getModel().getShowBlocks()) {
+            Scheduler s = Lookup.getDefault().lookup(Scheduler.class);
+            Collection<InputBlock> newBlocks = new ArrayList<InputBlock>(s.schedule(d.getGraph()));
+            d.schedule(newBlocks);
+        }
+
+        for (Figure f : d.getFigures()) {
+            FigureWidget w = new FigureWidget(f, this, mainLayer);
+            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);
+
+            for (InputSlot s : f.getInputSlots()) {
+                SlotWidget sw = new InputSlotWidget(s, this, slotLayer, w);
+                slotWidgets.put(s, sw);
+                sw.getActions().addAction(selectAction);
+            }
+
+            for (OutputSlot s : f.getOutputSlots()) {
+                SlotWidget sw = new OutputSlotWidget(s, this, slotLayer, w);
+                slotWidgets.put(s, sw);
+                sw.getActions().addAction(selectAction);
+            }
+        }
+
+        if (getModel().getShowBlocks()) {
+            for (InputBlock bn : d.getGraph().getBlocks()) {
+                BlockWidget w = new BlockWidget(this, d, bn);
+                w.setVisible(false);
+                blockWidgets.put(bn, w);
+                blockLayer.addChild(w);
+            }
+        }
+
+        this.smallUpdate(true);
+
+    }
+
+    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());
+
+        if (w1.isVisible() && w2.isVisible()) {
+            return true;
+        }
+
+        return false;
+    }
+
+    private void relayout(Set<Widget> oldVisibleWidgets) {
+
+        Diagram diagram = getModel().getDiagramToView();
+
+        HashSet<Figure> figures = new HashSet<Figure>();
+
+        for (Figure f : diagram.getFigures()) {
+            FigureWidget w = figureWidgets.get(f);
+            if (w.isVisible()) {
+                figures.add(f);
+            }
+        }
+
+        HashSet<Connection> edges = new HashSet<Connection>();
+
+        for (Connection c : diagram.getConnections()) {
+            if (isVisible(c)) {
+                edges.add(c);
+            }
+        }
+
+        if (getModel().getShowBlocks()) {
+            HierarchicalClusterLayoutManager m = new HierarchicalClusterLayoutManager(OldHierarchicalLayoutManager.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));
+        }
+
+        int maxX = -BORDER_SIZE;
+        int maxY = -BORDER_SIZE;
+        for (Figure f : diagram.getFigures()) {
+            FigureWidget w = figureWidgets.get(f);
+            if (w.isVisible()) {
+                Point p = f.getPosition();
+                Dimension d = f.getSize();
+                maxX = Math.max(maxX, p.x + d.width);
+                maxY = Math.max(maxY, p.y + d.height);
+            }
+        }
+
+        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());
+            if (w1.isVisible() && w2.isVisible()) {
+                for (Point p : points) {
+                    if (p != null) {
+                        maxX = Math.max(maxX, p.x);
+                        maxY = Math.max(maxY, p.y);
+                    }
+                }
+            }
+        }
+
+        if (getModel().getShowBlocks()) {
+            for (Block b : diagram.getBlocks()) {
+                BlockWidget w = blockWidgets.get(b.getInputBlock());
+                if (w != null && w.isVisible()) {
+                    Rectangle r = b.getBounds();
+                    maxX = Math.max(maxX, r.x + r.width);
+                    maxY = Math.max(maxY, r.y + r.height);
+                }
+            }
+        }
+
+        bottomRight.setPreferredLocation(new Point(maxX + BORDER_SIZE, maxY + BORDER_SIZE));
+        int offx = 0;
+        int offy = 0;
+        int curWidth = maxX + 2 * BORDER_SIZE;
+        int curHeight = maxY + 2 * BORDER_SIZE;
+
+        Rectangle bounds = this.getScrollPane().getBounds();
+        if (curWidth < bounds.width) {
+            offx = (bounds.width - curWidth) / 2;
+        }
+
+        if (curHeight < bounds.height) {
+            offy = (bounds.height - curHeight) / 2;
+        }
+
+        final int offx2 = offx;
+        final int offy2 = offy;
+
+        SceneAnimator animator = this.getSceneAnimator();
+        connectionLayer.removeChildren();
+        int visibleFigureCount = 0;
+        for (Figure f : diagram.getFigures()) {
+            if (figureWidgets.get(f).isVisible()) {
+                visibleFigureCount++;
+            }
+        }
+
+        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);
+            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);
+                    }
+                } else {
+                    w.setPreferredLocation(p2);
+                }
+            }
+        }
+
+        if (getModel().getShowBlocks()) {
+            for (Block b : diagram.getBlocks()) {
+                BlockWidget w = blockWidgets.get(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);
+                        }
+                    } else {
+                        w.setPreferredBounds(r);
+                    }
+                }
+            }
+        }
+    }
+    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>>();
+
+        for (Connection c : connections) {
+
+            if (!isVisible(c)) {
+                continue;
+            }
+
+            List<Point> controlPoints = c.getControlPoints();
+            if (controlPointIndex >= controlPoints.size()) {
+                continue;
+            }
+
+            Point cur = controlPoints.get(controlPointIndex);
+            if (cur == null) {
+                cur = specialNullPoint;
+            } else if (controlPointIndex == 0 && !s.getShowName()) {
+                cur = new Point(cur.x, cur.y - SLOT_OFFSET);
+            } else if (controlPointIndex == controlPoints.size() - 1 && !c.getInputSlot().getShowName()) {
+                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);
+                newList.add(c);
+                pointMap.put(cur, newList);
+            }
+
+        }
+
+        for (Point p : pointMap.keySet()) {
+            List<Connection> connectionList = pointMap.get(p);
+
+            boolean isBold = false;
+            boolean isDashed = true;
+
+            for (Connection c : connectionList) {
+
+                if (c.getStyle() == Connection.ConnectionStyle.BOLD) {
+                    isBold = true;
+                }
+
+                if (c.getStyle() != Connection.ConnectionStyle.DASHED) {
+                    isDashed = false;
+                }
+            }
+
+            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);
+                newPredecessor = w;
+                connectionLayer.addChild(w);
+                w.getActions().addAction(hoverAction);
+            }
+
+            processOutputSlot(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();
+    }
+
+    public Lookup getLookup() {
+        return lookup;
+    }
+
+    public void gotoFigures(final List<Figure> figures) {
+        Rectangle overall = null;
+        showFigures(figures);
+        for (Figure f : figures) {
+
+            FigureWidget fw = getFigureWidget(f);
+            if (fw != null) {
+                Rectangle r = fw.getBounds();
+                Point p = fw.getLocation();
+                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);
+        }
+    }
+
+    private Point calcCenter(Rectangle r) {
+
+        Point center = new Point((int) r.getCenterX(), (int) r.getCenterY());
+        center.x -= getScrollPane().getViewport().getViewRect().width / 2;
+        center.y -= getScrollPane().getViewport().getViewRect().height / 2;
+
+        // Ensure to be within area
+        center.x = Math.max(0, center.x);
+        center.x = Math.min(getScrollPane().getViewport().getViewSize().width - getScrollPane().getViewport().getViewRect().width, center.x);
+        center.y = Math.max(0, center.y);
+        center.y = Math.min(getScrollPane().getViewport().getViewSize().height - getScrollPane().getViewport().getViewRect().height, center.y);
+
+        return center;
+    }
+
+    private void centerRectangle(Rectangle r) {
+
+        if (getScrollPane().getViewport().getViewRect().width == 0 || getScrollPane().getViewport().getViewRect().height == 0) {
+            return;
+        }
+
+        Rectangle r2 = new Rectangle(r.x, r.y, r.width, r.height);
+        r2 = convertSceneToView(r2);
+
+        double factorX = (double) r2.width / (double) getScrollPane().getViewport().getViewRect().width;
+        double factorY = (double) r2.height / (double) getScrollPane().getViewport().getViewRect().height;
+        double factor = Math.max(factorX, factorY);
+        if (factor >= 1.0) {
+            Point p = getScrollPane().getViewport().getViewPosition();
+            setZoomFactor(getZoomFactor() / factor);
+            r2.x /= factor;
+            r2.y /= factor;
+            r2.width /= factor;
+            r2.height /= factor;
+            getScrollPane().getViewport().setViewPosition(calcCenter(r2));
+        } else {
+            getScrollPane().getViewport().setViewPosition(calcCenter(r2));
+        }
+    }
+
+    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();
+    }
+
+    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;
+    }
+
+    private UndoRedo.Manager getUndoRedoManager() {
+        if (undoRedoManager == null) {
+            undoRedoManager = new UndoRedo.Manager();
+            undoRedoManager.setLimit(UNDOREDO_LIMIT);
+        }
+
+        return undoRedoManager;
+    }
+
+    public UndoRedo getUndoRedo() {
+        return getUndoRedoManager();
+    }
+
+    private boolean isVisible(Figure f) {
+        for (Integer n : f.getSource().getSourceNodesAsSet()) {
+            if (getModel().getHiddenNodes().contains(n)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean doesIntersect(Set s1, Set s2) {
+        if (s1.size() > s2.size()) {
+            Set tmp = s1;
+            s1 = s2;
+            s2 = tmp;
+        }
+
+        for (Object o : s1) {
+            if (s2.contains(o)) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+
+    public void showNot(final Set<Integer> nodes) {
+        updateHiddenNodes(nodes, true);
+    }
+
+    public void showOnly(final Set<Integer> nodes) {
+        HashSet<Integer> allNodes = new HashSet<Integer>(getModel().getGraphToView().getGroup().getAllNodes());
+        allNodes.removeAll(nodes);
+        updateHiddenNodes(allNodes, true);
+    }
+
+    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>();
+
+        for (Figure f : diagram.getFigures()) {
+            FigureWidget w = figureWidgets.get(f);
+            if (w.isVisible()) {
+                oldVisibleWidgets.add(w);
+            }
+        }
+
+        if (getModel().getShowBlocks()) {
+            for (InputBlock b : diagram.getGraph().getBlocks()) {
+                BlockWidget w = blockWidgets.get(b);
+                if (w.isVisible()) {
+                    oldVisibleWidgets.add(w);
+                }
+            }
+        }
+
+        for (Figure f : diagram.getFigures()) {
+            boolean hiddenAfter = doesIntersect(f.getSource().getSourceNodesAsSet(), newHiddenNodes);
+
+            FigureWidget w = this.figureWidgets.get(f);
+            w.setBoundary(false);
+            if (!hiddenAfter) {
+                // Figure is shown
+                w.setVisible(true);
+                for (InputNode n : f.getSource().getSourceNodes()) {
+                    visibleBlocks.add(diagram.getGraph().getBlock(n));
+                }
+            } else {
+                // Figure is hidden
+                w.setVisible(false);
+            }
+        }
+
+        if (getModel().getShowNodeHull()) {
+            List<FigureWidget> boundaries = new ArrayList<FigureWidget>();
+            for (Figure f : diagram.getFigures()) {
+                FigureWidget w = this.figureWidgets.get(f);
+                if (!w.isVisible()) {
+                    Set<Figure> set = new HashSet<Figure>(f.getPredecessorSet());
+                    set.addAll(f.getSuccessorSet());
+
+                    boolean b = false;
+                    for (Figure neighbor : set) {
+                        FigureWidget neighborWidget = figureWidgets.get(neighbor);
+                        if (neighborWidget.isVisible()) {
+                            b = true;
+                            break;
+                        }
+                    }
+
+                    if (b) {
+                        w.setBoundary(true);
+                        for (InputNode n : f.getSource().getSourceNodes()) {
+                            visibleBlocks.add(diagram.getGraph().getBlock(n));
+                        }
+                        boundaries.add(w);
+                    }
+                }
+            }
+
+            for (FigureWidget w : boundaries) {
+                if (w.isBoundary()) {
+                    w.setVisible(true);
+                }
+            }
+        }
+
+        if (getModel().getShowBlocks()) {
+            for (InputBlock b : diagram.getGraph().getBlocks()) {
+
+                boolean visibleAfter = visibleBlocks.contains(b);
+
+                BlockWidget w = blockWidgets.get(b);
+                if (visibleAfter) {
+                    // Block must be shown
+                    w.setVisible(true);
+                } else {
+                    // Block must be hidden
+                    w.setVisible(false);
+                }
+            }
+        }
+
+        getModel().setHiddenNodes(newHiddenNodes);
+        if (doRelayout) {
+            relayout(oldVisibleWidgets);
+        }
+        this.validate();
+        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());
+        newHiddenNodes.removeAll(f.getSource().getSourceNodesAsSet());
+        updateHiddenNodes(newHiddenNodes, true);
+    }
+
+    public void showAll(final Collection<Figure> f) {
+        showFigures(f);
+
+    }
+
+    public void show(final Figure f) {
+        showFigure(f);
+    }
+
+    public void gotoFigure(final Figure f) {
+
+        if (!isVisible(f)) {
+            showFigure(f);
+        }
+
+        FigureWidget fw = getFigureWidget(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();
+        }
+    }
+
+    public JPopupMenu createPopupMenu() {
+        JPopupMenu menu = new JPopupMenu();
+        for (Action a : actions) {
+            if (a == null) {
+                menu.addSeparator();
+            } else {
+                menu.add(a);
+            }
+        }
+        return menu;
+    }
+
+    private static class DiagramUndoRedo extends AbstractUndoableEdit implements ChangedListener<DiagramViewModel> {
+
+        private DiagramViewModel oldModel;
+        private DiagramViewModel newModel;
+        private Point oldScrollPosition;
+        private DiagramScene scene;
+
+        public DiagramUndoRedo(DiagramScene scene, Point oldScrollPosition, DiagramViewModel oldModel, DiagramViewModel newModel) {
+            assert oldModel != null;
+            assert newModel != null;
+            this.oldModel = oldModel;
+            this.newModel = newModel;
+            this.scene = scene;
+            this.oldScrollPosition = oldScrollPosition;
+        }
+
+        @Override
+        public void redo() throws CannotRedoException {
+            super.redo();
+            boolean b = scene.getUndoRedoEnabled();
+            scene.setUndoRedoEnabled(false);
+            scene.getModel().getViewChangedEvent().addListener(this);
+            scene.getModel().setData(newModel);
+            scene.getModel().getViewChangedEvent().removeListener(this);
+            scene.setUndoRedoEnabled(b);
+        }
+
+        @Override
+        public void undo() throws CannotUndoException {
+            super.undo();
+            boolean b = scene.getUndoRedoEnabled();
+            scene.setUndoRedoEnabled(false);
+            scene.getModel().getViewChangedEvent().addListener(this);
+            scene.getModel().setData(oldModel);
+            scene.getModel().getViewChangedEvent().removeListener(this);
+
+            SwingUtilities.invokeLater(new Runnable() {
+
+                public void run() {
+                    scene.setScrollPosition(oldScrollPosition);
+                }
+            });
+
+            scene.setUndoRedoEnabled(b);
+        }
+
+        public void changed(DiagramViewModel source) {
+            scene.getModel().getViewChangedEvent().removeListener(this);
+            if (oldModel.getSelectedNodes().equals(newModel.getHiddenNodes())) {
+                scene.smallUpdate(false);
+            } else {
+                scene.smallUpdate(true);
+            }
+        }
+    }
+    private boolean undoRedoEnabled = true;
+
+    public void setUndoRedoEnabled(boolean b) {
+        this.undoRedoEnabled = b;
+    }
+
+    public boolean getUndoRedoEnabled() {
+        return undoRedoEnabled;
+    }
+
+    public void changed(DiagramViewModel source) {
+        assert source == model : "Receive only changed event from current model!";
+        assert source != null;
+        update();
+    }
+
+    private void addUndo() {
+
+        DiagramViewModel newModelCopy = model.copy();
+
+        if (undoRedoEnabled) {
+            this.getUndoRedoManager().undoableEditHappened(new UndoableEditEvent(this, new DiagramUndoRedo(this, this.getScrollPosition(), modelCopy, newModelCopy)));
+        }
+
+        this.modelCopy = newModelCopy;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,303 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+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.difference.Difference;
+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.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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class DiagramViewModel extends RangeSliderModel implements ChangedListener<RangeSliderModel> {
+
+    // Warning: Update setData method if fields are added
+    private Group group;
+    private Set<Integer> hiddenNodes;
+    private Set<Integer> onScreenNodes;
+    private Set<Integer> selectedNodes;
+    private FilterChain filterChain;
+    private FilterChain sequenceFilterChain;
+    private Diagram diagram;
+    private ChangedEvent<DiagramViewModel> diagramChangedEvent;
+    private ChangedEvent<DiagramViewModel> viewChangedEvent;
+    private ChangedEvent<DiagramViewModel> viewPropertiesChangedEvent;
+    private boolean showBlocks;
+    private boolean showNodeHull;
+    private ChangedListener<FilterChain> filterChainChangedListener = new ChangedListener<FilterChain>() {
+
+        public void changed(FilterChain source) {
+            diagramChanged();
+        }
+    };
+
+    public DiagramViewModel copy() {
+        DiagramViewModel result = new DiagramViewModel(group, filterChain, sequenceFilterChain);
+        result.setData(this);
+        return result;
+    }
+
+    public void setData(DiagramViewModel newModel) {
+        super.setData(newModel);
+        boolean diagramChanged = false;
+        boolean viewChanged = false;
+        boolean viewPropertiesChanged = false;
+
+        this.group = newModel.group;
+        diagramChanged |= (filterChain != newModel.filterChain);
+        this.filterChain = newModel.filterChain;
+        diagramChanged |= (sequenceFilterChain != newModel.sequenceFilterChain);
+        this.sequenceFilterChain = newModel.sequenceFilterChain;
+        diagramChanged |= (diagram != newModel.diagram);
+        this.diagram = newModel.diagram;
+        viewChanged |= (hiddenNodes != newModel.hiddenNodes);
+        this.hiddenNodes = newModel.hiddenNodes;
+        viewChanged |= (onScreenNodes != newModel.onScreenNodes);
+        this.onScreenNodes = newModel.onScreenNodes;
+        viewChanged |= (selectedNodes != newModel.selectedNodes);
+        this.selectedNodes = newModel.selectedNodes;
+        viewPropertiesChanged |= (showBlocks != newModel.showBlocks);
+        this.showBlocks = newModel.showBlocks;
+        viewPropertiesChanged |= (showNodeHull != newModel.showNodeHull);
+        this.showNodeHull = newModel.showNodeHull;
+
+        if (diagramChanged) {
+            diagramChangedEvent.fire();
+        }
+        if (viewPropertiesChanged) {
+            viewPropertiesChangedEvent.fire();
+        }
+        if (viewChanged) {
+            viewChangedEvent.fire();
+        }
+    }
+
+    public boolean getShowBlocks() {
+        return showBlocks;
+    }
+
+    public void setShowBlocks(boolean b) {
+        showBlocks = b;
+        viewPropertiesChangedEvent.fire();
+    }
+
+    public boolean getShowNodeHull() {
+        return showNodeHull;
+    }
+
+    public void setShowNodeHull(boolean b) {
+        showNodeHull = b;
+        viewPropertiesChangedEvent.fire();
+    }
+
+    public DiagramViewModel(Group g, FilterChain filterChain, FilterChain sequenceFilterChain) {
+        super(calculateStringList(g));
+
+        this.showNodeHull = true;
+        this.showBlocks = true;
+        this.group = g;
+        assert filterChain != null;
+        this.filterChain = filterChain;
+        assert sequenceFilterChain != null;
+        this.sequenceFilterChain = sequenceFilterChain;
+        hiddenNodes = new HashSet<Integer>();
+        onScreenNodes = new HashSet<Integer>();
+        selectedNodes = new HashSet<Integer>();
+        super.getChangedEvent().addListener(this);
+        diagramChangedEvent = new ChangedEvent<DiagramViewModel>(this);
+        viewChangedEvent = new ChangedEvent<DiagramViewModel>(this);
+        viewPropertiesChangedEvent = new ChangedEvent<DiagramViewModel>(this);
+
+        filterChain.getChangedEvent().addListener(filterChainChangedListener);
+        sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
+    }
+
+    public ChangedEvent<DiagramViewModel> getDiagramChangedEvent() {
+        return diagramChangedEvent;
+    }
+
+    public ChangedEvent<DiagramViewModel> getViewChangedEvent() {
+        return viewChangedEvent;
+    }
+
+    public ChangedEvent<DiagramViewModel> getViewPropertiesChangedEvent() {
+        return viewPropertiesChangedEvent;
+    }
+
+    public Set<Integer> getSelectedNodes() {
+        return Collections.unmodifiableSet(selectedNodes);
+    }
+
+    public Set<Integer> getHiddenNodes() {
+        return Collections.unmodifiableSet(hiddenNodes);
+    }
+
+    public Set<Integer> getOnScreenNodes() {
+        return Collections.unmodifiableSet(onScreenNodes);
+    }
+
+    public void setSelectedNodes(Set<Integer> nodes) {
+        this.selectedNodes = nodes;
+        List<Color> colors = new ArrayList<Color>();
+        for (String s : getPositions()) {
+            colors.add(Color.black);
+        }
+        if (nodes.size() >= 1) {
+            for (Integer id : nodes) {
+                if (id < 0) {
+                    id = -id;
+                }
+                InputNode last = null;
+                int index = 0;
+                for (InputGraph g : group.getGraphs()) {
+                    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 (curColor == Color.black) {
+                                    curColor = Color.white;
+                                }
+                            } else {
+                                if (curColor != Color.green) {
+                                    curColor = Color.orange;
+                                }
+                            }
+                        }
+                    }
+                    last = cur;
+                    colors.set(index, curColor);
+                    index++;
+                }
+            }
+            this.setColors(colors);
+        }
+        setColors(colors);
+        viewChangedEvent.fire();
+    }
+
+    public void setHiddenNodes(Set<Integer> nodes) {
+        this.hiddenNodes = nodes;
+        viewChangedEvent.fire();
+    }
+
+    public void setOnScreenNodes(Set<Integer> onScreenNodes) {
+        this.onScreenNodes = onScreenNodes;
+        viewChangedEvent.fire();
+    }
+
+    public FilterChain getSequenceFilterChain() {
+        return filterChain;
+    }
+
+    public void setSequenceFilterChain(FilterChain chain) {
+        assert chain != null : "sequenceFilterChain must never be null";
+        sequenceFilterChain.getChangedEvent().removeListener(filterChainChangedListener);
+        sequenceFilterChain = chain;
+        sequenceFilterChain.getChangedEvent().addListener(filterChainChangedListener);
+        diagramChanged();
+    }
+
+    private void diagramChanged() {
+        // clear diagram
+        diagram = null;
+        getDiagramChangedEvent().fire();
+
+    }
+
+    public FilterChain getFilterChain() {
+        return filterChain;
+    }
+
+    public void setFilterChain(FilterChain chain) {
+        assert chain != null : "filterChain must never be null";
+        filterChain.getChangedEvent().removeListener(filterChainChangedListener);
+        filterChain = chain;
+        filterChain.getChangedEvent().addListener(filterChainChangedListener);
+        diagramChanged();
+    }
+
+    private static List<String> calculateStringList(Group g) {
+        List<String> result = new ArrayList<String>();
+        for (InputGraph graph : g.getGraphs()) {
+            result.add(graph.getName());
+        }
+        return result;
+    }
+
+    public InputGraph getFirstGraph() {
+        return group.getGraphs().get(getFirstPosition());
+    }
+
+    public InputGraph getSecondGraph() {
+        return group.getGraphs().get(getSecondPosition());
+    }
+
+    public void selectGraph(InputGraph g) {
+        int index = group.getGraphs().indexOf(g);
+        assert index != -1;
+        setPositions(index, index);
+    }
+
+    public Diagram getDiagramToView() {
+
+        if (diagram == null) {
+            diagram = Diagram.createDiagram(getGraphToView(), Settings.get().get(Settings.NODE_TEXT, Settings.NODE_TEXT_DEFAULT));
+            getFilterChain().apply(diagram, getSequenceFilterChain());
+        }
+
+        return diagram;
+    }
+
+    public InputGraph getGraphToView() {
+        if (getFirstGraph() != getSecondGraph()) {
+            InputGraph inputGraph = Difference.createDiffGraph(getSecondGraph(), getFirstGraph());
+            return inputGraph;
+        } else {
+            InputGraph inputGraph = getFirstGraph();
+            return inputGraph;
+        }
+    }
+
+    public void changed(RangeSliderModel source) {
+        diagramChanged();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,52 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.hotspot.igv.view;
+
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.services.InputGraphProvider;
+import com.sun.hotspot.igv.data.InputNode;
+import java.util.Set;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class EditorInputGraphProvider implements InputGraphProvider {
+
+    public InputGraph getGraph() {
+        EditorTopComponent e = EditorTopComponent.getActive();
+        if (e == null) {
+            return null;
+        }
+        return e.getDiagramModel().getGraphToView();
+    }
+
+    public void setSelectedNodes(Set<InputNode> nodes) {
+        EditorTopComponent e = EditorTopComponent.getActive();
+        if (e != null) {
+            e.setSelectedNodes(nodes);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.form	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.2" maxVersion="1.2" type="org.netbeans.modules.form.forminfo.JPanelFormInfo">
+  <NonVisualComponents>
+    <Component class="javax.swing.JCheckBox" name="jCheckBox1">
+      <Properties>
+        <Property name="text" type="java.lang.String" value="jCheckBox1"/>
+        <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+          <Border info="org.netbeans.modules.form.compat2.border.EmptyBorderInfo">
+            <EmptyBorder bottom="0" left="0" right="0" top="0"/>
+          </Border>
+        </Property>
+        <Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
+          <Insets value="[0, 0, 0, 0]"/>
+        </Property>
+      </Properties>
+    </Component>
+  </NonVisualComponents>
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="0"/>
+    <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"/>
+    <AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+    <AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
+  </AuxValues>
+
+  <Layout class="org.netbeans.modules.form.compat2.layouts.DesignBorderLayout"/>
+</Form>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,577 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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.filter.FilterChain;
+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.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 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.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 javax.swing.border.Border;
+import org.openide.DialogDisplayer;
+import org.openide.actions.FindAction;
+import org.openide.actions.RedoAction;
+import org.openide.actions.UndoAction;
+import org.openide.awt.Toolbar;
+import org.openide.awt.ToolbarPool;
+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.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 {
+
+    private DiagramScene scene;
+    private InstanceContent content;
+    private FindPanel findPanel;
+    private EnableBlockLayoutAction blockLayoutAction;
+    private OverviewAction overviewAction;
+    private PredSuccAction predSuccAction;
+    private boolean notFirstTime;
+    private ExtendedSatelliteComponent satelliteComponent;
+    private JPanel centerPanel;
+    private CardLayout cardLayout;
+    private RangeSlider rangeSlider;
+    private JToggleButton overviewButton;
+    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() {
+
+        public void export(File f) {
+
+            Graphics2D svgGenerator = BatikSVG.createGraphicsObject();
+
+            if (svgGenerator == null) {
+                NotifyDescriptor message = new NotifyDescriptor.Message("For export to SVG files the Batik SVG Toolkit must be intalled.", NotifyDescriptor.ERROR_MESSAGE);
+                DialogDisplayer.getDefault().notifyLater(message);
+            } else {
+                scene.paint(svgGenerator);
+                FileOutputStream os = null;
+                try {
+                    os = new FileOutputStream(f);
+                    Writer out = new OutputStreamWriter(os, "UTF-8");
+                    BatikSVG.printToStream(svgGenerator, out, true);
+                } catch (FileNotFoundException e) {
+                    NotifyDescriptor message = new NotifyDescriptor.Message("For export to SVG files the Batik SVG Toolkit must be intalled.", NotifyDescriptor.ERROR_MESSAGE);
+                    DialogDisplayer.getDefault().notifyLater(message);
+
+                } catch (UnsupportedEncodingException e) {
+                } finally {
+                    if (os != null) {
+                        try {
+                            os.close();
+                        } catch (IOException e) {
+                        }
+                    }
+                }
+
+            }
+        }
+    };
+
+    private void updateDisplayName() {
+        setDisplayName(getDiagram().getName());
+    }
+
+    public EditorTopComponent(Diagram diagram) {
+
+        FilterChain filterChain = null;
+        FilterChain sequence = null;
+        FilterChainProvider provider = Lookup.getDefault().lookup(FilterChainProvider.class);
+        if (provider == null) {
+            filterChain = new FilterChain();
+            sequence = new FilterChain();
+        } else {
+            filterChain = provider.getFilterChain();
+            sequence = provider.getSequence();
+        }
+
+        setName(NbBundle.getMessage(EditorTopComponent.class, "CTL_EditorTopComponent"));
+        setToolTipText(NbBundle.getMessage(EditorTopComponent.class, "HINT_EditorTopComponent"));
+
+        Action[] actions = new Action[]{
+            PrevDiagramAction.get(PrevDiagramAction.class),
+            NextDiagramAction.get(NextDiagramAction.class),
+            null,
+            ExtractAction.get(ExtractAction.class),
+            ShowAllAction.get(HideAction.class),
+            ShowAllAction.get(ShowAllAction.class),
+            null,
+            ZoomInAction.get(ZoomInAction.class),
+            ZoomOutAction.get(ZoomOutAction.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
+        toolBar.setBorder(b);
+        JPanel container = new JPanel();
+        this.add(container, BorderLayout.NORTH);
+        container.setLayout(new BorderLayout());
+        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);
+
+        scene = new DiagramScene(actions, rangeSliderModel);
+        content = new InstanceContent();
+        this.associateLookup(new ProxyLookup(new Lookup[]{scene.getLookup(), new AbstractLookup(content)}));
+        content.add(exportCookie);
+        content.add(rangeSliderModel);
+
+
+        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();
+        toolBar.add(ExtractAction.get(ExtractAction.class));
+        toolBar.add(ShowAllAction.get(HideAction.class));
+        toolBar.add(ShowAllAction.get(ShowAllAction.class));
+        toolBar.addSeparator();
+        toolBar.add(ShowAllAction.get(ZoomInAction.class));
+        toolBar.add(ShowAllAction.get(ZoomOutAction.class));
+
+        blockLayoutAction = new EnableBlockLayoutAction();
+        JToggleButton button = new JToggleButton(blockLayoutAction);
+        button.setSelected(true);
+        toolBar.add(button);
+        blockLayoutAction.addPropertyChangeListener(this);
+
+        overviewAction = new OverviewAction();
+        overviewButton = new JToggleButton(overviewAction);
+        overviewButton.setSelected(false);
+        toolBar.add(overviewButton);
+        overviewAction.addPropertyChangeListener(this);
+
+        predSuccAction = new PredSuccAction();
+        button = new JToggleButton(predSuccAction);
+        button.setSelected(true);
+        toolBar.add(button);
+        predSuccAction.addPropertyChangeListener(this);
+
+        toolBar.addSeparator();
+        toolBar.add(UndoAction.get(UndoAction.class));
+        toolBar.add(RedoAction.get(RedoAction.class));
+
+        centerPanel = new JPanel();
+        this.add(centerPanel, BorderLayout.CENTER);
+        cardLayout = new CardLayout();
+        centerPanel.setLayout(cardLayout);
+        centerPanel.add(SCENE_STRING, scene.getScrollPane());
+        centerPanel.setBackground(Color.WHITE);
+        satelliteComponent = new ExtendedSatelliteComponent(scene);
+        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);
+
+        scene.getScrollPane().addKeyListener(keyListener);
+        scene.getView().addKeyListener(keyListener);
+        satelliteComponent.addKeyListener(keyListener);
+
+        scene.getScrollPane().addHierarchyBoundsListener(new HierarchyBoundsListener() {
+
+            public void ancestorMoved(HierarchyEvent e) {
+            }
+
+            public void ancestorResized(HierarchyEvent e) {
+                if (!notFirstTime && scene.getScrollPane().getBounds().width > 0) {
+                    notFirstTime = true;
+                    SwingUtilities.invokeLater(new Runnable() {
+
+                        public void run() {
+                            Figure f = EditorTopComponent.this.scene.getModel().getDiagramToView().getRootFigure();
+                            if (f != null) {
+                                scene.setUndoRedoEnabled(false);
+                                scene.gotoFigure(f);
+                                scene.setUndoRedoEnabled(true);
+                            }
+                        }
+                    });
+                }
+            }
+        });
+
+        updateDisplayName();
+    }
+    private KeyListener keyListener = new KeyListener() {
+
+        public void keyTyped(KeyEvent e) {
+        }
+
+        public void keyPressed(KeyEvent e) {
+            if (e.getKeyCode() == KeyEvent.VK_S) {
+                EditorTopComponent.this.overviewButton.setSelected(true);
+                EditorTopComponent.this.overviewAction.setState(true);
+            }
+        }
+
+        public void keyReleased(KeyEvent e) {
+            if (e.getKeyCode() == KeyEvent.VK_S) {
+                EditorTopComponent.this.overviewButton.setSelected(false);
+                EditorTopComponent.this.overviewAction.setState(false);
+            }
+        }
+    };
+
+    public DiagramViewModel getDiagramModel() {
+        return scene.getModel();
+    }
+
+    private void showSatellite() {
+        cardLayout.show(centerPanel, SATELLITE_STRING);
+        satelliteComponent.requestFocus();
+
+    }
+
+    private void showScene() {
+        cardLayout.show(centerPanel, SCENE_STRING);
+        scene.getView().requestFocus();
+    }
+
+    public void findNode() {
+        findPanel.find();
+    }
+
+    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();
+        }
+    }
+
+    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();
+        }
+    }
+
+    public void showPrevDiagram() {
+        int fp = getModel().getFirstPosition();
+        int sp = getModel().getSecondPosition();
+        if (fp != 0) {
+            fp--;
+            sp--;
+            getModel().setPositions(fp, sp);
+        }
+    }
+
+    public DiagramViewModel getModel() {
+        return scene.getModel();
+    }
+
+    public FilterChain getFilterChain() {
+        return this.scene.getModel().getFilterChain();
+    }
+
+    public static EditorTopComponent getActive() {
+        Set<? extends Mode> modes = WindowManager.getDefault().getModes();
+        for (Mode m : modes) {
+            TopComponent tc = m.getSelectedTopComponent();
+            if (tc instanceof EditorTopComponent) {
+                return (EditorTopComponent) tc;
+            }
+        }
+        return null;
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+        // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
+        private void initComponents() {
+                jCheckBox1 = new javax.swing.JCheckBox();
+
+                org.openide.awt.Mnemonics.setLocalizedText(jCheckBox1, "jCheckBox1");
+                jCheckBox1.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
+                jCheckBox1.setMargin(new java.awt.Insets(0, 0, 0, 0));
+
+                setLayout(new java.awt.BorderLayout());
+
+        }// </editor-fold>//GEN-END:initComponents
+        // 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;
+    }
+
+    @Override
+    public void componentOpened() {
+    }
+
+    @Override
+    public void componentClosed() {
+    }
+
+    @Override
+    protected String preferredID() {
+        return PREFERRED_ID;
+    }
+
+    public void changed(RangeSliderModel model) {
+        updateDisplayName();
+    }
+
+    public boolean showPredSucc() {
+        return (Boolean) predSuccAction.getValue(PredSuccAction.STATE);
+    }
+
+    public void setSelection(PropertyMatcher matcher) {
+
+        Properties.PropertySelector<Figure> selector = new Properties.PropertySelector<Figure>(scene.getModel().getDiagramToView().getFigures());
+        List<Figure> list = selector.selectMultiple(matcher);
+        boolean b = scene.getUndoRedoEnabled();
+        scene.setUndoRedoEnabled(false);
+        scene.gotoFigures(list);
+        scene.setUndoRedoEnabled(b);
+        scene.setSelection(list);
+    }
+
+    public void setSelectedNodes(Set<InputNode> nodes) {
+
+        List<Figure> list = new ArrayList<Figure>();
+        Set<Integer> ids = new HashSet<Integer>();
+        for (InputNode n : nodes) {
+            ids.add(n.getId());
+        }
+
+        for (Figure f : scene.getModel().getDiagramToView().getFigures()) {
+            for (InputNode n : f.getSource().getSourceNodes()) {
+                if (ids.contains(n.getId())) {
+                    list.add(f);
+                    break;
+                }
+            }
+        }
+
+        scene.gotoFigures(list);
+        scene.setSelection(list);
+    }
+
+    public void propertyChange(PropertyChangeEvent evt) {
+        if (evt.getSource() == this.predSuccAction) {
+            boolean b = (Boolean) predSuccAction.getValue(PredSuccAction.STATE);
+            this.getModel().setShowNodeHull(b);
+        } else if (evt.getSource() == this.overviewAction) {
+            boolean b = (Boolean) overviewAction.getValue(OverviewAction.STATE);
+            if (b) {
+                showSatellite();
+            } else {
+                showScene();
+            }
+        } else if (evt.getSource() == this.blockLayoutAction) {
+            boolean b = (Boolean) blockLayoutAction.getValue(EnableBlockLayoutAction.STATE);
+            System.out.println("Showblocks = " + b);
+            this.getModel().setShowBlocks(b);
+        } else {
+            assert false : "Unknown event source";
+        }
+    }
+
+    public void extract() {
+        scene.showOnly(scene.getSelectedNodes());
+    }
+
+    public void hideNodes() {
+        Set<Integer> selectedNodes = this.scene.getSelectedNodes();
+        HashSet<Integer> nodes = new HashSet<Integer>(scene.getModel().getHiddenNodes());
+        nodes.addAll(selectedNodes);
+        this.scene.showNot(nodes);
+    }
+
+    public void expandPredecessors() {
+        Set<Figure> oldSelection = scene.getSelectedFigures();
+        Set<Figure> figures = new HashSet<Figure>();
+
+        for (Figure f : this.getDiagramModel().getDiagramToView().getFigures()) {
+            boolean ok = false;
+            if (oldSelection.contains(f)) {
+                ok = true;
+            } else {
+                for (Figure pred : f.getSuccessors()) {
+                    if (oldSelection.contains(pred)) {
+                        ok = true;
+                        break;
+                    }
+                }
+            }
+
+            if (ok) {
+                figures.add(f);
+            }
+        }
+
+        scene.showAll(figures);
+    }
+
+    public void expandSuccessors() {
+        Set<Figure> oldSelection = scene.getSelectedFigures();
+        Set<Figure> figures = new HashSet<Figure>();
+
+        for (Figure f : this.getDiagramModel().getDiagramToView().getFigures()) {
+            boolean ok = false;
+            if (oldSelection.contains(f)) {
+                ok = true;
+            } else {
+                for (Figure succ : f.getPredecessors()) {
+                    if (oldSelection.contains(succ)) {
+                        ok = true;
+                        break;
+                    }
+                }
+            }
+
+            if (ok) {
+                figures.add(f);
+            }
+        }
+
+        scene.showAll(figures);
+    }
+
+    public void showAll() {
+        scene.showNot(new HashSet<Integer>());
+    }
+
+    public Diagram getDiagram() {
+        return getDiagramModel().getDiagramToView();
+    }
+
+    @Override
+    protected void componentActivated() {
+    }
+
+    @Override
+    public void requestFocus() {
+        super.requestFocus();
+        scene.getView().requestFocus();
+    }
+
+    @Override
+    public boolean requestFocusInWindow() {
+        super.requestFocusInWindow();
+        return scene.getView().requestFocusInWindow();
+    }
+
+    @Override
+    public UndoRedo getUndoRedo() {
+        return scene.getUndoRedo();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExportCookie.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,36 @@
+/*
+ * Copyright 1998-2007 Sun Microsystems, Inc.  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.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package com.sun.hotspot.igv.view;
+
+import java.io.File;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public interface ExportCookie {
+
+    void export(File f);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedPanAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedSatelliteComponent.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,200 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.view;
+
+import org.netbeans.api.visual.widget.Scene;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.*;
+
+/**
+ * @author David Kaspar
+ * @author Thomas Wuerthinger
+ */
+public class ExtendedSatelliteComponent extends JComponent implements MouseListener, MouseMotionListener, Scene.SceneListener, ComponentListener {
+
+    private DiagramScene scene;
+    private Image image;
+    private int imageWidth;
+    private int imageHeight;
+
+    public ExtendedSatelliteComponent(DiagramScene scene) {
+        this.scene = scene;
+        setDoubleBuffered(true);
+        setPreferredSize(new Dimension(128, 128));
+        addMouseListener(this);
+        addMouseMotionListener(this);
+    }
+
+    public void addNotify() {
+        super.addNotify();
+        scene.addSceneListener(this);
+        JComponent viewComponent = scene.getView();
+        if (viewComponent == null) {
+            viewComponent = scene.createView();
+        }
+        viewComponent.addComponentListener(this);
+        repaint();
+    }
+
+    public void removeNotify() {
+        scene.getView().removeComponentListener(this);
+        scene.removeSceneListener(this);
+        super.removeNotify();
+    }
+
+    public void update() {
+        this.image = null;
+        if (this.isVisible()) {
+            repaint();
+            revalidate();
+            validate();
+        }
+    }
+
+    public void paint(Graphics g) {
+        Graphics2D gr = (Graphics2D) g;
+        super.paint(g);
+        Rectangle bounds = scene.getBounds();
+        Dimension size = getSize();
+
+        double sx = bounds.width > 0 ? (double) size.width / bounds.width : 0.0;
+        double sy = bounds.width > 0 ? (double) size.height / bounds.height : 0.0;
+        double scale = Math.min(sx, sy);
+
+        int vw = (int) (scale * bounds.width);
+        int vh = (int) (scale * bounds.height);
+        int vx = (size.width - vw) / 2;
+        int vy = (size.height - vh) / 2;
+
+
+        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);
+            scene.paint(ig);
+            scene.setRealZoomFactor(0.0);
+        }
+
+        gr.drawImage(image, vx, vy, this);
+
+        JComponent component = scene.getView();
+        double zoomFactor = scene.getZoomFactor();
+        Rectangle viewRectangle = component != null ? component.getVisibleRect() : null;
+        if (viewRectangle != null) {
+            Rectangle window = new Rectangle(
+                    (int) ((double) viewRectangle.x * scale / zoomFactor),
+                    (int) ((double) viewRectangle.y * scale / zoomFactor),
+                    (int) ((double) viewRectangle.width * scale / zoomFactor),
+                    (int) ((double) viewRectangle.height * scale / zoomFactor));
+            window.translate(vx, vy);
+            gr.setColor(new Color(200, 200, 200, 128));
+            gr.fill(window);
+            gr.setColor(Color.BLACK);
+            gr.drawRect(window.x, window.y, window.width - 1, window.height - 1);
+        }
+    }
+
+    public void mouseClicked(MouseEvent e) {
+    }
+
+    public void mousePressed(MouseEvent e) {
+        moveVisibleRect(e.getPoint());
+    }
+
+    public void mouseReleased(MouseEvent e) {
+        moveVisibleRect(e.getPoint());
+    }
+
+    public void mouseEntered(MouseEvent e) {
+    }
+
+    public void mouseExited(MouseEvent e) {
+    }
+
+    public void mouseDragged(MouseEvent e) {
+        moveVisibleRect(e.getPoint());
+    }
+
+    public void mouseMoved(MouseEvent e) {
+    }
+
+    private void moveVisibleRect(Point center) {
+        JComponent component = scene.getView();
+        if (component == null) {
+            return;
+        }
+        double zoomFactor = scene.getZoomFactor();
+        Rectangle bounds = scene.getBounds();
+        Dimension size = getSize();
+
+        double sx = bounds.width > 0 ? (double) size.width / bounds.width : 0.0;
+        double sy = bounds.width > 0 ? (double) size.height / bounds.height : 0.0;
+        double scale = Math.min(sx, sy);
+
+        int vw = (int) (scale * bounds.width);
+        int vh = (int) (scale * bounds.height);
+        int vx = (size.width - vw) / 2;
+        int vy = (size.height - vh) / 2;
+
+        int cx = (int) ((double) (center.x - vx) / scale * zoomFactor);
+        int cy = (int) ((double) (center.y - vy) / scale * zoomFactor);
+
+        Rectangle visibleRect = component.getVisibleRect();
+        visibleRect.x = cx - visibleRect.width / 2;
+        visibleRect.y = cy - visibleRect.height / 2;
+        component.scrollRectToVisible(visibleRect);
+
+        this.repaint();
+    }
+
+    public void sceneRepaint() {
+    //repaint ();
+    }
+
+    public void sceneValidating() {
+    }
+
+    public void sceneValidated() {
+    }
+
+    public void componentResized(ComponentEvent e) {
+        repaint();
+    }
+
+    public void componentMoved(ComponentEvent e) {
+        repaint();
+    }
+
+    public void componentShown(ComponentEvent e) {
+    }
+
+    public void componentHidden(ComponentEvent e) {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/FindPanel.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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.getProperties()) {
+                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) {
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/GraphViewerImplementation.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.view;
+
+import com.sun.hotspot.igv.data.InputGraph;
+import com.sun.hotspot.igv.data.services.GraphViewer;
+import com.sun.hotspot.igv.graph.Diagram;
+import com.sun.hotspot.igv.settings.Settings;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class GraphViewerImplementation implements GraphViewer {
+
+    public void view(InputGraph graph) {
+        Diagram diagram = Diagram.createDiagram(graph, Settings.get().get(Settings.NODE_TEXT, Settings.NODE_TEXT_DEFAULT));
+        EditorTopComponent tc = new EditorTopComponent(diagram);
+        tc.open();
+        tc.requestActive();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/PreferenceConstants.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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";
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/SlotLayout.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,7 @@
+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...
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/EnableBlockLayoutAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class EnableBlockLayoutAction extends AbstractAction {
+
+    private boolean state;
+    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);
+        putValue(Action.SHORT_DESCRIPTION, "Cluster nodes into blocks");
+    }
+
+    public void actionPerformed(ActionEvent ev) {
+        this.state = !state;
+        this.putValue(STATE, state);
+    }
+
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/blocks.gif";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class ExpandPredecessorsAction extends CallableSystemAction {
+
+    public void performAction() {
+        EditorTopComponent editor = EditorTopComponent.getActive();
+        if (editor != null) {
+            editor.expandPredecessors();
+        }
+    }
+
+    public String getName() {
+        return "Expand Predecessors";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class ExpandSuccessorsAction extends CallableSystemAction {
+
+    public void performAction() {
+        EditorTopComponent editor = EditorTopComponent.getActive();
+        if (editor != null) {
+            editor.expandSuccessors();
+        }
+    }
+
+    public String getName() {
+        return "Expand Successors";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExportAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.view.actions;
+
+import com.sun.hotspot.igv.settings.Settings;
+import com.sun.hotspot.igv.view.ExportCookie;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.io.File;
+import javax.swing.Action;
+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.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class ExportAction extends CallableSystemAction implements LookupListener {
+
+    private final Lookup lookup;
+    private final Lookup.Result<ExportCookie> result;
+
+    public ExportAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Export current graph as an 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.addLookupListener(this);
+        resultChanged(null);
+    }
+
+    public void resultChanged(LookupEvent e) {
+        super.setEnabled(result.allInstances().size() > 0);
+    }
+
+    public void performAction() {
+
+        JFileChooser fc = new JFileChooser();
+        fc.setFileFilter(new FileFilter() {
+
+            public boolean accept(File f) {
+                return true;
+            }
+
+            public String getDescription() {
+                return "SVG files (*.svg)";
+            }
+        });
+        fc.setCurrentDirectory(new File(Settings.get().get(Settings.DIRECTORY, Settings.DIRECTORY_DEFAULT)));
+
+
+        if (fc.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
+            File file = fc.getSelectedFile();
+            if (!file.getName().contains(".")) {
+                file = new File(file.getAbsolutePath() + ".svg");
+            }
+
+            File dir = file;
+            if (!dir.isDirectory()) {
+                dir = dir.getParentFile();
+            }
+
+            Settings.get().put(Settings.DIRECTORY, dir.getAbsolutePath());
+            ExportCookie cookie = Utilities.actionsGlobalContext().lookup(ExportCookie.class);
+            if (cookie != null) {
+                cookie.export(file);
+            }
+        }
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(ExportAction.class, "CTL_ExportAction");
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/export.gif";
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExtractAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 java.awt.Event;
+import java.awt.event.KeyEvent;
+import javax.swing.Action;
+import javax.swing.KeyStroke;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class ExtractAction extends CallableSystemAction {
+
+    public void performAction() {
+        EditorTopComponent editor = EditorTopComponent.getActive();
+        if (editor != null) {
+            editor.extract();
+        }
+    }
+
+    public ExtractAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Extract current set of selected nodes");
+        putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_X, Event.CTRL_MASK, false));
+    }
+
+    public String getName() {
+        return "Extract action";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/extract.gif";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/HideAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 java.awt.Event;
+import java.awt.event.KeyEvent;
+import javax.swing.Action;
+import javax.swing.KeyStroke;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class HideAction extends CallableSystemAction {
+
+    public void performAction() {
+        EditorTopComponent editor = EditorTopComponent.getActive();
+        if (editor != null) {
+            editor.hideNodes();
+        }
+    }
+
+    public HideAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Hide selected nodes");
+        putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_H, Event.CTRL_MASK, false));
+    }
+
+    public String getName() {
+        return "Hide";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/hide.gif";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/MouseOverAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.view.actions;
+
+import org.netbeans.api.visual.action.HoverProvider;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.action.WidgetAction.State;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class MouseOverAction extends WidgetAction.Adapter {
+
+    private long eventID = Integer.MIN_VALUE;
+    private HoverProvider provider;
+
+    public MouseOverAction(HoverProvider provider) {
+        this.provider = provider;
+    }
+
+    @Override
+    public State mouseMoved(Widget widget, WidgetMouseEvent event) {
+        long id = event.getEventID();
+        if (id != eventID) {
+            eventID = id;
+            provider.widgetHovered(widget);
+        }
+        return State.REJECTED;
+    }
+
+    @Override
+    public State mouseExited(Widget widget, WidgetMouseEvent event) {
+        provider.widgetHovered(null);
+        return State.REJECTED;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/NextDiagramAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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 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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class NextDiagramAction extends ContextAction<DiagramViewModel> implements ChangedListener<DiagramViewModel> {
+
+    private DiagramViewModel model;
+
+    public NextDiagramAction() {
+        this(Utilities.actionsGlobalContext());
+    }
+
+    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")));
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(NextDiagramAction.class, "CTL_NextDiagramAction");
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    public Class<DiagramViewModel> contextClass() {
+        return DiagramViewModel.class;
+    }
+
+    @Override
+    public void performAction(DiagramViewModel model) {
+        int fp = model.getFirstPosition();
+        int sp = model.getSecondPosition();
+        if (sp != model.getPositions().size() - 1) {
+            int nfp = fp + 1;
+            int nsp = sp + 1;
+            model.setPositions(nfp, nsp);
+        }
+    }
+
+    @Override
+    public void update(DiagramViewModel model) {
+        super.update(model);
+
+        if (this.model != model) {
+            if (this.model != null) {
+                this.model.getDiagramChangedEvent().removeListener(this);
+            }
+
+            this.model = model;
+            if (this.model != null) {
+                this.model.getDiagramChangedEvent().addListener(this);
+            }
+        }
+    }
+
+    @Override
+    public boolean isEnabled(DiagramViewModel model) {
+        return model.getSecondPosition() != model.getPositions().size() - 1;
+    }
+
+    public Action createContextAwareInstance(Lookup arg0) {
+        return new NextDiagramAction(arg0);
+    }
+
+    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/NodeFindAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/OverviewAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class OverviewAction extends AbstractAction {
+
+    private boolean state;
+    public static final String STATE = "state";
+
+    public OverviewAction() {
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(org.openide.util.Utilities.loadImage(iconResource())));
+        putValue(Action.SHORT_DESCRIPTION, "Show satellite view of whole graph");
+        setState(false);
+    }
+
+    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/overview.gif";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PredSuccAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class PredSuccAction extends AbstractAction {
+
+    private boolean state;
+    public static final String STATE = "state";
+
+    public PredSuccAction() {
+        state = true;
+        putValue(AbstractAction.SMALL_ICON, new ImageIcon(org.openide.util.Utilities.loadImage(iconResource())));
+        putValue(STATE, true);
+        putValue(Action.SHORT_DESCRIPTION, "Show neighboring nodes of fully visible nodes semi-transparent");
+    }
+
+    public void actionPerformed(ActionEvent ev) {
+        this.state = !state;
+        this.putValue(STATE, state);
+    }
+
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/predsucc.gif";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PrevDiagramAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.view.actions;
+
+import com.sun.hotspot.igv.data.ChangedListener;
+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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class PrevDiagramAction extends ContextAction<DiagramViewModel> implements ChangedListener<DiagramViewModel> {
+
+    private DiagramViewModel model;
+
+    public PrevDiagramAction() {
+        this(Utilities.actionsGlobalContext());
+    }
+
+    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")));
+    }
+
+    public String getName() {
+        return NbBundle.getMessage(PrevDiagramAction.class, "CTL_PrevDiagramAction");
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    public Class<DiagramViewModel> contextClass() {
+        return DiagramViewModel.class;
+    }
+
+    @Override
+    public void performAction(DiagramViewModel model) {
+        int fp = model.getFirstPosition();
+        int sp = model.getSecondPosition();
+        if (fp != 0) {
+            int nfp = fp - 1;
+            int nsp = sp - 1;
+            model.setPositions(nfp, nsp);
+        }
+    }
+
+    @Override
+    public void update(DiagramViewModel model) {
+        super.update(model);
+
+        if (this.model != model) {
+            if (this.model != null) {
+                this.model.getDiagramChangedEvent().removeListener(this);
+            }
+
+            this.model = model;
+            if (this.model != null) {
+                this.model.getDiagramChangedEvent().addListener(this);
+            }
+        }
+    }
+
+    @Override
+    public boolean isEnabled(DiagramViewModel model) {
+        return model.getFirstPosition() != 0;
+    }
+
+    public Action createContextAwareInstance(Lookup arg0) {
+        return new PrevDiagramAction(arg0);
+    }
+
+    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/ShowAllAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.view.actions;
+
+import com.sun.hotspot.igv.view.*;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import javax.swing.Action;
+import javax.swing.KeyStroke;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class ShowAllAction extends CallableSystemAction {
+
+    public void performAction() {
+        EditorTopComponent editor = EditorTopComponent.getActive();
+        if (editor != null) {
+            editor.showAll();
+        }
+    }
+
+    public ShowAllAction() {
+        putValue(Action.SHORT_DESCRIPTION, "Show all nodes");
+        putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK));
+    }
+
+    public String getName() {
+        return "Show all";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/expand.gif";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ZoomInAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 java.awt.Event;
+import java.awt.event.KeyEvent;
+import javax.swing.Action;
+import javax.swing.KeyStroke;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class ZoomInAction extends CallableSystemAction {
+
+    public void performAction() {
+        EditorTopComponent editor = EditorTopComponent.getActive();
+        if (editor != null) {
+            editor.zoomIn();
+        }
+    }
+
+    public String getName() {
+        return "Zoom in";
+    }
+
+    public ZoomInAction() {
+        putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_EQUALS, Event.CTRL_MASK, false));
+        putValue(Action.SHORT_DESCRIPTION, "Zoom in");
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/zoomin.gif";
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ZoomOutAction.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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 java.awt.Event;
+import java.awt.event.KeyEvent;
+import javax.swing.Action;
+import javax.swing.KeyStroke;
+import org.openide.util.HelpCtx;
+import org.openide.util.actions.CallableSystemAction;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public final class ZoomOutAction extends CallableSystemAction {
+
+    public void performAction() {
+        EditorTopComponent editor = EditorTopComponent.getActive();
+        if (editor != null) {
+            editor.zoomOut();
+        }
+    }
+
+    public ZoomOutAction() {
+
+        putValue(Action.SHORT_DESCRIPTION, "Zoom out");
+        putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, Event.CTRL_MASK, false));
+    }
+
+    public String getName() {
+        return "Zoom out";
+    }
+
+    @Override
+    protected void initialize() {
+        super.initialize();
+    }
+
+    public HelpCtx getHelpCtx() {
+        return HelpCtx.DEFAULT_HELP;
+    }
+
+    @Override
+    protected boolean asynchronous() {
+        return false;
+    }
+
+    @Override
+    protected String iconResource() {
+        return "com/sun/hotspot/igv/view/images/zoomout.gif";
+    }
+}
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/blocks.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/expand.gif has changed
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/extract.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/hide.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/next_diagram.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/predsucc.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/prev_diagram.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/zoomin.gif has changed
Binary file hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoomout.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,59 @@
+<?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="Actions">
+        <folder name="File">
+            <file name="com-sun-hotspot-igv-view-actions-ExportAction.instance">
+                <attr name="position" intvalue="1100"/>
+            </file>
+        </folder>
+        <folder name="View">
+            <file name="com-sun-hotspot-igv-view-actions-NextDiagramAction.instance"><attr name="position" intvalue="2000"/></file>
+            <file name="com-sun-hotspot-igv-view-actions-PrevDiagramAction.instance"><attr name="position" intvalue="2001"/></file>
+            <file name="com-sun-hotspot-igv-view-actions-ShowAllAction.instance"><attr name="position" intvalue="2001"/></file>
+            <file name="com-sun-hotspot-igv-view-actions-ExtractAction.instance"><attr name="position" intvalue="2001"/></file>
+            <file name="com-sun-hotspot-igv-view-actions-HideAction.instance"><attr name="position" intvalue="2001"/></file>
+            <file name="com-sun-hotspot-igv-view-actions-ZoomInAction.instance"><attr name="position" intvalue="2001"/></file>
+            <file name="com-sun-hotspot-igv-view-actions-ZoomOutAction.instance"><attr name="position" intvalue="2001"/></file>
+            <file name="com-sun-hotspot-igv-view-actions-OverviewAction.instance"><attr name="position" intvalue="2001"/></file>
+            <file name="com-sun-hotspot-igv-view-actions-PredSuccAction.instance"><attr name="position" intvalue="2001"/></file>
+            <file name="com-sun-hotspot-igv-view-actions-EnableBlockLayoutAction.instance"><attr name="position" intvalue="2001"/></file>
+        </folder>
+    </folder>
+    <folder name="Menu">
+        <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"/>
+            </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"/>
+            </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"/>
+            </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"/>
+            </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"/>
+            </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"/>
+            </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"/>
+            </file>
+        </folder>
+        <folder name="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"/>
+            </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>
+    </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/widgets/BlockWidget.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.view.widgets;
+
+import com.sun.hotspot.igv.data.InputBlock;
+import com.sun.hotspot.igv.graph.Diagram;
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.Stroke;
+import java.awt.geom.Rectangle2D;
+import org.netbeans.api.visual.widget.Scene;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class BlockWidget extends Widget {
+
+    public static final int BORDER = 20;
+    public static final Color BACKGROUND_COLOR = new Color(235, 235, 255);
+    private static final Font titleFont = new Font("Serif", Font.PLAIN, 14).deriveFont(Font.BOLD);
+    private InputBlock blockNode;
+    private Diagram diagram;
+
+    public BlockWidget(Scene scene, Diagram d, InputBlock blockNode) {
+        super(scene);
+        this.blockNode = blockNode;
+        this.diagram = d;
+        this.setBackground(BACKGROUND_COLOR);
+        this.setOpaque(true);
+        this.setCheckClipping(true);
+    }
+
+    @Override
+    protected void paintWidget() {
+        super.paintWidget();
+        Graphics2D g = this.getGraphics();
+        Stroke old = g.getStroke();
+        g.setColor(Color.BLUE);
+        Rectangle r = new Rectangle(this.getPreferredBounds());
+        r.width--;
+        r.height--;
+        if (this.getBounds().width > 0 && this.getBounds().height > 0) {
+            g.setStroke(new BasicStroke(2));
+            g.drawRect(r.x, r.y, r.width, r.height);
+        }
+
+        Color titleColor = Color.BLACK;
+        g.setColor(titleColor);
+        g.setFont(titleFont);
+
+        String s = "B" + blockNode.toString();
+        Rectangle2D r1 = g.getFontMetrics().getStringBounds(s, g);
+        g.drawString(s, r.x + 5, r.y + (int) r1.getHeight());
+        g.setStroke(old);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/DiagramConnectionWidget.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,251 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/FigureWidget.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,358 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.view.widgets;
+
+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.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 java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Set;
+import javax.swing.Action;
+import javax.swing.BorderFactory;
+import javax.swing.JMenu;
+import javax.swing.JPopupMenu;
+import org.netbeans.api.visual.action.PopupMenuProvider;
+import org.netbeans.api.visual.action.WidgetAction;
+import org.netbeans.api.visual.model.ObjectState;
+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;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+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;
+    private Widget middleWidget;
+    private ArrayList<LabelWidget> labelWidgets;
+    private DiagramScene diagramScene;
+    private boolean boundary;
+    private Node node;
+
+    public void setBoundary(boolean b) {
+        boundary = b;
+    }
+
+    public boolean isBoundary() {
+        return boundary;
+    }
+
+    public Node getNode() {
+        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;
+    }
+
+    public FigureWidget(final Figure f, DiagramScene s, Widget parent) {
+
+        super(s);
+
+
+        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());
+
+        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);
+
+        if (VERTICAL_LAYOUT) {
+            this.setLayout(LayoutFactory.createVerticalFlowLayout());
+        } else {
+            this.setLayout(LayoutFactory.createHorizontalFlowLayout());
+        }
+
+        middleWidget.setLayout(LayoutFactory.createVerticalFlowLayout());
+
+        middleWidget.setBackground(f.getColor());
+        middleWidget.setOpaque(true);
+        assert this.getScene() != null;
+        assert this.getScene().getView() != null;
+        middleWidget.setBorder(BorderFactory.createLineBorder(Color.BLACK));
+
+
+        labelWidgets = new ArrayList<LabelWidget>();
+
+        String[] strings = figure.getLines();
+
+        for (String cur : strings) {
+
+            String displayString = cur;
+
+            LabelWidget lw = new LabelWidget(s);
+            labelWidgets.add(lw);
+            middleWidget.addChild(lw);
+            lw.setLabel(displayString);
+
+            lw.setFont(font);
+            lw.setForeground(Color.BLACK);
+            lw.setAlignment(LabelWidget.Alignment.CENTER);
+            lw.setVerticalAlignment(LabelWidget.VerticalAlignment.CENTER);
+            lw.setMaximumSize(new Dimension(f.getWidth(), 20000));
+            lw.setMinimumSize(new Dimension(f.getWidth(), 20));
+        }
+
+        rightWidget = new Widget(s);
+        this.addChild(rightWidget);
+        rightWidget.setLayout(new SlotLayout(SlotLayout.HorizontalAlignment.Left, VERTICAL_LAYOUT));//LayoutFactory.createVerticalLayout(LayoutFactory.SerialAlignment.JUSTIFY, 0));
+
+        // Initialize node for property sheet
+        node = new AbstractNode(Children.LEAF) {
+
+            @Override
+            protected Sheet createSheet() {
+                Sheet s = super.createSheet();
+                PropertiesSheet.initializeSheet(f.getProperties(), s);
+                return s;
+            }
+        };
+        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;
+    }
+
+    public Widget getRightWidget() {
+        return rightWidget;
+    }
+
+    @Override
+    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
+        super.notifyStateChanged(previousState, state);
+
+        Color borderColor = Color.BLACK;
+        int thickness = 1;
+        boolean repaint = false;
+        Font f = font;
+        if (state.isSelected()) {
+            thickness = 1;
+            f = boldFont;
+        }
+
+        if (state.isHovered()) {
+            borderColor = Color.BLUE;
+        }
+
+        if (state.isHovered() != previousState.isHovered()) {
+            repaint = true;
+        }
+
+        if (state.isSelected() != previousState.isSelected()) {
+            repaint = true;
+        }
+
+        if (repaint) {
+            middleWidget.setBorder(BorderFactory.createLineBorder(borderColor, thickness));
+            for (LabelWidget labelWidget : labelWidgets) {
+                labelWidget.setFont(f);
+            }
+            repaint();
+        }
+    }
+
+    public String getName() {
+        return getProperties().get("name");
+    }
+
+    public Properties getProperties() {
+        return figure.getProperties();
+    }
+
+    public Figure getFigure() {
+        return figure;
+    }
+
+    @Override
+    protected void paintChildren() {
+
+        if (diagramScene.getRealZoomFactor() < ZOOM_FACTOR && diagramScene.getModel().getShowBlocks()) {
+            return;
+        }
+
+        Composite oldComposite = null;
+        if (boundary) {
+            oldComposite = getScene().getGraphics().getComposite();
+            float alpha = DiagramScene.ALPHA;
+            this.getScene().getGraphics().setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
+        }
+
+        if (diagramScene.getRealZoomFactor() < LABEL_ZOOM_FACTOR) {
+
+            for (LabelWidget labelWidget : labelWidgets) {
+                labelWidget.setVisible(false);
+            }
+            super.paintChildren();
+            for (LabelWidget labelWidget : labelWidgets) {
+                labelWidget.setVisible(true);
+            }
+
+        } else {
+            super.paintChildren();
+        }
+
+        if (boundary) {
+            getScene().getGraphics().setComposite(oldComposite);
+        }
+    }
+
+    public JPopupMenu getPopupMenu(Widget widget, Point point) {
+        JPopupMenu m = diagramScene.createPopupMenu();
+
+        JMenu predecessors = new JMenu("Predecessors");
+        addFigureToSubMenu(predecessors, getFigure(), false, DEPTH);
+
+        JMenu successors = new JMenu("Successors");
+        addFigureToSubMenu(successors, getFigure(), true, DEPTH);
+
+        m.addSeparator();
+        m.add(predecessors);
+        m.add(successors);
+        return m;
+    }
+
+    public void addFigureToSubMenu(JMenu subMenu, final Figure f, boolean successor, int depth) {
+        Set<Figure> set = f.getPredecessorSet();
+        if (successor) {
+            set = f.getSuccessorSet();
+        }
+
+        int count = set.size();
+        if (set.contains(f)) {
+            count--;
+        }
+
+        for (Figure f2 : set) {
+            if (f2 == f) {
+                continue;
+            }
+
+            count--;
+            addFigureToMenu(subMenu, f2, successor, depth - 1);
+            if (count > 0) {
+                subMenu.addSeparator();
+            }
+        }
+    }
+
+    public void addFigureToMenu(JMenu m, final Figure f, boolean successor, int depth) {
+
+        Action a = diagramScene.createGotoAction(f);
+
+
+        m.add(a);
+
+        if (depth > 0) {
+            String name = "Predecessors";
+            if (successor) {
+                name = "Successors";
+            }
+
+            JMenu subMenu = new JMenu(name);
+            addFigureToSubMenu(subMenu, f, successor, depth);
+            m.add(subMenu);
+        }
+
+    }
+
+    public void handleDoubleClick(Widget w, WidgetAction.WidgetMouseEvent e) {
+
+        if (diagramScene.isAllVisible()) {
+            Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getGraphToView().getGroup().getAllNodes());
+            hiddenNodes.removeAll(this.getFigure().getSource().getSourceNodesAsSet());
+            this.diagramScene.showNot(hiddenNodes);
+        } else if (isBoundary()) {
+
+            Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getHiddenNodes());
+            hiddenNodes.removeAll(this.getFigure().getSource().getSourceNodesAsSet());
+            this.diagramScene.showNot(hiddenNodes);
+        } else {
+            Set<Integer> hiddenNodes = new HashSet<Integer>(diagramScene.getModel().getHiddenNodes());
+            hiddenNodes.addAll(this.getFigure().getSource().getSourceNodesAsSet());
+            this.diagramScene.showNot(hiddenNodes);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/InputSlotWidget.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.view.widgets;
+
+import com.sun.hotspot.igv.graph.InputSlot;
+import com.sun.hotspot.igv.view.DiagramScene;
+import java.awt.Point;
+import java.util.List;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class InputSlotWidget extends SlotWidget {
+
+    private InputSlot inputSlot;
+
+    public InputSlotWidget(InputSlot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
+        super(slot, scene, parent, fw);
+        inputSlot = slot;
+        init();
+        getFigureWidget().getLeftWidget().addChild(this);
+    }
+
+    public InputSlot getInputSlot() {
+        return inputSlot;
+    }
+
+    protected Point calculateRelativeLocation() {
+        if (getFigureWidget().getBounds() == null) {
+            return new Point(0, 0);
+        }
+
+        double x = 0;
+        List<InputSlot> slots = inputSlot.getFigure().getInputSlots();
+        assert slots.contains(inputSlot);
+        return new Point((int) x, (int) (calculateRelativeY(slots.size(), slots.indexOf(inputSlot))));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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.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.List;
+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.animator.SceneAnimator;
+import org.netbeans.api.visual.model.ObjectState;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class LineWidget extends Widget implements PopupMenuProvider {
+
+    public final int BORDER = 8;
+    public final int ARROW_SIZE = 6;
+    public final int BOLD_ARROW_SIZE = 7;
+    public final int HOVER_ARROW_SIZE = 8;
+    public final int BOLD_STROKE_WIDTH = 2;
+    public final int HOVER_STROKE_WIDTH = 3;
+    private static double ZOOM_FACTOR = 0.1;
+    private OutputSlot outputSlot;
+    private DiagramScene scene;
+    private List<Connection> connections;
+    private Point from;
+    private Point to;
+    private Rectangle clientArea;
+    private Color color = Color.BLACK;
+    private LineWidget predecessor;
+    private List<LineWidget> successors;
+    private boolean highlighted;
+    private boolean popupVisible;
+    private boolean isBold;
+    private boolean isDashed;
+
+    public LineWidget(DiagramScene scene, OutputSlot s, List<Connection> connections, Point from, Point to, LineWidget predecessor, SceneAnimator animator, boolean isBold, boolean isDashed) {
+        super(scene);
+        this.scene = scene;
+        this.outputSlot = s;
+        this.connections = connections;
+        this.from = from;
+        this.to = to;
+        this.predecessor = predecessor;
+        this.successors = new ArrayList<LineWidget>();
+        if (predecessor != null) {
+            predecessor.addSuccessor(this);
+        }
+
+        this.isBold = isBold;
+        this.isDashed = isDashed;
+
+        int minX = from.x;
+        int minY = from.y;
+        int maxX = to.x;
+        int maxY = to.y;
+        if (minX > maxX) {
+            int tmp = minX;
+            minX = maxX;
+            maxX = tmp;
+        }
+
+        if (minY > maxY) {
+            int tmp = minY;
+            minY = maxY;
+            maxY = tmp;
+        }
+
+        clientArea = new Rectangle(minX, minY, maxX - minX + 1, maxY - minY + 1);
+        clientArea.grow(BORDER, BORDER);
+
+        if (connections.size() > 0) {
+            color = connections.get(0).getColor();
+        }
+
+        this.setCheckClipping(true);
+
+        this.getActions().addAction(ActionFactory.createPopupMenuAction(this));
+        if (animator == null) {
+            this.setBackground(color);
+        } else {
+            this.setBackground(Color.WHITE);
+            animator.animateBackgroundColor(this, color);
+        }
+    }
+
+    public Point getFrom() {
+        return from;
+    }
+
+    public Point getTo() {
+        return to;
+    }
+
+    private void addSuccessor(LineWidget widget) {
+        this.successors.add(widget);
+    }
+
+    @Override
+    protected Rectangle calculateClientArea() {
+        return clientArea;
+    }
+
+    @Override
+    protected void paintWidget() {
+        if (scene.getRealZoomFactor() < ZOOM_FACTOR) {
+            return;
+        }
+
+        Graphics2D g = getScene().getGraphics();
+        g.setPaint(this.getBackground());
+        ObjectState state = this.getState();
+        float width = 1.0f;
+
+        if (isBold) {
+            width = BOLD_STROKE_WIDTH;
+        }
+
+        if (highlighted || popupVisible) {
+            width = HOVER_STROKE_WIDTH;
+        }
+
+        Stroke oldStroke = g.getStroke();
+        if (isDashed) {
+            float[] dashPattern = {5, 5, 5, 5};
+            g.setStroke(new BasicStroke(width, BasicStroke.CAP_BUTT,
+                    BasicStroke.JOIN_MITER, 10,
+                    dashPattern, 0));
+        } else {
+            g.setStroke(new BasicStroke(width));
+        }
+
+        g.drawLine(from.x, from.y, to.x, to.y);
+
+        boolean sameFrom = false;
+        boolean sameTo = successors.size() == 0;
+        for (LineWidget w : successors) {
+            if (w.getFrom().equals(getTo())) {
+                sameTo = true;
+            }
+        }
+
+        if (predecessor == null || predecessor.getTo().equals(getFrom())) {
+            sameFrom = true;
+        }
+
+
+        int size = ARROW_SIZE;
+        if (isBold) {
+            size = BOLD_ARROW_SIZE;
+        }
+        if (highlighted || popupVisible) {
+            size = HOVER_ARROW_SIZE;
+        }
+        if (!sameFrom) {
+            g.fillPolygon(
+                    new int[]{from.x - size / 2, from.x + size / 2, from.x},
+                    new int[]{from.y - size / 2, from.y - size / 2, from.y + size / 2},
+                    3);
+        }
+        if (!sameTo) {
+            g.fillPolygon(
+                    new int[]{to.x - size / 2, to.x + size / 2, to.x},
+                    new int[]{to.y - size / 2, to.y - size / 2, to.y + size / 2},
+                    3);
+        }
+        g.setStroke(oldStroke);
+    }
+
+    private void setHighlighted(boolean b) {
+        this.highlighted = b;
+        this.revalidate(true);
+    }
+
+    private void setPopupVisible(boolean b) {
+        this.popupVisible = b;
+        this.revalidate(true);
+    }
+
+    @Override
+    public boolean isHitAt(Point localPoint) {
+        return Line2D.ptLineDistSq(from.x, from.y, to.x, to.y, localPoint.x, localPoint.y) <= BORDER * BORDER;
+    }
+
+    @Override
+    protected void notifyStateChanged(ObjectState previousState, ObjectState state) {
+        if (previousState.isHovered() != state.isHovered()) {
+            setRecursiveHighlighted(state.isHovered());
+        }
+    }
+
+    private void setRecursiveHighlighted(boolean b) {
+        LineWidget cur = predecessor;
+        while (cur != null) {
+            cur.setHighlighted(b);
+            cur = cur.predecessor;
+        }
+
+        highlightSuccessors(b);
+        this.setHighlighted(b);
+    }
+
+    private void highlightSuccessors(boolean b) {
+        for (LineWidget s : successors) {
+            s.setHighlighted(b);
+            s.highlightSuccessors(b);
+        }
+    }
+
+    private void setRecursivePopupVisible(boolean b) {
+        LineWidget cur = predecessor;
+        while (cur != null) {
+            cur.setPopupVisible(b);
+            cur = cur.predecessor;
+        }
+
+        popupVisibleSuccessors(b);
+        setPopupVisible(b);
+    }
+
+    private void popupVisibleSuccessors(boolean b) {
+        for (LineWidget s : successors) {
+            s.setPopupVisible(b);
+            s.popupVisibleSuccessors(b);
+        }
+    }
+
+    public JPopupMenu getPopupMenu(Widget widget, Point localLocation) {
+        JPopupMenu menu = new JPopupMenu();
+        menu.add(scene.createGotoAction(outputSlot.getFigure()));
+        menu.addSeparator();
+
+        for (Connection c : connections) {
+            InputSlot s = c.getInputSlot();
+            menu.add(scene.createGotoAction(s.getFigure()));
+        }
+
+        final LineWidget w = this;
+        menu.addPopupMenuListener(new PopupMenuListener() {
+
+            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+                w.setRecursivePopupVisible(true);
+            }
+
+            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
+                w.setRecursivePopupVisible(false);
+            }
+
+            public void popupMenuCanceled(PopupMenuEvent e) {
+            }
+        });
+
+        return menu;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/MultiConnectionWidget.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,281 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/OutputSlotWidget.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+package com.sun.hotspot.igv.view.widgets;
+
+import com.sun.hotspot.igv.graph.OutputSlot;
+import com.sun.hotspot.igv.view.DiagramScene;
+import java.awt.Point;
+import java.util.List;
+import org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public class OutputSlotWidget extends SlotWidget {
+
+    private OutputSlot outputSlot;
+
+    public OutputSlotWidget(OutputSlot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
+        super(slot, scene, parent, fw);
+        outputSlot = slot;
+        init();
+        getFigureWidget().getRightWidget().addChild(this);
+    }
+
+    public OutputSlot getOutputSlot() {
+        return outputSlot;
+    }
+
+    protected Point calculateRelativeLocation() {
+        if (getFigureWidget().getBounds() == null) {
+            return new Point(0, 0);
+        }
+
+        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))));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/SlotWidget.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ *
+ */
+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.graph.Slot;
+import com.sun.hotspot.igv.view.*;
+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 org.netbeans.api.visual.widget.Widget;
+
+/**
+ *
+ * @author Thomas Wuerthinger
+ */
+public abstract class SlotWidget extends Widget {
+
+    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;
+
+    public SlotWidget(Slot slot, DiagramScene scene, Widget parent, FigureWidget fw) {
+        super(scene);
+        this.scene = scene;
+        this.slot = slot;
+        figureWidget = fw;
+        this.setToolTipText("<HTML>" + slot.getName() + "</HTML>");
+        this.setCheckClipping(true);
+    }
+
+    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);
+    }
+
+    public Slot getSlot() {
+        return slot;
+    }
+
+    public FigureWidget getFigureWidget() {
+        return figureWidget;
+    }
+
+    @Override
+    protected void paintWidget() {
+
+        if (scene.getRealZoomFactor() < 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;
+
+            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);
+            } else {
+
+                if (slot instanceof OutputSlot) {
+                    g.fillArc(w / 4, -h / 4 - 1, w / 2, h / 2, 180, 180);
+                } else {
+                    g.fillArc(w / 4, 3 * h / 4, w / 2, h / 2, 0, 180);
+                }
+            }
+        }
+    }
+
+    @Override
+    protected Rectangle calculateClientArea() {
+        return new Rectangle(0, 0, Figure.SLOT_WIDTH, Figure.SLOT_WIDTH);
+    }
+
+    protected abstract Point calculateRelativeLocation();
+
+    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);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,7 @@
+currentVersion=IdealGraphVisualizer {0}
+LBL_splash_window_title=Starting IdealGraphVisualizer
+SPLASH_WIDTH=475
+SplashProgressBarBounds=0,268,473,6
+SplashProgressBarColor=0xFFFFFF
+SplashRunningTextBounds=269,253,205,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/splash.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,2 @@
+CTL_MainWindow_Title=IdealGraphVisualizer {0}
+CTL_MainWindow_Title_No_Project=IdealGraphVisualizer {0}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/build.xml	Wed Jul 05 16:38:46 2017 +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="IdealGraphVisualizer" basedir=".">
+    <description>Builds the module suite IdealGraphVisualizer.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/build-impl.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="IdealGraphVisualizer-impl" basedir=".." xmlns:sproject="http://www.netbeans.org/ns/nb-module-suite-project/1">
+    <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">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" 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'">
+        <condition>
+            <not>
+                <available file="${harness.dir}" type="dir"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/suite.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/genfiles.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=72833581
+build.xml.script.CRC32=e9c757c5
+build.xml.stylesheet.CRC32=531c622b
+# 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,29 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    harness,\
+    ide8,\
+    java1,\
+    nb6.0,\
+    profiler2
+disabled.modules=\
+    org.netbeans.core.execution,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.modules.applemenu,\
+    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=\
+    platform7
+nbjdk.active=default
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,40 @@
+app.icon=branding/core/core.jar/org/netbeans/core/startup/frame48.gif
+app.name=idealgraphvisualizer
+app.title=IdealGraphVisualizer
+branding.token=${app.name}
+modules=\
+    ${project.com.sun.hotspot.igv.graph}:\
+    ${project.com.sun.hotspot.igv.coordinator}:\
+    ${project.com.sun.hotspot.igv.filter}:\
+    ${project.com.sun.hotspot.igv.hierarchicallayout}:\
+    ${project.com.sun.hotspot.igv.layout}:\
+    ${project.com.sun.hotspot.igv.controlflow}:\
+    ${project.com.sun.hotspot.igv.data}:\
+    ${project.com.sun.hotspot.igv.view}:\
+    ${project.com.sun.hotspot.igv.bytecodes}:\
+    ${project.com.sun.hotspot.igv.difference}:\
+    ${project.com.sun.hotspot.igv.settings}:\
+    ${project.com.sun.hotspot.igv.util}:\
+    ${project.com.sun.hotspot.igv.rhino}:\
+    ${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.connection=NetworkConnection
+project.com.sun.hotspot.igv.bytecodes=Bytecodes
+project.com.sun.hotspot.igv.controlflow=ControlFlow
+project.com.sun.hotspot.igv.coordinator=Coordinator
+project.com.sun.hotspot.igv.data=Data
+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.graph=Graph
+project.com.sun.hotspot.igv.hierarchicallayout=HierarchicalLayout
+project.com.sun.hotspot.igv.layout=Layout
+project.com.sun.hotspot.igv.rhino=RhinoScriptEngineProxy
+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 = -server -J-Xms64m -J-Xmx512m -J-da
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/src/share/tools/IdealGraphVisualizer/nbproject/project.xml	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://www.netbeans.org/ns/project/1">
+    <type>org.netbeans.modules.apisupport.project.suite</type>
+    <configuration>
+        <data xmlns="http://www.netbeans.org/ns/nb-module-suite-project/1">
+            <name>IdealGraphVisualizer</name>
+        </data>
+    </configuration>
+</project>
--- a/hotspot/src/share/tools/MakeDeps/Database.java	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/tools/MakeDeps/Database.java	Wed Jul 05 16:38:46 2017 +0200
@@ -36,6 +36,7 @@
   private FileList outerFiles;
   private FileList indivIncludes;
   private FileList grandInclude; // the results for the grand include file
+  private HashMap<String,String> platformDepFiles;
   private long threshold;
   private int nOuterFiles;
   private int nPrecompiledFiles;
@@ -57,6 +58,7 @@
     outerFiles      = new FileList("outerFiles", plat);
     indivIncludes   = new FileList("IndivIncludes", plat);
     grandInclude    = new FileList(plat.getGIFileTemplate().nameOfList(), plat);
+    platformDepFiles = new HashMap<String,String>();
 
     threshold = t;
     nOuterFiles = 0;
@@ -209,6 +211,10 @@
               FileList p = allFiles.listForFile(includer);
               p.setPlatformDependentInclude(pdName.dirPreStemSuff());
 
+              // Record the implicit include of this file so that the
+              // dependencies for precompiled headers can mention it.
+              platformDepFiles.put(newIncluder, includer);
+
               // Add an implicit dependency on platform
               // specific file for the generic file
 
@@ -408,6 +414,12 @@
       for (Iterator iter = grandInclude.iterator(); iter.hasNext(); ) {
         FileList list = (FileList) iter.next();
         gd.println(list.getName() + " \\");
+        String platformDep = platformDepFiles.get(list.getName());
+        if (platformDep != null) {
+            // make sure changes to the platform dependent file will
+            // cause regeneration of the pch file.
+            gd.println(platformDep + " \\");
+        }
       }
       gd.println();
       gd.println();
--- a/hotspot/src/share/vm/adlc/adlc.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/adlc/adlc.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -29,11 +29,7 @@
 // standard library constants
 #include "stdio.h"
 #include "stdlib.h"
-#if _MSC_VER >= 1300  // Visual C++ 7.0 or later
 #include <iostream>
-#else
-#include <iostream.h>
-#endif
 #include "string.h"
 #include "ctype.h"
 #include "stdarg.h"
--- a/hotspot/src/share/vm/adlc/filebuff.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/adlc/filebuff.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -23,13 +23,9 @@
  */
 
 // FILEBUFF.HPP - Definitions for parser file buffering routines
+#include <iostream>
 
-#if _MSC_VER >= 1300  // Visual C++ 7.0 or later
-#include <iostream>
-#else
-#include <iostream.h>
-#endif
-
+using namespace std;
 // STRUCTURE FOR HANDLING INPUT AND OUTPUT FILES
 typedef struct {
   const char *_name;
--- a/hotspot/src/share/vm/adlc/formssel.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/adlc/formssel.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -729,6 +729,7 @@
         !strcmp(_matrule->_rChild->_opType,"DecodeN")    ||
         !strcmp(_matrule->_rChild->_opType,"EncodeP")    ||
         !strcmp(_matrule->_rChild->_opType,"LoadN")      ||
+        !strcmp(_matrule->_rChild->_opType,"LoadNKlass") ||
         !strcmp(_matrule->_rChild->_opType,"CreateEx")   ||  // type of exception
         !strcmp(_matrule->_rChild->_opType,"CheckCastPP")) ) return true;
   else if ( is_ideal_load() == Form::idealP )                return true;
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -1004,6 +1004,9 @@
 
   DEBUG_ONLY(mark_bitmap()->verify_clear();)
   DEBUG_ONLY(summary_data().verify_clear();)
+
+  // Have worker threads release resources the next time they run a task.
+  gc_task_manager()->release_all_resources();
 }
 
 void PSParallelCompact::post_compact()
@@ -1949,12 +1952,6 @@
   TimeStamp compaction_start;
   TimeStamp collection_exit;
 
-  // "serial_CM" is needed until the parallel implementation
-  // of the move and update is done.
-  ParCompactionManager* serial_CM = new ParCompactionManager();
-  // Don't initialize more than once.
-  // serial_CM->initialize(&summary_data(), mark_bitmap());
-
   ParallelScavengeHeap* heap = gc_heap();
   GCCause::Cause gc_cause = heap->gc_cause();
   PSYoungGen* young_gen = heap->young_gen();
@@ -1969,6 +1966,10 @@
   PreGCValues pre_gc_values;
   pre_compact(&pre_gc_values);
 
+  // Get the compaction manager reserved for the VM thread.
+  ParCompactionManager* const vmthread_cm =
+    ParCompactionManager::manager_array(gc_task_manager()->workers());
+
   // Place after pre_compact() where the number of invocations is incremented.
   AdaptiveSizePolicyOutput(size_policy, heap->total_collections());
 
@@ -2008,7 +2009,7 @@
     bool marked_for_unloading = false;
 
     marking_start.update();
-    marking_phase(serial_CM, maximum_heap_compaction);
+    marking_phase(vmthread_cm, maximum_heap_compaction);
 
 #ifndef PRODUCT
     if (TraceParallelOldGCMarkingPhase) {
@@ -2039,7 +2040,7 @@
 #endif
 
     bool max_on_system_gc = UseMaximumCompactionOnSystemGC && is_system_gc;
-    summary_phase(serial_CM, maximum_heap_compaction || max_on_system_gc);
+    summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
 
 #ifdef ASSERT
     if (VerifyParallelOldWithMarkSweep &&
@@ -2067,13 +2068,13 @@
       // code can use the the forwarding pointers to
       // check the new pointer calculation.  The restore_marks()
       // has to be done before the real compact.
-      serial_CM->set_action(ParCompactionManager::VerifyUpdate);
-      compact_perm(serial_CM);
-      compact_serial(serial_CM);
-      serial_CM->set_action(ParCompactionManager::ResetObjects);
-      compact_perm(serial_CM);
-      compact_serial(serial_CM);
-      serial_CM->set_action(ParCompactionManager::UpdateAndCopy);
+      vmthread_cm->set_action(ParCompactionManager::VerifyUpdate);
+      compact_perm(vmthread_cm);
+      compact_serial(vmthread_cm);
+      vmthread_cm->set_action(ParCompactionManager::ResetObjects);
+      compact_perm(vmthread_cm);
+      compact_serial(vmthread_cm);
+      vmthread_cm->set_action(ParCompactionManager::UpdateAndCopy);
 
       // For debugging only
       PSMarkSweep::restore_marks();
@@ -2084,16 +2085,14 @@
     compaction_start.update();
     // Does the perm gen always have to be done serially because
     // klasses are used in the update of an object?
-    compact_perm(serial_CM);
+    compact_perm(vmthread_cm);
 
     if (UseParallelOldGCCompacting) {
       compact();
     } else {
-      compact_serial(serial_CM);
+      compact_serial(vmthread_cm);
     }
 
-    delete serial_CM;
-
     // Reset the mark bitmap, summary data, and do other bookkeeping.  Must be
     // done before resizing.
     post_compact();
--- a/hotspot/src/share/vm/includeDB_compiler2	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/includeDB_compiler2	Wed Jul 05 16:38:46 2017 +0200
@@ -1084,6 +1084,7 @@
 idealGraphPrinter.hpp                   vectset.hpp
 idealGraphPrinter.hpp                   growableArray.hpp
 idealGraphPrinter.hpp                   ostream.hpp
+idealGraphPrinter.hpp                   xmlstream.hpp
 
 idealGraphPrinter.cpp                   idealGraphPrinter.hpp
 idealGraphPrinter.cpp                   chaitin.hpp
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -196,6 +196,8 @@
   assert(_whole_heap.contains(new_region),
            "attempt to cover area not in reserved area");
   debug_only(verify_guard();)
+  // collided is true if the expansion would push into another committed region
+  debug_only(bool collided = false;)
   int const ind = find_covering_region_by_base(new_region.start());
   MemRegion const old_region = _covered[ind];
   assert(old_region.start() == new_region.start(), "just checking");
@@ -211,12 +213,36 @@
     }
     // Align the end up to a page size (starts are already aligned).
     jbyte* const new_end = byte_after(new_region.last());
-    HeapWord* const new_end_aligned =
+    HeapWord* new_end_aligned =
       (HeapWord*) align_size_up((uintptr_t)new_end, _page_size);
     assert(new_end_aligned >= (HeapWord*) new_end,
            "align up, but less");
+    int ri = 0;
+    for (ri = 0; ri < _cur_covered_regions; ri++) {
+      if (ri != ind) {
+        if (_committed[ri].contains(new_end_aligned)) {
+          assert((new_end_aligned >= _committed[ri].start()) &&
+                 (_committed[ri].start() > _committed[ind].start()),
+                 "New end of committed region is inconsistent");
+          new_end_aligned = _committed[ri].start();
+          assert(new_end_aligned > _committed[ind].start(),
+            "New end of committed region is before start");
+          debug_only(collided = true;)
+          // Should only collide with 1 region
+          break;
+        }
+      }
+    }
+#ifdef ASSERT
+    for (++ri; ri < _cur_covered_regions; ri++) {
+      assert(!_committed[ri].contains(new_end_aligned),
+        "New end of committed region is in a second committed region");
+    }
+#endif
     // The guard page is always committed and should not be committed over.
-    HeapWord* const new_end_for_commit = MIN2(new_end_aligned, _guard_region.start());
+    HeapWord* const new_end_for_commit = MIN2(new_end_aligned,
+                                              _guard_region.start());
+
     if (new_end_for_commit > cur_committed.end()) {
       // Must commit new pages.
       MemRegion const new_committed =
@@ -239,9 +265,11 @@
       if (!uncommit_region.is_empty()) {
         if (!os::uncommit_memory((char*)uncommit_region.start(),
                                  uncommit_region.byte_size())) {
-          // Do better than this for Merlin
-          vm_exit_out_of_memory(uncommit_region.byte_size(),
-            "card table contraction");
+          assert(false, "Card table contraction failed");
+          // The call failed so don't change the end of the
+          // committed region.  This is better than taking the
+          // VM down.
+          new_end_aligned = _committed[ind].end();
         }
       }
     }
@@ -257,8 +285,25 @@
     }
     assert(index_for(new_region.last()) < (int) _guard_index,
       "The guard card will be overwritten");
-    jbyte* const end = byte_after(new_region.last());
+    // This line commented out cleans the newly expanded region and
+    // not the aligned up expanded region.
+    // jbyte* const end = byte_after(new_region.last());
+    jbyte* const end = (jbyte*) new_end_for_commit;
+    assert((end >= byte_after(new_region.last())) || collided,
+      "Expect to be beyond new region unless impacting another region");
     // do nothing if we resized downward.
+#ifdef ASSERT
+    for (int ri = 0; ri < _cur_covered_regions; ri++) {
+      if (ri != ind) {
+        // The end of the new committed region should not
+        // be in any existing region unless it matches
+        // the start of the next region.
+        assert(!_committed[ri].contains(end) ||
+               (_committed[ri].start() == (HeapWord*) end),
+               "Overlapping committed regions");
+      }
+    }
+#endif
     if (entry < end) {
       memset(entry, clean_card, pointer_delta(end, entry, sizeof(jbyte)));
     }
--- a/hotspot/src/share/vm/oops/symbolKlass.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/oops/symbolKlass.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -209,10 +209,7 @@
 
 void symbolKlass::oop_print_on(oop obj, outputStream* st) {
   st->print("Symbol: '");
-  symbolOop sym = symbolOop(obj);
-  for (int i = 0; i < sym->utf8_length(); i++) {
-    st->print("%c", sym->byte_at(i));
-  }
+  symbolOop(obj)->print_symbol_on(st);
   st->print("'");
 }
 
--- a/hotspot/src/share/vm/oops/symbolOop.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/oops/symbolOop.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -68,8 +68,17 @@
 
 void symbolOopDesc::print_symbol_on(outputStream* st) {
   st = st ? st : tty;
-  for (int index = 0; index < utf8_length(); index++)
-    st->put((char)byte_at(index));
+  int length = UTF8::unicode_length((const char*)bytes(), utf8_length());
+  const char *ptr = (const char *)bytes();
+  jchar value;
+  for (int index = 0; index < length; index++) {
+    ptr = UTF8::next(ptr, &value);
+    if (value >= 32 && value < 127 || value == '\'' || value == '\\') {
+      st->put(value);
+    } else {
+      st->print("\\u%04x", value);
+    }
+  }
 }
 
 jchar* symbolOopDesc::as_unicode(int& length) const {
--- a/hotspot/src/share/vm/opto/callnode.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/callnode.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -632,7 +632,7 @@
   const TypeOopPtr *adrInst_t  = addr_t->isa_oopptr();
 
   // if not an InstPtr or not an instance type, assume the worst
-  if (adrInst_t == NULL || !adrInst_t->is_instance_field()) {
+  if (adrInst_t == NULL || !adrInst_t->is_known_instance_field()) {
     return true;
   }
   Compile *C = phase->C;
--- a/hotspot/src/share/vm/opto/cfgnode.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -708,12 +708,12 @@
 // Split out an instance type from a bottom phi.
 PhiNode* PhiNode::split_out_instance(const TypePtr* at, PhaseIterGVN *igvn) const {
   const TypeOopPtr *t_oop = at->isa_oopptr();
-  assert(t_oop != NULL && t_oop->is_instance(), "expecting instance oopptr");
+  assert(t_oop != NULL && t_oop->is_known_instance(), "expecting instance oopptr");
   const TypePtr *t = adr_type();
   assert(type() == Type::MEMORY &&
          (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM ||
-          t->isa_oopptr() && !t->is_oopptr()->is_instance() &&
-          t->is_oopptr()->cast_to_instance(t_oop->instance_id()) == t_oop),
+          t->isa_oopptr() && !t->is_oopptr()->is_known_instance() &&
+          t->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop),
          "bottom or raw memory required");
 
   // Check if an appropriate node already exists.
@@ -854,7 +854,8 @@
   // Until we have harmony between classes and interfaces in the type
   // lattice, we must tread carefully around phis which implicitly
   // convert the one to the other.
-  const TypeInstPtr* ttip = _type->isa_narrowoop() ? _type->isa_narrowoop()->make_oopptr()->isa_instptr() :_type->isa_instptr();
+  const TypePtr* ttp = _type->make_ptr();
+  const TypeInstPtr* ttip = (ttp != NULL) ? ttp->isa_instptr() : NULL;
   bool is_intf = false;
   if (ttip != NULL) {
     ciKlass* k = ttip->klass();
@@ -873,7 +874,8 @@
       // of all the input types.  The lattice is not distributive in
       // such cases.  Ward off asserts in type.cpp by refusing to do
       // meets between interfaces and proper classes.
-      const TypeInstPtr* tiip = ti->isa_narrowoop() ? ti->is_narrowoop()->make_oopptr()->isa_instptr() : ti->isa_instptr();
+      const TypePtr* tip = ti->make_ptr();
+      const TypeInstPtr* tiip = (tip != NULL) ? tip->isa_instptr() : NULL;
       if (tiip) {
         bool ti_is_intf = false;
         ciKlass* k = tiip->klass();
@@ -930,13 +932,14 @@
     // class-typed Phi and an interface flows in, it's possible that the meet &
     // join report an interface back out.  This isn't possible but happens
     // because the type system doesn't interact well with interfaces.
-    const TypeInstPtr *jtip = jt->isa_narrowoop() ? jt->isa_narrowoop()->make_oopptr()->isa_instptr() : jt->isa_instptr();
+    const TypePtr *jtp = jt->make_ptr();
+    const TypeInstPtr *jtip = (jtp != NULL) ? jtp->isa_instptr() : NULL;
     if( jtip && ttip ) {
       if( jtip->is_loaded() &&  jtip->klass()->is_interface() &&
           ttip->is_loaded() && !ttip->klass()->is_interface() ) {
         // Happens in a CTW of rt.jar, 320-341, no extra flags
         assert(ft == ttip->cast_to_ptr_type(jtip->ptr()) ||
-               ft->isa_narrowoop() && ft->isa_narrowoop()->make_oopptr() == ttip->cast_to_ptr_type(jtip->ptr()), "");
+               ft->isa_narrowoop() && ft->make_ptr() == ttip->cast_to_ptr_type(jtip->ptr()), "");
         jt = ft;
       }
     }
--- a/hotspot/src/share/vm/opto/cfgnode.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/cfgnode.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -129,7 +129,7 @@
   };
 
   PhiNode( Node *r, const Type *t, const TypePtr* at = NULL,
-           const int iid = TypeOopPtr::UNKNOWN_INSTANCE,
+           const int iid = TypeOopPtr::InstanceTop,
            const int iidx = Compile::AliasIdxTop,
            const int ioffs = Type::OffsetTop )
     : TypeNode(t,r->req()),
--- a/hotspot/src/share/vm/opto/compile.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -313,9 +313,6 @@
   _compile->begin_method();
 }
 CompileWrapper::~CompileWrapper() {
-  if (_compile->failing()) {
-    _compile->print_method("Failed");
-  }
   _compile->end_method();
   if (_compile->scratch_buffer_blob() != NULL)
     BufferBlob::free(_compile->scratch_buffer_blob());
@@ -604,6 +601,8 @@
   if (failing())  return;
   NOT_PRODUCT( verify_graph_edges(); )
 
+  print_method("Before Matching");
+
 #ifndef PRODUCT
   if (PrintIdeal) {
     ttyLocker ttyl;  // keep the following output all in one block
@@ -1070,7 +1069,7 @@
       // No constant oop pointers (such as Strings); they alias with
       // unknown strings.
       tj = to = TypeInstPtr::make(TypePtr::BotPTR,to->klass(),false,0,offset);
-    } else if( to->is_instance_field() ) {
+    } else if( to->is_known_instance_field() ) {
       tj = to; // Keep NotNull and klass_is_exact for instance type
     } else if( ptr == TypePtr::NotNull || to->klass_is_exact() ) {
       // During the 2nd round of IterGVN, NotNull castings are removed.
@@ -1191,8 +1190,8 @@
   _field = NULL;
   _is_rewritable = true; // default
   const TypeOopPtr *atoop = (at != NULL) ? at->isa_oopptr() : NULL;
-  if (atoop != NULL && atoop->is_instance()) {
-    const TypeOopPtr *gt = atoop->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
+  if (atoop != NULL && atoop->is_known_instance()) {
+    const TypeOopPtr *gt = atoop->cast_to_instance_id(TypeOopPtr::InstanceBot);
     _general_index = Compile::current()->get_alias_index(gt);
   } else {
     _general_index = 0;
@@ -1481,7 +1480,7 @@
 
   NOT_PRODUCT( verify_graph_edges(); )
 
-  print_method("Start");
+  print_method("After Parsing");
 
  {
   // Iterative Global Value Numbering, including ideal transforms
@@ -1688,7 +1687,7 @@
     Output();
   }
 
-  print_method("End");
+  print_method("Final Code");
 
   // He's dead, Jim.
   _cfg     = (PhaseCFG*)0xdeadbeef;
@@ -2017,7 +2016,7 @@
         for (uint i = 0; i < cnt; i++) {
           Node* m = r->raw_out(i);
           if (m!= NULL && m->Opcode() == Op_ConN &&
-              m->bottom_type()->is_narrowoop()->make_oopptr() == t) {
+              m->bottom_type()->make_ptr() == t) {
             nn = m;
             break;
           }
@@ -2070,7 +2069,7 @@
             }
           }
         } else if (t->isa_oopptr()) {
-          in2 = ConNode::make(C, t->is_oopptr()->make_narrowoop());
+          in2 = ConNode::make(C, t->make_narrowoop());
         }
       }
       if( in2 != NULL ) {
@@ -2466,6 +2465,9 @@
     // Record the first failure reason.
     _failure_reason = reason;
   }
+  if (!C->failure_reason_is(C2Compiler::retry_no_subsuming_loads())) {
+    C->print_method(_failure_reason);
+  }
   _root = NULL;  // flush the graph, too
 }
 
--- a/hotspot/src/share/vm/opto/connode.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/connode.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -565,26 +565,12 @@
 }
 
 const Type *DecodeNNode::Value( PhaseTransform *phase ) const {
-  if (phase->type( in(1) ) == TypeNarrowOop::NULL_PTR) {
-    return TypePtr::NULL_PTR;
-  }
-  return bottom_type();
-}
+  const Type *t = phase->type( in(1) );
+  if (t == Type::TOP) return Type::TOP;
+  if (t == TypeNarrowOop::NULL_PTR) return TypePtr::NULL_PTR;
 
-Node* DecodeNNode::decode(PhaseTransform* phase, Node* value) {
-  if (value->is_EncodeP()) {
-    // (DecodeN (EncodeP p)) -> p
-    return value->in(1);
-  }
-  const Type* newtype = value->bottom_type();
-  if (newtype == TypeNarrowOop::NULL_PTR) {
-    return phase->transform(new (phase->C, 1) ConPNode(TypePtr::NULL_PTR));
-  } else if (newtype->isa_narrowoop()) {
-    return phase->transform(new (phase->C, 2) DecodeNNode(value, newtype->is_narrowoop()->make_oopptr()));
-  } else {
-    ShouldNotReachHere();
-    return NULL; // to make C++ compiler happy.
-  }
+  assert(t->isa_narrowoop(), "only  narrowoop here");
+  return t->make_ptr();
 }
 
 Node* EncodePNode::Identity(PhaseTransform* phase) {
@@ -599,27 +585,14 @@
 }
 
 const Type *EncodePNode::Value( PhaseTransform *phase ) const {
-  if (phase->type( in(1) ) == TypePtr::NULL_PTR) {
-    return TypeNarrowOop::NULL_PTR;
-  }
-  return bottom_type();
+  const Type *t = phase->type( in(1) );
+  if (t == Type::TOP) return Type::TOP;
+  if (t == TypePtr::NULL_PTR) return TypeNarrowOop::NULL_PTR;
+
+  assert(t->isa_oopptr(), "only oopptr here");
+  return t->make_narrowoop();
 }
 
-Node* EncodePNode::encode(PhaseTransform* phase, Node* value) {
-  if (value->is_DecodeN()) {
-    // (EncodeP (DecodeN p)) -> p
-    return value->in(1);
-  }
-  const Type* newtype = value->bottom_type();
-  if (newtype == TypePtr::NULL_PTR) {
-    return phase->transform(new (phase->C, 1) ConNNode(TypeNarrowOop::NULL_PTR));
-  } else if (newtype->isa_oopptr()) {
-    return phase->transform(new (phase->C, 2) EncodePNode(value, newtype->is_oopptr()->make_narrowoop()));
-  } else {
-    ShouldNotReachHere();
-    return NULL; // to make C++ compiler happy.
-  }
-}
 
 Node *EncodePNode::Ideal_DU_postCCP( PhaseCCP *ccp ) {
   return MemNode::Ideal_common_DU_postCCP(ccp, this, in(1));
--- a/hotspot/src/share/vm/opto/connode.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/connode.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -280,7 +280,6 @@
   virtual const Type *Value( PhaseTransform *phase ) const;
   virtual uint  ideal_reg() const { return Op_RegN; }
 
-  static Node* encode(PhaseTransform* phase, Node* value);
   virtual Node *Ideal_DU_postCCP( PhaseCCP *ccp );
 };
 
@@ -300,8 +299,6 @@
   virtual Node *Identity( PhaseTransform *phase );
   virtual const Type *Value( PhaseTransform *phase ) const;
   virtual uint  ideal_reg() const { return Op_RegP; }
-
-  static Node* decode(PhaseTransform* phase, Node* value);
 };
 
 //------------------------------Conv2BNode-------------------------------------
@@ -549,10 +546,18 @@
   virtual uint hash() const ;                  // { return NO_HASH; }
   virtual uint cmp( const Node &n ) const;
 public:
-  Opaque1Node( Node *n ) : Node(0,n) {}
+  Opaque1Node( Compile* C, Node *n ) : Node(0,n) {
+    // Put it on the Macro nodes list to removed during macro nodes expansion.
+    init_flags(Flag_is_macro);
+    C->add_macro_node(this);
+  }
   // Special version for the pre-loop to hold the original loop limit
   // which is consumed by range check elimination.
-  Opaque1Node( Node *n, Node* orig_limit ) : Node(0,n,orig_limit) {}
+  Opaque1Node( Compile* C, Node *n, Node* orig_limit ) : Node(0,n,orig_limit) {
+    // Put it on the Macro nodes list to removed during macro nodes expansion.
+    init_flags(Flag_is_macro);
+    C->add_macro_node(this);
+  }
   Node* original_loop_limit() { return req()==3 ? in(2) : NULL; }
   virtual int Opcode() const;
   virtual const Type *bottom_type() const { return TypeInt::INT; }
@@ -572,7 +577,11 @@
   virtual uint hash() const ;                  // { return NO_HASH; }
   virtual uint cmp( const Node &n ) const;
 public:
-  Opaque2Node( Node *n ) : Node(0,n) {}
+  Opaque2Node( Compile* C, Node *n ) : Node(0,n) {
+    // Put it on the Macro nodes list to removed during macro nodes expansion.
+    init_flags(Flag_is_macro);
+    C->add_macro_node(this);
+  }
   virtual int Opcode() const;
   virtual const Type *bottom_type() const { return TypeInt::INT; }
 };
--- a/hotspot/src/share/vm/opto/escape.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/escape.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -483,7 +483,7 @@
 //
 void ConnectionGraph::split_AddP(Node *addp, Node *base,  PhaseGVN  *igvn) {
   const TypeOopPtr *base_t = igvn->type(base)->isa_oopptr();
-  assert(base_t != NULL && base_t->is_instance(), "expecting instance oopptr");
+  assert(base_t != NULL && base_t->is_known_instance(), "expecting instance oopptr");
   const TypeOopPtr *t = igvn->type(addp)->isa_oopptr();
   if (t == NULL) {
     // We are computing a raw address for a store captured by an Initialize
@@ -494,8 +494,8 @@
     assert(offs != Type::OffsetBot, "offset must be a constant");
     t = base_t->add_offset(offs)->is_oopptr();
   }
-  uint inst_id =  base_t->instance_id();
-  assert(!t->is_instance() || t->instance_id() == inst_id,
+  int inst_id =  base_t->instance_id();
+  assert(!t->is_known_instance() || t->instance_id() == inst_id,
                              "old type must be non-instance or match new type");
   const TypeOopPtr *tinst = base_t->add_offset(t->offset())->is_oopptr();
   // Do NOT remove the next call: ensure an new alias index is allocated
@@ -509,7 +509,7 @@
   Node *adr = addp->in(AddPNode::Address);
   const TypeOopPtr  *atype = igvn->type(adr)->isa_oopptr();
   if (atype != NULL && atype->instance_id() != inst_id) {
-    assert(!atype->is_instance(), "no conflicting instances");
+    assert(!atype->is_known_instance(), "no conflicting instances");
     const TypeOopPtr *new_atype = base_t->add_offset(atype->offset())->isa_oopptr();
     Node *acast = new (_compile, 2) CastPPNode(adr, new_atype);
     acast->set_req(0, adr->in(0));
@@ -663,7 +663,7 @@
     return orig_mem;
   Compile* C = phase->C;
   const TypeOopPtr *tinst = C->get_adr_type(alias_idx)->isa_oopptr();
-  bool is_instance = (tinst != NULL) && tinst->is_instance();
+  bool is_instance = (tinst != NULL) && tinst->is_known_instance();
   Node *prev = NULL;
   Node *result = orig_mem;
   while (prev != result) {
@@ -693,7 +693,7 @@
         AllocateNode* alloc = proj_in->as_Initialize()->allocation();
         // Stop if this is the initialization for the object instance which
         // which contains this memory slice, otherwise skip over it.
-        if (alloc == NULL || alloc->_idx != tinst->instance_id()) {
+        if (alloc == NULL || alloc->_idx != (uint)tinst->instance_id()) {
           result = proj_in->in(TypeFunc::Memory);
         }
       } else if (proj_in->is_MemBar()) {
@@ -887,7 +887,7 @@
       const TypeOopPtr *t = igvn->type(n)->isa_oopptr();
       if (t == NULL)
         continue;  // not a TypeInstPtr
-      tinst = t->cast_to_instance(ni);
+      tinst = t->cast_to_instance_id(ni);
       igvn->hash_delete(n);
       igvn->set_type(n,  tinst);
       n->raise_bottom_type(tinst);
@@ -959,19 +959,19 @@
         Node *val = get_map(elem);   // CheckCastPP node
         TypeNode *tn = n->as_Type();
         tinst = igvn->type(val)->isa_oopptr();
-        assert(tinst != NULL && tinst->is_instance() &&
-               tinst->instance_id() == elem , "instance type expected.");
+        assert(tinst != NULL && tinst->is_known_instance() &&
+               (uint)tinst->instance_id() == elem , "instance type expected.");
 
-        const TypeOopPtr *tn_t = NULL;
         const Type *tn_type = igvn->type(tn);
+        const TypeOopPtr *tn_t;
         if (tn_type->isa_narrowoop()) {
-          tn_t = tn_type->is_narrowoop()->make_oopptr()->isa_oopptr();
+          tn_t = tn_type->make_ptr()->isa_oopptr();
         } else {
           tn_t = tn_type->isa_oopptr();
         }
 
         if (tn_t != NULL &&
- tinst->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE)->higher_equal(tn_t)) {
+            tinst->cast_to_instance_id(TypeOopPtr::InstanceBot)->higher_equal(tn_t)) {
           if (tn_type->isa_narrowoop()) {
             tn_type = tinst->make_narrowoop();
           } else {
@@ -1921,9 +1921,7 @@
     case Op_StoreN:
     {
       const Type *adr_type = phase->type(n->in(MemNode::Address));
-      if (adr_type->isa_narrowoop()) {
-        adr_type = adr_type->is_narrowoop()->make_oopptr();
-      }
+      adr_type = adr_type->make_ptr();
       if (adr_type->isa_oopptr()) {
         add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false);
       } else {
@@ -1948,9 +1946,7 @@
     case Op_CompareAndSwapN:
     {
       const Type *adr_type = phase->type(n->in(MemNode::Address));
-      if (adr_type->isa_narrowoop()) {
-        adr_type = adr_type->is_narrowoop()->make_oopptr();
-      }
+      adr_type = adr_type->make_ptr();
       if (adr_type->isa_oopptr()) {
         add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false);
       } else {
@@ -2131,10 +2127,7 @@
     case Op_CompareAndSwapN:
     {
       Node *adr = n->in(MemNode::Address);
-      const Type *adr_type = phase->type(adr);
-      if (adr_type->isa_narrowoop()) {
-        adr_type = adr_type->is_narrowoop()->make_oopptr();
-      }
+      const Type *adr_type = phase->type(adr)->make_ptr();
 #ifdef ASSERT
       if (!adr_type->isa_oopptr())
         assert(phase->type(adr) == TypeRawPtr::NOTNULL, "Op_StoreP");
--- a/hotspot/src/share/vm/opto/gcm.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/gcm.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -307,7 +307,6 @@
 
     // Test and set the visited bit.
     if (mid->raise_LCA_visited() == mark)  continue;  // already visited
-    mid->set_raise_LCA_visited(mark);
 
     // Don't process the current LCA, otherwise the search may terminate early
     if (mid != LCA && mid->raise_LCA_mark() == mark) {
@@ -317,6 +316,8 @@
       assert(early->dominates(LCA), "early is high enough");
       // Resume searching at that point, skipping intermediate levels.
       worklist.push(LCA);
+      if (LCA == mid)
+        continue; // Don't mark as visited to avoid early termination.
     } else {
       // Keep searching through this block's predecessors.
       for (uint j = 1, jmax = mid->num_preds(); j < jmax; j++) {
@@ -324,6 +325,7 @@
         worklist.push(mid_parent);
       }
     }
+    mid->set_raise_LCA_visited(mark);
   }
   return LCA;
 }
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -100,16 +100,18 @@
 // Constructor, either file or network output
 IdealGraphPrinter::IdealGraphPrinter() {
 
-  _traverse_outs = false;
+  // By default dump both ins and outs since dead or unreachable code
+  // needs to appear in the graph.  There are also some special cases
+  // in the mach where kill projections have no users but should
+  // appear in the dump.
+  _traverse_outs = true;
   _should_send_method = true;
   _output = NULL;
   buffer[0] = 0;
   _depth = 0;
   _current_method = NULL;
   assert(!_current_method, "current method must be initialized to NULL");
-  _arena = new Arena();
-
-  _stream = new (ResourceObj::C_HEAP) networkStream();
+  _stream = NULL;
 
   if (PrintIdealGraphFile != NULL) {
     ThreadCritical tc;
@@ -124,12 +126,16 @@
       } else {
         st.print("%s%d", PrintIdealGraphFile, _file_count);
       }
-      _output = new (ResourceObj::C_HEAP) fileStream(st.as_string());
+      fileStream *stream = new (ResourceObj::C_HEAP) fileStream(st.as_string());
+      _output = stream;
     } else {
-      _output = new (ResourceObj::C_HEAP) fileStream(PrintIdealGraphFile);
+      fileStream *stream = new (ResourceObj::C_HEAP) fileStream(PrintIdealGraphFile);
+      _output = stream;
     }
     _file_count++;
   } else {
+    _stream = new (ResourceObj::C_HEAP) networkStream();
+
     // Try to connect to visualizer
     if (_stream->connect(PrintIdealGraphAddress, PrintIdealGraphPort)) {
       char c = 0;
@@ -149,13 +155,24 @@
     }
   }
 
-  start_element(TOP_ELEMENT);
+  _xml = new (ResourceObj::C_HEAP) xmlStream(_output);
+
+  head(TOP_ELEMENT);
 }
 
 // Destructor, close file or network stream
 IdealGraphPrinter::~IdealGraphPrinter() {
 
-  end_element(TOP_ELEMENT);
+  tail(TOP_ELEMENT);
+
+  // tty->print_cr("Walk time: %d", (int)_walk_time.milliseconds());
+  // tty->print_cr("Output time: %d", (int)_output_time.milliseconds());
+  // tty->print_cr("Build blocks time: %d", (int)_build_blocks_time.milliseconds());
+
+  if(_xml) {
+    delete _xml;
+    _xml = NULL;
+  }
 
   if (_stream) {
     delete _stream;
@@ -171,94 +188,93 @@
   }
 }
 
-void IdealGraphPrinter::print_ifg(PhaseIFG* ifg) {
-
-  // Code to print an interference graph to tty, currently not used
 
-  /*
-  if (!_current_method) return;
-   // Remove neighbor colors
+void IdealGraphPrinter::begin_elem(const char *s) {
+  _xml->begin_elem(s);
+}
+
+void IdealGraphPrinter::end_elem() {
+  _xml->end_elem();
+}
 
-  for (uint i = 0; i < ifg._maxlrg; i++) {
+void IdealGraphPrinter::begin_head(const char *s) {
+  _xml->begin_head(s);
+}
 
-    IndexSet *s = ifg.neighbors(i);
-    IndexSetIterator elements(s);
-    uint neighbor;
-    while ((neighbor = elements.next()) != 0) {
-        tty->print_cr("Edge between %d and %d\n", i, neighbor);
-    }
-  }
+void IdealGraphPrinter::end_head() {
+  _xml->end_head();
+}
 
+void IdealGraphPrinter::print_attr(const char *name, intptr_t val) {
+  stringStream stream;
+  stream.print(INTX_FORMAT, val);
+  print_attr(name, stream.as_string());
+}
 
-  for (uint i = 0; i < ifg._maxlrg; i++) {
-    LRG &l = ifg.lrgs(i);
-    if (l._def) {
-      OptoReg::Name name = l.reg();
-      tty->print("OptoReg::dump: ");
-      OptoReg::dump(name);
-      tty->print_cr("");
-      tty->print_cr("name=%d\n", name);
-      if (name) {
-        if (OptoReg::is_stack(name)) {
-          tty->print_cr("Stack number %d\n", OptoReg::reg2stack(name));
+void IdealGraphPrinter::print_attr(const char *name, const char *val) {
+  _xml->print(" %s='", name);
+  text(val);
+  _xml->print("'");
+}
 
-        } else if (!OptoReg::is_valid(name)) {
-          tty->print_cr("BAD!!!");
-        } else {
+void IdealGraphPrinter::head(const char *name) {
+  _xml->head(name);
+}
+
+void IdealGraphPrinter::tail(const char *name) {
+  _xml->tail(name);
+}
 
-          if (OptoReg::is_reg(name)) {
-          tty->print_cr(OptoReg::regname(name));
-          } else {
-            int x = 0;
-          }
-        }
-        int x = 0;
-      }
+void IdealGraphPrinter::text(const char *s) {
+  _xml->text(s);
+}
+
+void IdealGraphPrinter::print_prop(const char *name, int val) {
 
-      if (l._def == NodeSentinel) {
-        tty->print("multiple mapping from %d: ", i);
-        for (int j=0; j<l._defs->length(); j++) {
-          tty->print("%d ", l._defs->at(j)->_idx);
-        }
-        tty->print_cr("");
-      } else {
-        tty->print_cr("mapping between %d and %d\n", i, l._def->_idx);
-      }
-    }
-  }*/
+  stringStream stream;
+  stream.print("%d", val);
+  print_prop(name, stream.as_string());
+}
+
+void IdealGraphPrinter::print_prop(const char *name, const char *val) {
+  begin_head(PROPERTY_ELEMENT);
+  print_attr(PROPERTY_NAME_PROPERTY, name);
+  end_head();
+  text(val);
+  tail(PROPERTY_ELEMENT);
 }
 
 void IdealGraphPrinter::print_method(ciMethod *method, int bci, InlineTree *tree) {
+  begin_head(METHOD_ELEMENT);
 
-  Properties properties;
   stringStream str;
   method->print_name(&str);
 
   stringStream shortStr;
   method->print_short_name(&shortStr);
 
+  print_attr(METHOD_NAME_PROPERTY, str.as_string());
+  print_attr(METHOD_SHORT_NAME_PROPERTY, shortStr.as_string());
+  print_attr(METHOD_BCI_PROPERTY, bci);
 
-  properties.add(new Property(METHOD_NAME_PROPERTY, str.as_string()));
-  properties.add(new Property(METHOD_SHORT_NAME_PROPERTY, shortStr.as_string()));
-  properties.add(new Property(METHOD_BCI_PROPERTY, bci));
-  start_element(METHOD_ELEMENT, &properties);
+  end_head();
 
-  start_element(BYTECODES_ELEMENT);
+  head(BYTECODES_ELEMENT);
   output()->print_cr("<![CDATA[");
   method->print_codes_on(output());
   output()->print_cr("]]>");
-  end_element(BYTECODES_ELEMENT);
+  tail(BYTECODES_ELEMENT);
 
-  start_element(INLINE_ELEMENT);
+  head(INLINE_ELEMENT);
   if (tree != NULL) {
     GrowableArray<InlineTree *> subtrees = tree->subtrees();
     for (int i = 0; i < subtrees.length(); i++) {
       print_inline_tree(subtrees.at(i));
     }
   }
-  end_element(INLINE_ELEMENT);
+  tail(INLINE_ELEMENT);
 
-  end_element(METHOD_ELEMENT);
+  tail(METHOD_ELEMENT);
   output()->flush();
 }
 
@@ -271,12 +287,6 @@
 
 }
 
-void IdealGraphPrinter::clear_nodes() {
- // for (int i = 0; i < _nodes.length(); i++) {
- //   _nodes.at(i)->clear_node();
- // }
-}
-
 void IdealGraphPrinter::print_inlining(Compile* compile) {
 
   // Print inline tree
@@ -298,143 +308,56 @@
   assert(method, "null methods are not allowed!");
   assert(!_current_method, "current method must be null!");
 
-  _arena->destruct_contents();
+  head(GROUP_ELEMENT);
 
-  start_element(GROUP_ELEMENT);
+  head(PROPERTIES_ELEMENT);
 
   // Print properties
-  Properties properties;
-
   // Add method name
   stringStream strStream;
   method->print_name(&strStream);
-  properties.add(new Property(METHOD_NAME_PROPERTY, strStream.as_string()));
+  print_prop(METHOD_NAME_PROPERTY, strStream.as_string());
 
   if (method->flags().is_public()) {
-    properties.add(new Property(METHOD_IS_PUBLIC_PROPERTY, TRUE_VALUE));
+    print_prop(METHOD_IS_PUBLIC_PROPERTY, TRUE_VALUE);
   }
 
   if (method->flags().is_static()) {
-    properties.add(new Property(METHOD_IS_STATIC_PROPERTY, TRUE_VALUE));
+    print_prop(METHOD_IS_STATIC_PROPERTY, TRUE_VALUE);
   }
 
-  properties.print(this);
+  tail(PROPERTIES_ELEMENT);
 
   if (_stream) {
     char answer = 0;
-    _stream->flush();
+    _xml->flush();
     int result = _stream->read(&answer, 1);
     _should_send_method = (answer == 'y');
   }
 
-  this->_nodes = GrowableArray<NodeDescription *>(_arena, 2, 0, NULL);
-  this->_edges = GrowableArray< EdgeDescription * >(_arena, 2, 0, NULL);
-
-
   this->_current_method = method;
 
-
-
-  _output->flush();
+  _xml->flush();
 }
 
 // Has to be called whenever a method has finished compilation
 void IdealGraphPrinter::end_method() {
 
-//  if (finish && !in_method) return;
-
   nmethod* method = (nmethod*)this->_current_method->code();
 
-  start_element(ASSEMBLY_ELEMENT);
- // Disassembler::decode(method, _output);
-  end_element(ASSEMBLY_ELEMENT);
-
-
-  end_element(GROUP_ELEMENT);
+  tail(GROUP_ELEMENT);
   _current_method = NULL;
-  _output->flush();
-  for (int i = 0; i < _nodes.length(); i++) {
-    NodeDescription *desc = _nodes.at(i);
-    if (desc) {
-      delete desc;
-      _nodes.at_put(i, NULL);
-    }
-  }
-  this->_nodes.clear();
-
-
-  for (int i = 0; i < _edges.length(); i++) {
-   // for (int j=0; j<_edges.at(i)->length(); j++) {
-      EdgeDescription *conn = _edges.at(i);
-      conn->print(this);
-      if (conn) {
-        delete conn;
-        _edges.at_put(i, NULL);
-      }
-    //}
-    //_edges.at(i)->clear();
-    //delete _edges.at(i);
-    //_edges.at_put(i, NULL);
-  }
-  this->_edges.clear();
-
-//  in_method = false;
-}
-
-// Outputs an XML start element
-void IdealGraphPrinter::start_element(const char *s, Properties *properties /* = NULL */, bool print_indent /* = false */, bool print_return /* = true */) {
-
-  start_element_helper(s, properties, false, print_indent, print_return);
-  _depth++;
-
-}
-
-// Outputs an XML start element without body
-void IdealGraphPrinter::simple_element(const char *s, Properties *properties /* = NULL */, bool print_indent /* = false */) {
-  start_element_helper(s, properties, true, print_indent, true);
-}
-
-// Outputs an XML start element. If outputEnd is true, the element has no body.
-void IdealGraphPrinter::start_element_helper(const char *s, Properties *properties, bool outputEnd, bool print_indent /* = false */, bool print_return /* = true */) {
-
-  assert(_output, "output stream must exist!");
-
-  if (print_indent) this->print_indent();
-  _output->print("<");
-  _output->print(s);
-  if (properties) properties->print_as_attributes(this);
-
-  if (outputEnd) {
-    _output->print("/");
-  }
-
-  _output->print(">");
-  if (print_return) _output->print_cr("");
-
+  _xml->flush();
 }
 
 // Print indent
 void IdealGraphPrinter::print_indent() {
+  tty->print_cr("printing ident %d", _depth);
   for (int i = 0; i < _depth; i++) {
-    _output->print(INDENT);
+    _xml->print(INDENT);
   }
 }
 
-// Outputs an XML end element
-void IdealGraphPrinter::end_element(const char *s, bool print_indent /* = true */, bool print_return /* = true */) {
-
-  assert(_output, "output stream must exist!");
-
-  _depth--;
-
-  if (print_indent) this->print_indent();
-  _output->print("</");
-  _output->print(s);
-  _output->print(">");
-  if (print_return) _output->print_cr("");
-
-}
-
 bool IdealGraphPrinter::traverse_outs() {
   return _traverse_outs;
 }
@@ -443,7 +366,255 @@
   _traverse_outs = b;
 }
 
-void IdealGraphPrinter::walk(Node *start) {
+intptr_t IdealGraphPrinter::get_node_id(Node *n) {
+  return (intptr_t)(n);
+}
+
+void IdealGraphPrinter::visit_node(Node *n, void *param) {
+
+  if(param) {
+
+    // Output edge
+    intptr_t dest_id = get_node_id(n);
+    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(TO_PROPERTY, dest_id);
+        print_attr(INDEX_PROPERTY, i);
+        end_elem();
+      }
+    }
+
+  } else {
+
+    // Output node
+    begin_head(NODE_ELEMENT);
+    print_attr(NODE_ID_PROPERTY, get_node_id(n));
+    end_head();
+
+    head(PROPERTIES_ELEMENT);
+
+    Node *node = n;
+#ifndef PRODUCT
+    node->_in_dump_cnt++;
+    print_prop(NODE_NAME_PROPERTY, (const char *)node->Name());
+    const Type *t = node->bottom_type();
+    print_prop("type", (const char *)Type::msg[t->base()]);
+    print_prop("idx", node->_idx);
+#ifdef ASSERT
+    print_prop("debug_idx", node->_debug_idx);
+#endif
+
+    if(C->cfg() != NULL) {
+      Block *block = C->cfg()->_bbs[node->_idx];
+      if(block == NULL) {
+        print_prop("block", C->cfg()->_blocks[0]->_pre_order);
+      } else {
+        print_prop("block", block->_pre_order);
+      }
+    }
+
+    const jushort flags = node->flags();
+    if (flags & Node::Flag_is_Copy) {
+      print_prop("is_copy", "true");
+    }
+    if (flags & Node::Flag_is_Call) {
+      print_prop("is_call", "true");
+    }
+    if (flags & Node::Flag_rematerialize) {
+      print_prop("rematerialize", "true");
+    }
+    if (flags & Node::Flag_needs_anti_dependence_check) {
+      print_prop("needs_anti_dependence_check", "true");
+    }
+    if (flags & Node::Flag_is_macro) {
+      print_prop("is_macro", "true");
+    }
+    if (flags & Node::Flag_is_Con) {
+      print_prop("is_con", "true");
+    }
+    if (flags & Node::Flag_is_cisc_alternate) {
+      print_prop("is_cisc_alternate", "true");
+    }
+    if (flags & Node::Flag_is_Branch) {
+      print_prop("is_branch", "true");
+    }
+    if (flags & Node::Flag_is_block_start) {
+      print_prop("is_block_start", "true");
+    }
+    if (flags & Node::Flag_is_Goto) {
+      print_prop("is_goto", "true");
+    }
+    if (flags & Node::Flag_is_dead_loop_safe) {
+      print_prop("is_dead_loop_safe", "true");
+    }
+    if (flags & Node::Flag_may_be_short_branch) {
+      print_prop("may_be_short_branch", "true");
+    }
+    if (flags & Node::Flag_is_safepoint_node) {
+      print_prop("is_safepoint_node", "true");
+    }
+    if (flags & Node::Flag_is_pc_relative) {
+      print_prop("is_pc_relative", "true");
+    }
+
+    if (C->matcher() != NULL) {
+      if (C->matcher()->is_shared(node)) {
+        print_prop("is_shared", "true");
+      } else {
+        print_prop("is_shared", "false");
+      }
+      if (C->matcher()->is_dontcare(node)) {
+        print_prop("is_dontcare", "true");
+      } else {
+        print_prop("is_dontcare", "false");
+      }
+
+      Node* old = C->matcher()->find_old_node(node);
+      if (old != NULL) {
+        print_prop("old_node_idx", old->_idx);
+      }
+    }
+
+    if (node->is_Proj()) {
+      print_prop("con", (int)node->as_Proj()->_con);
+    }
+
+    if (node->is_Mach()) {
+      print_prop("idealOpcode", (const char *)NodeClassNames[node->as_Mach()->ideal_Opcode()]);
+    }
+
+    buffer[0] = 0;
+    stringStream s2(buffer, sizeof(buffer) - 1);
+
+    node->dump_spec(&s2);
+    if (t != NULL && (t->isa_instptr() || t->isa_klassptr())) {
+      const TypeInstPtr  *toop = t->isa_instptr();
+      const TypeKlassPtr *tkls = t->isa_klassptr();
+      ciKlass*           klass = toop ? toop->klass() : (tkls ? tkls->klass() : NULL );
+      if( klass && klass->is_loaded() && klass->is_interface() ) {
+        s2.print("  Interface:");
+      } else if( toop ) {
+        s2.print("  Oop:");
+      } else if( tkls ) {
+        s2.print("  Klass:");
+      }
+      t->dump_on(&s2);
+    } else if( t == Type::MEMORY ) {
+      s2.print("  Memory:");
+      MemNode::dump_adr_type(node, node->adr_type(), &s2);
+    }
+
+    assert(s2.size() < sizeof(buffer), "size in range");
+    print_prop("dump_spec", buffer);
+
+    if (node->is_block_proj()) {
+      print_prop("is_block_proj", "true");
+    }
+
+    if (node->is_block_start()) {
+      print_prop("is_block_start", "true");
+    }
+
+    const char *short_name = "short_name";
+    if (strcmp(node->Name(), "Parm") == 0 && node->as_Proj()->_con >= TypeFunc::Parms) {
+      int index = node->as_Proj()->_con - TypeFunc::Parms;
+      if (index >= 10) {
+        print_prop(short_name, "PA");
+      } else {
+        sprintf(buffer, "P%d", index);
+        print_prop(short_name, buffer);
+      }
+    } else if (strcmp(node->Name(), "IfTrue") == 0) {
+      print_prop(short_name, "T");
+    } else if (strcmp(node->Name(), "IfFalse") == 0) {
+      print_prop(short_name, "F");
+    } else if ((node->is_Con() && node->is_Type()) || node->is_Proj()) {
+
+      if (t->base() == Type::Int && t->is_int()->is_con()) {
+        const TypeInt *typeInt = t->is_int();
+        assert(typeInt->is_con(), "must be constant");
+        jint value = typeInt->get_con();
+
+        // max. 2 chars allowed
+        if (value >= -9 && value <= 99) {
+          sprintf(buffer, "%d", value);
+          print_prop(short_name, buffer);
+        } else {
+          print_prop(short_name, "I");
+        }
+      } else if (t == Type::TOP) {
+        print_prop(short_name, "^");
+      } else if (t->base() == Type::Long && t->is_long()->is_con()) {
+        const TypeLong *typeLong = t->is_long();
+        assert(typeLong->is_con(), "must be constant");
+        jlong value = typeLong->get_con();
+
+        // max. 2 chars allowed
+        if (value >= -9 && value <= 99) {
+          sprintf(buffer, "%d", value);
+          print_prop(short_name, buffer);
+        } else {
+          print_prop(short_name, "L");
+        }
+      } else if (t->base() == Type::KlassPtr) {
+        const TypeKlassPtr *typeKlass = t->is_klassptr();
+        print_prop(short_name, "CP");
+      } else if (t->base() == Type::Control) {
+        print_prop(short_name, "C");
+      } else if (t->base() == Type::Memory) {
+        print_prop(short_name, "M");
+      } else if (t->base() == Type::Abio) {
+        print_prop(short_name, "IO");
+      } else if (t->base() == Type::Return_Address) {
+        print_prop(short_name, "RA");
+      } else if (t->base() == Type::AnyPtr) {
+        print_prop(short_name, "P");
+      } else if (t->base() == Type::RawPtr) {
+        print_prop(short_name, "RP");
+      } else if (t->base() == Type::AryPtr) {
+        print_prop(short_name, "AP");
+      }
+    }
+
+    JVMState* caller = NULL;
+    if (node->is_SafePoint()) {
+      caller = node->as_SafePoint()->jvms();
+    } else {
+      Node_Notes* notes = C->node_notes_at(node->_idx);
+      if (notes != NULL) {
+        caller = notes->jvms();
+      }
+    }
+
+    if (caller != NULL) {
+      stringStream bciStream;
+      while(caller) {
+        bciStream.print("%d ", caller->bci());
+        caller = caller->caller();
+      }
+      print_prop("bci", bciStream.as_string());
+    }
+
+    if (_chaitin && _chaitin != (PhaseChaitin *)0xdeadbeef) {
+      buffer[0] = 0;
+      _chaitin->dump_register(node, buffer);
+      print_prop("reg", buffer);
+      print_prop("lrg", _chaitin->n2lidx(node));
+    }
+
+    node->_in_dump_cnt--;
+#endif
+
+    tail(PROPERTIES_ELEMENT);
+    tail(NODE_ELEMENT);
+  }
+}
+
+void IdealGraphPrinter::walk_nodes(Node *start, void *param) {
 
 
   VectorSet visited(Thread::current()->resource_area());
@@ -453,7 +624,7 @@
   while(nodeStack.length() > 0) {
 
     Node *n = nodeStack.pop();
-    IdealGraphPrinter::pre_node(n, this);
+    visit_node(n, param);
 
     if (_traverse_outs) {
       for (DUIterator i = n->outs(); n->has_out(i); i++) {
@@ -474,573 +645,6 @@
   }
 }
 
-void IdealGraphPrinter::compress(int index, GrowableArray<Block>* blocks) {
-  Block *block = blocks->adr_at(index);
-
-  int ancestor = block->ancestor();
-  assert(ancestor != -1, "");
-
-  Block *ancestor_block = blocks->adr_at(ancestor);
-  if (ancestor_block->ancestor() != -1) {
-    compress(ancestor, blocks);
-
-    int label = block->label();
-    Block *label_block = blocks->adr_at(label);
-
-    int ancestor_label = ancestor_block->label();
-    Block *ancestor_label_block = blocks->adr_at(label);
-    if (ancestor_label_block->semi() < label_block->semi()) {
-      block->set_label(ancestor_label);
-    }
-
-    block->set_ancestor(ancestor_block->ancestor());
-  }
-}
-
-int IdealGraphPrinter::eval(int index, GrowableArray<Block>* blocks) {
-  Block *block = blocks->adr_at(index);
-  if (block->ancestor() == -1) {
-    return index;
-  } else {
-    compress(index, blocks);
-    return block->label();
-  }
-}
-
-void IdealGraphPrinter::link(int index1, int index2, GrowableArray<Block>* blocks) {
-  Block *block2 = blocks->adr_at(index2);
-  block2->set_ancestor(index1);
-}
-
-void IdealGraphPrinter::build_dominators(GrowableArray<Block>* blocks) {
-
-  if (blocks->length() == 0) return;
-
-  GrowableArray<int> stack;
-  stack.append(0);
-
-  GrowableArray<Block *> array;
-
-  assert(blocks->length() > 0, "");
-  blocks->adr_at(0)->set_dominator(0);
-
-  int n = 0;
-  while(!stack.is_empty()) {
-    int index = stack.pop();
-    Block *block = blocks->adr_at(index);
-    block->set_semi(n);
-    array.append(block);
-    n = n + 1;
-    for (int i = 0; i < block->succs()->length(); i++) {
-      int succ_index = block->succs()->at(i);
-      Block *succ = blocks->adr_at(succ_index);
-      if (succ->semi() == -1) {
-        succ->set_parent(index);
-        stack.push(succ_index);
-      }
-      succ->add_pred(index);
-    }
-  }
-
-  for (int i=n-1; i>0; i--) {
-    Block *block = array.at(i);
-    int block_index = block->index();
-    for (int j=0; j<block->pred()->length(); j++) {
-      int pred_index = block->pred()->at(j);
-      int cur_index = eval(pred_index, blocks);
-
-      Block *cur_block = blocks->adr_at(cur_index);
-      if (cur_block->semi() < block->semi()) {
-        block->set_semi(cur_block->semi());
-      }
-    }
-
-    int semi_index = block->semi();
-    Block *semi_block = array.at(semi_index);
-    semi_block->add_to_bucket(block_index);
-
-    link(block->parent(), block_index, blocks);
-    Block *parent_block = blocks->adr_at(block->parent());
-
-    for (int j=0; j<parent_block->bucket()->length(); j++) {
-      int cur_index = parent_block->bucket()->at(j);
-      int new_index = eval(cur_index, blocks);
-      Block *cur_block = blocks->adr_at(cur_index);
-      Block *new_block = blocks->adr_at(new_index);
-      int dom = block->parent();
-
-      if (new_block->semi() < cur_block->semi()) {
-        dom = new_index;
-      }
-
-      cur_block->set_dominator(dom);
-    }
-
-    parent_block->clear_bucket();
-  }
-
-  for (int i=1; i < n; i++) {
-
-    Block *block = array.at(i);
-    int block_index = block->index();
-
-    int semi_index = block->semi();
-    Block *semi_block = array.at(semi_index);
-
-    if (block->dominator() != semi_block->index()) {
-      int new_dom = blocks->adr_at(block->dominator())->dominator();
-      block->set_dominator(new_dom);
-    }
-  }
-
-  for (int i = 0; i < blocks->length(); i++) {
-    if (blocks->adr_at(i)->dominator() == -1) {
-      blocks->adr_at(i)->set_dominator(0);
-    }
-  }
-
-  // Build dominates array
-  for (int i=1; i < blocks->length(); i++) {
-    Block *block = blocks->adr_at(i);
-    int dominator = block->dominator();
-    Block *dom_block = blocks->adr_at(dominator);
-    dom_block->add_dominates(i);
-    dom_block->add_child(i);
-
-    while(dominator != 0) {
-      dominator = dom_block->dominator();
-      dom_block = blocks->adr_at(dominator);
-      dom_block->add_child(i);
-    }
-  }
-}
-
-void IdealGraphPrinter::build_common_dominator(int **common_dominator, int index, GrowableArray<Block>* blocks) {
-
-  common_dominator[index][index] = index;
-  Block *block = blocks->adr_at(index);
-  for (int i = 0; i < block->dominates()->length(); i++) {
-    Block *dominated = blocks->adr_at(block->dominates()->at(i));
-
-    for (int j=0; j<dominated->children()->length(); j++) {
-      Block *child = blocks->adr_at(dominated->children()->at(j));
-      common_dominator[index][child->index()] = common_dominator[child->index()][index] = index;
-
-      for (int k=0; k<i; k++) {
-        Block *other_dominated = blocks->adr_at(block->dominates()->at(k));
-        common_dominator[child->index()][other_dominated->index()] = common_dominator[other_dominated->index()][child->index()] = index;
-
-        for (int l=0 ; l<other_dominated->children()->length(); l++) {
-          Block *other_child = blocks->adr_at(other_dominated->children()->at(l));
-          common_dominator[child->index()][other_child->index()] = common_dominator[other_child->index()][child->index()] = index;
-        }
-      }
-    }
-
-    build_common_dominator(common_dominator, dominated->index(), blocks);
-  }
-}
-
-void IdealGraphPrinter::schedule_latest(int **common_dominator, GrowableArray<Block>* blocks) {
-
-  int queue_size = _nodes.length() + 1;
-  NodeDescription **queue = NEW_RESOURCE_ARRAY(NodeDescription *, queue_size);
-  int queue_start = 0;
-  int queue_end = 0;
-  Arena *a = new Arena();
-  VectorSet on_queue(a);
-
-  for (int i = 0; i < _nodes.length(); i++) {
-    NodeDescription *desc = _nodes.at(i);
-    if (desc) {
-      desc->init_succs();
-    }
-  }
-
-  for (int i = 0; i < _nodes.length(); i++) {
-    NodeDescription *desc = _nodes.at(i);
-    if (desc) {
-      for (uint j=0; j<desc->node()->len(); j++) {
-        Node *n = desc->node()->in(j);
-        if (n) {
-          NodeDescription *other_desc = _nodes.at(n->_idx);
-          other_desc->add_succ(desc);
-        }
-      }
-    }
-  }
-
-  for (int i = 0; i < _nodes.length(); i++) {
-    NodeDescription *desc = _nodes.at(i);
-    if (desc && desc->block_index() == -1) {
-
-      // Put Phi into same block as region
-      if (desc->node()->is_Phi() && desc->node()->in(0) && _nodes.at(desc->node()->in(0)->_idx)->block_index() != -1) {
-        int index = _nodes.at(desc->node()->in(0)->_idx)->block_index();
-        desc->set_block_index(index);
-        blocks->adr_at(index)->add_node(desc);
-
-      // Put Projections to same block as parent
-      } else if (desc->node()->is_block_proj() && _nodes.at(desc->node()->is_block_proj()->_idx)->block_index() != -1) {
-        int index = _nodes.at(desc->node()->is_block_proj()->_idx)->block_index();
-        desc->set_block_index(index);
-        blocks->adr_at(index)->add_node(desc);
-      } else {
-        queue[queue_end] = desc;
-        queue_end++;
-        on_queue.set(desc->node()->_idx);
-      }
-    }
-  }
-
-
-  int z = 0;
-  while(queue_start != queue_end && z < 10000) {
-
-    NodeDescription *desc = queue[queue_start];
-    queue_start = (queue_start + 1) % queue_size;
-    on_queue >>= desc->node()->_idx;
-
-    Node* node = desc->node();
-
-    if (desc->succs()->length() == 0) {
-      int x = 0;
-    }
-
-    int block_index = -1;
-    if (desc->succs()->length() != 0) {
-      for (int i = 0; i < desc->succs()->length(); i++) {
-          NodeDescription *cur_desc = desc->succs()->at(i);
-          if (cur_desc != desc) {
-            if (cur_desc->succs()->length() == 0) {
-
-              // Ignore nodes with 0 successors
-
-            } else if (cur_desc->block_index() == -1) {
-
-              // Let this node schedule first
-              block_index = -1;
-              break;
-
-            } else if (cur_desc->node()->is_Phi()){
-
-              // Special treatment for Phi functions
-              PhiNode *phi = cur_desc->node()->as_Phi();
-              assert(phi->in(0) && phi->in(0)->is_Region(), "Must have region node in first input");
-              RegionNode *region = phi->in(0)->as_Region();
-
-              for (uint j=1; j<phi->len(); j++) {
-                Node *cur_phi_input = phi->in(j);
-                if (cur_phi_input == desc->node() && region->in(j)) {
-                  NodeDescription *cur_region_input = _nodes.at(region->in(j)->_idx);
-                  if (cur_region_input->block_index() == -1) {
-
-                    // Let this node schedule first
-                    block_index = -1;
-                    break;
-                  } else {
-                    if (block_index == -1) {
-                      block_index = cur_region_input->block_index();
-                    } else {
-                      block_index = common_dominator[block_index][cur_region_input->block_index()];
-                    }
-                  }
-                }
-              }
-
-            } else {
-              if (block_index == -1) {
-                block_index = cur_desc->block_index();
-              } else {
-                block_index = common_dominator[block_index][cur_desc->block_index()];
-              }
-            }
-          }
-      }
-    }
-
-    if (block_index == -1) {
-      queue[queue_end] = desc;
-      queue_end = (queue_end + 1) % queue_size;
-      on_queue.set(desc->node()->_idx);
-      z++;
-    } else {
-      assert(desc->block_index() == -1, "");
-      desc->set_block_index(block_index);
-      blocks->adr_at(block_index)->add_node(desc);
-      z = 0;
-    }
-  }
-
-  for (int i = 0; i < _nodes.length(); i++) {
-    NodeDescription *desc = _nodes.at(i);
-    if (desc && desc->block_index() == -1) {
-
-      //if (desc->node()->is_Proj() || desc->node()->is_Con()) {
-        Node *parent = desc->node()->in(0);
-        uint cur = 1;
-        while(!parent && cur < desc->node()->len()) {
-          parent = desc->node()->in(cur);
-          cur++;
-        }
-
-        if (parent && _nodes.at(parent->_idx)->block_index() != -1) {
-          int index = _nodes.at(parent->_idx)->block_index();
-          desc->set_block_index(index);
-          blocks->adr_at(index)->add_node(desc);
-        } else {
-          desc->set_block_index(0);
-          blocks->adr_at(0)->add_node(desc);
-          //ShouldNotReachHere();
-        }
-      //}
-      /*
-      if (desc->node()->is_block_proj() && _nodes.at(desc->node()->is_block_proj()->_idx)->block_index() != -1) {
-        int index = _nodes.at(desc->node()->is_block_proj()->_idx)->block_index();
-        desc->set_block_index(index);
-        blocks->adr_at(index)->add_node(desc);
-      } */
-    }
-  }
-
-  for (int i = 0; i < _nodes.length(); i++) {
-    NodeDescription *desc = _nodes.at(i);
-    if (desc) {
-      desc->clear_succs();
-    }
-  }
-
-  for (int i = 0; i < _nodes.length(); i++) {
-    NodeDescription *desc = _nodes.at(i);
-    if (desc) {
-      int block_index = desc->block_index();
-
-      assert(block_index >= 0 && block_index < blocks->length(), "Block index must be in range");
-      assert(blocks->adr_at(block_index)->nodes()->contains(desc), "Node must be child of block");
-    }
-  }
-  a->destruct_contents();
-}
-
-void IdealGraphPrinter::build_blocks(Node *root) {
-
-  Arena *a = new Arena();
-  Node_Stack stack(a, 100);
-
-  VectorSet visited(a);
-  stack.push(root, 0);
-  GrowableArray<Block> blocks(a, 2, 0, Block(0));
-
-  for (int i = 0; i < _nodes.length(); i++) {
-    if (_nodes.at(i)) _nodes.at(i)->set_block_index(-1);
-  }
-
-
-  // Order nodes such that node index is equal to idx
-  for (int i = 0; i < _nodes.length(); i++) {
-
-    if (_nodes.at(i)) {
-      NodeDescription *node = _nodes.at(i);
-      int index = node->node()->_idx;
-      if (index != i) {
-        _nodes.at_grow(index);
-        NodeDescription *tmp = _nodes.at(index);
-        *(_nodes.adr_at(index)) = node;
-        *(_nodes.adr_at(i)) = tmp;
-        i--;
-      }
-    }
-  }
-
-  for (int i = 0; i < _nodes.length(); i++) {
-    NodeDescription *node = _nodes.at(i);
-    if (node) {
-      assert(node->node()->_idx == (uint)i, "");
-    }
-  }
-
-  while(stack.is_nonempty()) {
-
-    //Node *n = stack.node();
-    //int index = stack.index();
-    Node *proj = stack.node();//n->in(index);
-    const Node *parent = proj->is_block_proj();
-    if (parent == NULL) {
-      parent = proj;
-    }
-
-    if (!visited.test_set(parent->_idx)) {
-
-      NodeDescription *end_desc = _nodes.at(parent->_idx);
-      int block_index = blocks.length();
-      Block block(block_index);
-      blocks.append(block);
-      Block *b = blocks.adr_at(block_index);
-      b->set_start(end_desc);
-     // assert(end_desc->block_index() == -1, "");
-      end_desc->set_block_index(block_index);
-      b->add_node(end_desc);
-
-      // Skip any control-pinned middle'in stuff
-      Node *p = proj;
-      NodeDescription *start_desc = NULL;
-      do {
-        proj = p;                   // Update pointer to last Control
-        if (p->in(0) == NULL) {
-          start_desc = end_desc;
-          break;
-        }
-        p = p->in(0);               // Move control forward
-        start_desc = _nodes.at(p->_idx);
-        assert(start_desc, "");
-
-        if (start_desc != end_desc && start_desc->block_index() == -1) {
-          assert(start_desc->block_index() == -1, "");
-          assert(block_index < blocks.length(), "");
-          start_desc->set_block_index(block_index);
-          b->add_node(start_desc);
-        }
-     } while( !p->is_block_proj() &&
-               !p->is_block_start() );
-
-      for (uint i = 0; i < start_desc->node()->len(); i++) {
-
-          Node *pred_node = start_desc->node()->in(i);
-
-
-          if (pred_node && pred_node != start_desc->node()) {
-            const Node *cur_parent = pred_node->is_block_proj();
-            if (cur_parent != NULL) {
-              pred_node = (Node *)cur_parent;
-            }
-
-            NodeDescription *pred_node_desc = _nodes.at(pred_node->_idx);
-            if (pred_node_desc->block_index() != -1) {
-              blocks.adr_at(pred_node_desc->block_index())->add_succ(block_index);
-            }
-          }
-      }
-
-      for (DUIterator_Fast dmax, i = end_desc->node()->fast_outs(dmax); i < dmax; i++) {
-        Node* cur_succ = end_desc->node()->fast_out(i);
-        NodeDescription *cur_succ_desc = _nodes.at(cur_succ->_idx);
-
-        DUIterator_Fast dmax2, i2 = cur_succ->fast_outs(dmax2);
-        if (cur_succ->is_block_proj() && i2 < dmax2 && !cur_succ->is_Root()) {
-
-          for (; i2<dmax2; i2++) {
-            Node *cur_succ2 = cur_succ->fast_out(i2);
-            if (cur_succ2) {
-              cur_succ_desc = _nodes.at(cur_succ2->_idx);
-              if (cur_succ_desc == NULL) {
-                // dead node so skip it
-                continue;
-              }
-              if (cur_succ2 != end_desc->node() && cur_succ_desc->block_index() != -1) {
-                b->add_succ(cur_succ_desc->block_index());
-              }
-            }
-          }
-
-        } else {
-
-          if (cur_succ != end_desc->node() && cur_succ_desc && cur_succ_desc->block_index() != -1) {
-            b->add_succ(cur_succ_desc->block_index());
-          }
-        }
-      }
-
-
-      int num_preds = p->len();
-      int bottom = -1;
-      if (p->is_Region() || p->is_Phi()) {
-        bottom = 0;
-      }
-
-      int pushed = 0;
-      for (int i=num_preds - 1; i > bottom; i--) {
-        if (p->in(i) != NULL && p->in(i) != p) {
-          stack.push(p->in(i), 0);
-          pushed++;
-        }
-      }
-
-      if (pushed == 0 && p->is_Root() && !_matcher) {
-        // Special case when backedges to root are not yet built
-        for (int i = 0; i < _nodes.length(); i++) {
-          if (_nodes.at(i) && _nodes.at(i)->node()->is_SafePoint() && _nodes.at(i)->node()->outcnt() == 0) {
-            stack.push(_nodes.at(i)->node(), 0);
-          }
-        }
-      }
-
-    } else {
-      stack.pop();
-    }
-  }
-
-  build_dominators(&blocks);
-
-  int **common_dominator = NEW_RESOURCE_ARRAY(int *, blocks.length());
-  for (int i = 0; i < blocks.length(); i++) {
-    int *cur = NEW_RESOURCE_ARRAY(int, blocks.length());
-    common_dominator[i] = cur;
-
-    for (int j=0; j<blocks.length(); j++) {
-      cur[j] = 0;
-    }
-  }
-
-  for (int i = 0; i < blocks.length(); i++) {
-    blocks.adr_at(i)->add_child(blocks.adr_at(i)->index());
-  }
-  build_common_dominator(common_dominator, 0, &blocks);
-
-  schedule_latest(common_dominator, &blocks);
-
-  start_element(CONTROL_FLOW_ELEMENT);
-
-  for (int i = 0; i < blocks.length(); i++) {
-    Block *block = blocks.adr_at(i);
-
-    Properties props;
-    props.add(new Property(BLOCK_NAME_PROPERTY, i));
-    props.add(new Property(BLOCK_DOMINATOR_PROPERTY, block->dominator()));
-    start_element(BLOCK_ELEMENT, &props);
-
-    if (block->succs()->length() > 0) {
-      start_element(SUCCESSORS_ELEMENT);
-      for (int j=0; j<block->succs()->length(); j++) {
-        int cur_index = block->succs()->at(j);
-        if (cur_index != 0 /* start_block has must not have inputs */) {
-          Properties properties;
-          properties.add(new Property(BLOCK_NAME_PROPERTY, cur_index));
-          simple_element(SUCCESSOR_ELEMENT, &properties);
-        }
-      }
-      end_element(SUCCESSORS_ELEMENT);
-    }
-
-    start_element(NODES_ELEMENT);
-
-    for (int j=0; j<block->nodes()->length(); j++) {
-      NodeDescription *n = block->nodes()->at(j);
-      Properties properties;
-      properties.add(new Property(NODE_ID_PROPERTY, n->id()));
-      simple_element(NODE_ELEMENT, &properties);
-    }
-
-    end_element(NODES_ELEMENT);
-
-    end_element(BLOCK_ELEMENT);
-  }
-
-
-  end_element(CONTROL_FLOW_ELEMENT);
-
-  a->destruct_contents();
-}
-
 void IdealGraphPrinter::print_method(Compile* compile, const char *name, int level, bool clear_nodes) {
   print(compile, name, (Node *)compile->root(), level, clear_nodes);
 }
@@ -1048,872 +652,53 @@
 // Print current ideal graph
 void IdealGraphPrinter::print(Compile* compile, const char *name, Node *node, int level, bool clear_nodes) {
 
-//  if (finish && !in_method) return;
   if (!_current_method || !_should_send_method || level > PrintIdealGraphLevel) return;
 
-  assert(_current_method, "newMethod has to be called first!");
-
-  if (clear_nodes) {
-    int x = 0;
-  }
-
-  _clear_nodes = clear_nodes;
+  this->C = compile;
 
   // Warning, unsafe cast?
-  _chaitin = (PhaseChaitin *)compile->regalloc();
-  _matcher = compile->matcher();
-
-
-  // Update nodes
-  for (int i = 0; i < _nodes.length(); i++) {
-    NodeDescription *desc = _nodes.at(i);
-    if (desc) {
-      desc->set_state(Invalid);
-    }
-  }
-  Node *n = node;
-  walk(n);
-
-  // Update edges
-  for (int i = 0; i < _edges.length(); i++) {
-      _edges.at(i)->set_state(Invalid);
-  }
-
-  for (int i = 0; i < _nodes.length(); i++) {
-    NodeDescription *desc = _nodes.at(i);
-    if (desc && desc->state() != Invalid) {
-
-      int to = desc->id();
-      uint len = desc->node()->len();
-      for (uint j=0; j<len; j++) {
-        Node *n = desc->node()->in(j);
-
-        if (n) {
-
-
-          intptr_t from = (intptr_t)n;
+  _chaitin = (PhaseChaitin *)C->regalloc();
 
-          // Assert from node is valid
-          /*
-          bool ok = false;
-          for (int k=0; k<_nodes.length(); k++) {
-            NodeDescription *desc = _nodes.at(k);
-            if (desc && desc->id() == from) {
-              assert(desc->state() != Invalid, "");
-              ok = true;
-            }
-          }
-          assert(ok, "");*/
-
-          uint index = j;
-          if (index >= desc->node()->req()) {
-            index = desc->node()->req();
-          }
+  begin_head(GRAPH_ELEMENT);
+  print_attr(GRAPH_NAME_PROPERTY, (const char *)name);
+  end_head();
 
-          print_edge(from, to, index);
-        }
-      }
-    }
-  }
-
-  bool is_different = false;
-
-  for (int i = 0; i < _nodes.length(); i++) {
-    NodeDescription *desc = _nodes.at(i);
-    if (desc && desc->state() != Valid) {
-      is_different = true;
-      break;
-    }
-  }
-
-  if (!is_different) {
-    for (int i = 0; i < _edges.length(); i++) {
-      EdgeDescription *conn = _edges.at(i);
-      if (conn && conn->state() != Valid) {
-        is_different = true;
-        break;
-      }
-    }
-  }
+  head(NODES_ELEMENT);
+  walk_nodes(node, NULL);
+  tail(NODES_ELEMENT);
 
-  // No changes -> do not print graph
-  if (!is_different) return;
-
-  Properties properties;
-  properties.add(new Property(GRAPH_NAME_PROPERTY, (const char *)name));
-  start_element(GRAPH_ELEMENT, &properties);
-
-  start_element(NODES_ELEMENT);
-  for (int i = 0; i < _nodes.length(); i++) {
-    NodeDescription *desc = _nodes.at(i);
-    if (desc) {
-      desc->print(this);
-      if (desc->state() == Invalid) {
-        delete desc;
-        _nodes.at_put(i, NULL);
-      } else {
-        desc->set_state(Valid);
-      }
-    }
-  }
-  end_element(NODES_ELEMENT);
-
-  build_blocks(node);
-
-  start_element(EDGES_ELEMENT);
-  for (int i = 0; i < _edges.length(); i++) {
-    EdgeDescription *conn = _edges.at(i);
-
-    // Assert from and to nodes are valid
-    /*
-    if (!conn->state() == Invalid) {
-      bool ok1 = false;
-      bool ok2 = false;
-      for (int j=0; j<_nodes.length(); j++) {
-        NodeDescription *desc = _nodes.at(j);
-        if (desc && desc->id() == conn->from()) {
-          ok1 = true;
-        }
+  head(EDGES_ELEMENT);
+  walk_nodes(node, (void *)1);
+  tail(EDGES_ELEMENT);
+  if (C->cfg() != NULL) {
+    head(CONTROL_FLOW_ELEMENT);
+    for (uint i = 0; i < C->cfg()->_blocks.size(); i++) {
+      Block *b = C->cfg()->_blocks[i];
+      begin_head(BLOCK_ELEMENT);
+      print_attr(BLOCK_NAME_PROPERTY, b->_pre_order);
+      end_head();
 
-        if (desc && desc->id() == conn->to()) {
-          ok2 = true;
-        }
+      head(SUCCESSORS_ELEMENT);
+      for (uint s = 0; s < C->cfg()->_blocks[i]->_num_succs; s++) {
+        begin_elem(SUCCESSOR_ELEMENT);
+        print_attr(BLOCK_NAME_PROPERTY, b->_succs[s]->_pre_order);
+        end_elem();
       }
-
-      assert(ok1, "from node not found!");
-      assert(ok2, "to node not found!");
-    }*/
-
-    conn->print(this);
-    if (conn->state() == Invalid) {
-      _edges.remove_at(i);
-      delete conn;
-      i--;
-    }
-  }
-
-  end_element(EDGES_ELEMENT);
+      tail(SUCCESSORS_ELEMENT);
 
-  end_element(GRAPH_ELEMENT);
-
-  _output->flush();
-}
-
-// Print edge
-void IdealGraphPrinter::print_edge(int from, int to, int index) {
+      tail(BLOCK_ELEMENT);
+    }
 
-  EdgeDescription *conn = new EdgeDescription(from, to, index);
-  for (int i = 0; i < _edges.length(); i++) {
-    if (_edges.at(i)->equals(conn)) {
-      conn->set_state(Valid);
-      delete _edges.at(i);
-      _edges.at_put(i, conn);
-      return;
-    }
+    tail(CONTROL_FLOW_ELEMENT);
   }
-
-  _edges.append(conn);
+  tail(GRAPH_ELEMENT);
+  output()->flush();
 }
 
 extern const char *NodeClassNames[];
 
-// Create node description
-IdealGraphPrinter::NodeDescription *IdealGraphPrinter::create_node_description(Node* node) {
-
-#ifndef PRODUCT
-  node->_in_dump_cnt++;
-  NodeDescription *desc = new NodeDescription(node);
-  desc->properties()->add(new Property(NODE_NAME_PROPERTY, (const char *)node->Name()));
-
-  const Type *t = node->bottom_type();
-  desc->properties()->add(new Property("type", (const char *)Type::msg[t->base()]));
-
-  desc->properties()->add(new Property("idx", node->_idx));
-#ifdef ASSERT
-  desc->properties()->add(new Property("debug_idx", node->_debug_idx));
-#endif
-
-
-  const jushort flags = node->flags();
-  if (flags & Node::Flag_is_Copy) {
-    desc->properties()->add(new Property("is_copy", "true"));
-  }
-  if (flags & Node::Flag_is_Call) {
-    desc->properties()->add(new Property("is_call", "true"));
-  }
-  if (flags & Node::Flag_rematerialize) {
-    desc->properties()->add(new Property("rematerialize", "true"));
-  }
-  if (flags & Node::Flag_needs_anti_dependence_check) {
-    desc->properties()->add(new Property("needs_anti_dependence_check", "true"));
-  }
-  if (flags & Node::Flag_is_macro) {
-    desc->properties()->add(new Property("is_macro", "true"));
-  }
-  if (flags & Node::Flag_is_Con) {
-    desc->properties()->add(new Property("is_con", "true"));
-  }
-  if (flags & Node::Flag_is_cisc_alternate) {
-    desc->properties()->add(new Property("is_cisc_alternate", "true"));
-  }
-  if (flags & Node::Flag_is_Branch) {
-    desc->properties()->add(new Property("is_branch", "true"));
-  }
-  if (flags & Node::Flag_is_block_start) {
-    desc->properties()->add(new Property("is_block_start", "true"));
-  }
-  if (flags & Node::Flag_is_Goto) {
-    desc->properties()->add(new Property("is_goto", "true"));
-  }
-  if (flags & Node::Flag_is_dead_loop_safe) {
-    desc->properties()->add(new Property("is_dead_loop_safe", "true"));
-  }
-  if (flags & Node::Flag_may_be_short_branch) {
-    desc->properties()->add(new Property("may_be_short_branch", "true"));
-  }
-  if (flags & Node::Flag_is_safepoint_node) {
-    desc->properties()->add(new Property("is_safepoint_node", "true"));
-  }
-  if (flags & Node::Flag_is_pc_relative) {
-    desc->properties()->add(new Property("is_pc_relative", "true"));
-  }
-
-  if (_matcher) {
-    if (_matcher->is_shared(desc->node())) {
-      desc->properties()->add(new Property("is_shared", "true"));
-    } else {
-      desc->properties()->add(new Property("is_shared", "false"));
-    }
-
-    if (_matcher->is_dontcare(desc->node())) {
-      desc->properties()->add(new Property("is_dontcare", "true"));
-    } else {
-      desc->properties()->add(new Property("is_dontcare", "false"));
-    }
-  }
-
-  if (node->is_Proj()) {
-    desc->properties()->add(new Property("con", (int)node->as_Proj()->_con));
-  }
-
-  if (node->is_Mach()) {
-    desc->properties()->add(new Property("idealOpcode", (const char *)NodeClassNames[node->as_Mach()->ideal_Opcode()]));
-  }
-
-
-
-
-
-  outputStream *oldTty = tty;
-  buffer[0] = 0;
-  stringStream s2(buffer, sizeof(buffer) - 1);
-
-  node->dump_spec(&s2);
-  assert(s2.size() < sizeof(buffer), "size in range");
-  desc->properties()->add(new Property("dump_spec", buffer));
-
-  if (node->is_block_proj()) {
-    desc->properties()->add(new Property("is_block_proj", "true"));
-  }
-
-  if (node->is_block_start()) {
-    desc->properties()->add(new Property("is_block_start", "true"));
-  }
-
-  const char *short_name = "short_name";
-  if (strcmp(node->Name(), "Parm") == 0 && node->as_Proj()->_con >= TypeFunc::Parms) {
-      int index = node->as_Proj()->_con - TypeFunc::Parms;
-      if (index >= 10) {
-        desc->properties()->add(new Property(short_name, "PA"));
-      } else {
-        sprintf(buffer, "P%d", index);
-        desc->properties()->add(new Property(short_name, buffer));
-      }
-  } else if (strcmp(node->Name(), "IfTrue") == 0) {
-     desc->properties()->add(new Property(short_name, "T"));
-  } else if (strcmp(node->Name(), "IfFalse") == 0) {
-     desc->properties()->add(new Property(short_name, "F"));
-  } else if ((node->is_Con() && node->is_Type()) || node->is_Proj()) {
-
-    if (t->base() == Type::Int && t->is_int()->is_con()) {
-      const TypeInt *typeInt = t->is_int();
-      assert(typeInt->is_con(), "must be constant");
-      jint value = typeInt->get_con();
-
-      // max. 2 chars allowed
-      if (value >= -9 && value <= 99) {
-        sprintf(buffer, "%d", value);
-        desc->properties()->add(new Property(short_name, buffer));
-      }
-      else
-      {
-        desc->properties()->add(new Property(short_name, "I"));
-      }
-    } else if (t == Type::TOP) {
-      desc->properties()->add(new Property(short_name, "^"));
-    } else if (t->base() == Type::Long && t->is_long()->is_con()) {
-      const TypeLong *typeLong = t->is_long();
-      assert(typeLong->is_con(), "must be constant");
-      jlong value = typeLong->get_con();
-
-      // max. 2 chars allowed
-      if (value >= -9 && value <= 99) {
-        sprintf(buffer, "%d", value);
-        desc->properties()->add(new Property(short_name, buffer));
-      }
-      else
-      {
-        desc->properties()->add(new Property(short_name, "L"));
-      }
-    } else if (t->base() == Type::KlassPtr) {
-      const TypeKlassPtr *typeKlass = t->is_klassptr();
-      desc->properties()->add(new Property(short_name, "CP"));
-    } else if (t->base() == Type::Control) {
-      desc->properties()->add(new Property(short_name, "C"));
-    } else if (t->base() == Type::Memory) {
-      desc->properties()->add(new Property(short_name, "M"));
-    } else if (t->base() == Type::Abio) {
-      desc->properties()->add(new Property(short_name, "IO"));
-    } else if (t->base() == Type::Return_Address) {
-      desc->properties()->add(new Property(short_name, "RA"));
-    } else if (t->base() == Type::AnyPtr) {
-      desc->properties()->add(new Property(short_name, "P"));
-    } else if (t->base() == Type::RawPtr) {
-      desc->properties()->add(new Property(short_name, "RP"));
-    } else if (t->base() == Type::AryPtr) {
-      desc->properties()->add(new Property(short_name, "AP"));
-    }
-  }
-
-  if (node->is_SafePoint()) {
-    SafePointNode *safePointNode = node->as_SafePoint();
-    if (safePointNode->jvms()) {
-      stringStream bciStream;
-      bciStream.print("%d ", safePointNode->jvms()->bci());
-      JVMState *caller = safePointNode->jvms()->caller();
-      while(caller) {
-        bciStream.print("%d ", caller->bci());
-
-        caller = caller->caller();
-      }
-      desc->properties()->add(new Property("bci", bciStream.as_string()));
-    }
-  }
-
-  if (_chaitin && _chaitin != (PhaseChaitin *)0xdeadbeef) {
-    buffer[0] = 0;
-    _chaitin->dump_register(node, buffer);
-    desc->properties()->add(new Property("reg", buffer));
-    desc->properties()->add(new Property("lrg", _chaitin->n2lidx(node)));
-  }
-
-
-  node->_in_dump_cnt--;
-  return desc;
-#else
-  return NULL;
-#endif
-}
-
-void IdealGraphPrinter::pre_node(Node* node, void *env) {
-
-  IdealGraphPrinter *printer = (IdealGraphPrinter *)env;
-
-  NodeDescription *newDesc = printer->create_node_description(node);
-
-  if (printer->_clear_nodes) {
-
-    printer->_nodes.append(newDesc);
-  } else {
-
-    NodeDescription *desc = printer->_nodes.at_grow(node->_idx, NULL);
-
-    if (desc && desc->equals(newDesc)) {
-      //desc->set_state(Valid);
-      //desc->set_node(node);
-      delete desc;
-      printer->_nodes.at_put(node->_idx, NULL);
-      newDesc->set_state(Valid);
-      //printer->_nodes.at_put(node->_idx, newDesc);
-    } else {
-
-      if (desc && desc->id() == newDesc->id()) {
-        delete desc;
-        printer->_nodes.at_put(node->_idx, NULL);
-        newDesc->set_state(New);
-
-      }
-
-      //if (desc) {
-      //  delete desc;
-      //}
-
-      //printer->_nodes.at_put(node->_idx, newDesc);
-    }
-
-    printer->_nodes.append(newDesc);
-  }
-}
-
-void IdealGraphPrinter::post_node(Node* node, void *env) {
-}
-
 outputStream *IdealGraphPrinter::output() {
-  return _output;
-}
-
-IdealGraphPrinter::Description::Description() {
-  _state = New;
-}
-
-void IdealGraphPrinter::Description::print(IdealGraphPrinter *printer) {
-  if (_state == Invalid) {
-    print_removed(printer);
-  } else if (_state == New) {
-    print_changed(printer);
-  }
-}
-
-void IdealGraphPrinter::Description::set_state(State s) {
-  _state = s;
-}
-
-IdealGraphPrinter::State IdealGraphPrinter::Description::state() {
-  return _state;
-}
-
-void IdealGraphPrinter::Block::set_proj(NodeDescription *n) {
-  _proj = n;
-}
-
-void IdealGraphPrinter::Block::set_start(NodeDescription *n) {
-  _start = n;
-}
-
-int IdealGraphPrinter::Block::semi() {
-  return _semi;
-}
-
-int IdealGraphPrinter::Block::parent() {
-  return _parent;
-}
-
-GrowableArray<int>* IdealGraphPrinter::Block::bucket() {
-  return &_bucket;
-}
-
-GrowableArray<int>* IdealGraphPrinter::Block::children() {
-  return &_children;
-}
-
-void IdealGraphPrinter::Block::add_child(int i) {
-  _children.append(i);
-}
-
-GrowableArray<int>* IdealGraphPrinter::Block::dominates() {
-  return &_dominates;
-}
-
-void IdealGraphPrinter::Block::add_dominates(int i) {
-  _dominates.append(i);
-}
-
-void IdealGraphPrinter::Block::add_to_bucket(int i) {
-  _bucket.append(i);
-}
-
-void IdealGraphPrinter::Block::clear_bucket() {
-  _bucket.clear();
-}
-
-void IdealGraphPrinter::Block::set_dominator(int i) {
-  _dominator = i;
-}
-
-void IdealGraphPrinter::Block::set_label(int i) {
-  _label = i;
-}
-
-int IdealGraphPrinter::Block::label() {
-  return _label;
-}
-
-int IdealGraphPrinter::Block::ancestor() {
-  return _ancestor;
-}
-
-void IdealGraphPrinter::Block::set_ancestor(int i) {
-  _ancestor = i;
-}
-
-int IdealGraphPrinter::Block::dominator() {
-  return _dominator;
-}
-
-int IdealGraphPrinter::Block::index() {
-  return _index;
-}
-
-void IdealGraphPrinter::Block::set_parent(int i) {
-  _parent = i;
-}
-
-GrowableArray<int>* IdealGraphPrinter::Block::pred() {
-  return &_pred;
-}
-
-void IdealGraphPrinter::Block::set_semi(int i) {
-  _semi = i;
-}
-
-IdealGraphPrinter::Block::Block() {
-}
-
-IdealGraphPrinter::Block::Block(int index) {
-  _index = index;
-  _label = index;
-  _semi = -1;
-  _ancestor = -1;
-  _dominator = -1;
-}
-
-void IdealGraphPrinter::Block::add_pred(int i) {
-  _pred.append(i);
-}
-
-IdealGraphPrinter::NodeDescription *IdealGraphPrinter::Block::proj() {
-  return _proj;
-}
-
-IdealGraphPrinter::NodeDescription *IdealGraphPrinter::Block::start() {
-  return _start;
-}
-
-GrowableArray<int>* IdealGraphPrinter::Block::succs() {
-  return &_succs;
-}
-
-void IdealGraphPrinter::Block::add_succ(int index) {
-
-  if (this->_index == 16 && index == 15) {
-    int x = 0;
-  }
-
-  if (!_succs.contains(index)) {
-    _succs.append(index);
-  }
-}
-
-
-void IdealGraphPrinter::Block::add_node(NodeDescription *n) {
-  if (!_nodes.contains(n)) {
-    _nodes.append(n);
-  }
-}
-
-GrowableArray<IdealGraphPrinter::NodeDescription *>* IdealGraphPrinter::Block::nodes() {
-  return &_nodes;
-}
-
-int IdealGraphPrinter::NodeDescription::count = 0;
-
-IdealGraphPrinter::NodeDescription::NodeDescription(Node* node) : _node(node) {
-  _id = (intptr_t)(node);
-  _block_index = -1;
-}
-
-IdealGraphPrinter::NodeDescription::~NodeDescription() {
-  _properties.clean();
-}
-
-// void IdealGraphPrinter::NodeDescription::set_node(Node* node) {
-//   //this->_node = node;
-// }
-
-int IdealGraphPrinter::NodeDescription::block_index() {
-  return _block_index;
-}
-
-
-GrowableArray<IdealGraphPrinter::NodeDescription *>* IdealGraphPrinter::NodeDescription::succs() {
-  return &_succs;
-}
-
-void IdealGraphPrinter::NodeDescription::clear_succs() {
-  _succs.clear();
-}
-
-void IdealGraphPrinter::NodeDescription::init_succs() {
-  _succs = GrowableArray<NodeDescription *>();
-}
-
-void IdealGraphPrinter::NodeDescription::add_succ(NodeDescription *desc) {
-  _succs.append(desc);
-}
-
-void IdealGraphPrinter::NodeDescription::set_block_index(int i) {
-  _block_index = i;
-}
-
-bool IdealGraphPrinter::NodeDescription::equals(NodeDescription *desc) {
-  if (desc == NULL) return false;
-  if (desc->id() != id()) return false;
-  return properties()->equals(desc->properties());
-}
-
-Node* IdealGraphPrinter::NodeDescription::node() {
-  return _node;
-}
-
-IdealGraphPrinter::Properties* IdealGraphPrinter::NodeDescription::properties() {
-  return &_properties;
-}
-
-uint IdealGraphPrinter::NodeDescription::id() {
-  return _id;
-}
-
-void IdealGraphPrinter::NodeDescription::print_changed(IdealGraphPrinter *printer) {
-
-
-  Properties properties;
-  properties.add(new Property(NODE_ID_PROPERTY, id()));
-  printer->start_element(NODE_ELEMENT, &properties);
-
-  this->properties()->print(printer);
-
-
-  printer->end_element(NODE_ELEMENT);
-}
-
-void IdealGraphPrinter::NodeDescription::print_removed(IdealGraphPrinter *printer) {
-
-  Properties properties;
-  properties.add(new Property(NODE_ID_PROPERTY, id()));
-  printer->simple_element(REMOVE_NODE_ELEMENT, &properties);
-}
-
-IdealGraphPrinter::EdgeDescription::EdgeDescription(int from, int to, int index) {
-  this->_from = from;
-  this->_to = to;
-  this->_index = index;
-}
-
-IdealGraphPrinter::EdgeDescription::~EdgeDescription() {
-}
-
-int IdealGraphPrinter::EdgeDescription::from() {
-  return _from;
-}
-
-int IdealGraphPrinter::EdgeDescription::to() {
-  return _to;
-}
-
-void IdealGraphPrinter::EdgeDescription::print_changed(IdealGraphPrinter *printer) {
-
-  Properties properties;
-  properties.add(new Property(INDEX_PROPERTY, _index));
-  properties.add(new Property(FROM_PROPERTY, _from));
-  properties.add(new Property(TO_PROPERTY, _to));
-  printer->simple_element(EDGE_ELEMENT, &properties);
-}
-
-void IdealGraphPrinter::EdgeDescription::print_removed(IdealGraphPrinter *printer) {
-
-  Properties properties;
-  properties.add(new Property(INDEX_PROPERTY, _index));
-  properties.add(new Property(FROM_PROPERTY, _from));
-  properties.add(new Property(TO_PROPERTY, _to));
-  printer->simple_element(REMOVE_EDGE_ELEMENT, &properties);
-}
-
-bool IdealGraphPrinter::EdgeDescription::equals(IdealGraphPrinter::EdgeDescription *desc) {
-  if (desc == NULL) return false;
-  return (_from == desc->_from && _to == desc->_to && _index == desc->_index);
-}
-
-IdealGraphPrinter::Properties::Properties() : list(new (ResourceObj::C_HEAP) GrowableArray<Property *>(2, 0, NULL, true)) {
-}
-
-IdealGraphPrinter::Properties::~Properties() {
-  clean();
-  delete list;
-}
-
-void IdealGraphPrinter::Properties::add(Property *p) {
-  assert(p != NULL, "Property not NULL");
-  list->append(p);
-}
-
-void IdealGraphPrinter::Properties::print(IdealGraphPrinter *printer) {
-  printer->start_element(PROPERTIES_ELEMENT);
-
-  for (int i = 0; i < list->length(); i++) {
-    list->at(i)->print(printer);
-  }
-
-  printer->end_element(PROPERTIES_ELEMENT);
-}
-
-void IdealGraphPrinter::Properties::clean() {
-  for (int i = 0; i < list->length(); i++) {
-    delete list->at(i);
-    list->at_put(i, NULL);
-  }
-  list->clear();
-  assert(list->length() == 0, "List cleared");
-}
-
-void IdealGraphPrinter::Properties::remove(const char *name) {
-  for (int i = 0; i < list->length(); i++) {
-    if (strcmp(list->at(i)->name(), name) == 0) {
-      delete list->at(i);
-      list->remove_at(i);
-      i--;
-    }
-  }
-}
-
-void IdealGraphPrinter::Properties::print_as_attributes(IdealGraphPrinter *printer) {
-
-  for (int i = 0; i < list->length(); i++) {
-    assert(list->at(i) != NULL, "Property not null!");
-    printer->output()->print(" ");
-    list->at(i)->print_as_attribute(printer);
-  }
-}
-
-bool IdealGraphPrinter::Properties::equals(Properties* p) {
-  if (p->list->length() != this->list->length()) return false;
-
-  for (int i = 0; i < list->length(); i++) {
-    assert(list->at(i) != NULL, "Property not null!");
-    if (!list->at(i)->equals(p->list->at(i))) return false;
-  }
-
-  return true;
-}
-
-IdealGraphPrinter::Property::Property() {
-  _name = NULL;
-  _value = NULL;
-}
-
-const char *IdealGraphPrinter::Property::name() {
-  return _name;
-}
-
-IdealGraphPrinter::Property::Property(const Property* p) {
-
-  this->_name = NULL;
-  this->_value = NULL;
-
-  if (p->_name != NULL) {
-    _name = dup(p->_name);
-  }
-
-  if (p->_value) {
-    _value = dup(p->_value);
-  }
-}
-
-IdealGraphPrinter::Property::~Property() {
-
-  clean();
-}
-
-IdealGraphPrinter::Property::Property(const char *name, const char *value) {
-
-  assert(name, "Name must not be null!");
-  assert(value, "Value must not be null!");
-
-  _name = dup(name);
-  _value = dup(value);
-}
-
-IdealGraphPrinter::Property::Property(const char *name, int intValue) {
-  _name = dup(name);
-
-  stringStream stream;
-  stream.print("%d", intValue);
-  _value = dup(stream.as_string());
-}
-
-void IdealGraphPrinter::Property::clean() {
-  if (_name) {
-    delete _name;
-    _name = NULL;
-  }
-
-  if (_value) {
-    delete _value;
-    _value = NULL;
-  }
-}
-
-
-bool IdealGraphPrinter::Property::is_null() {
-  return _name == NULL;
-}
-
-void IdealGraphPrinter::Property::print(IdealGraphPrinter *printer) {
-
-  assert(!is_null(), "null properties cannot be printed!");
-  Properties properties;
-  properties.add(new Property(PROPERTY_NAME_PROPERTY, _name));
-  printer->start_element(PROPERTY_ELEMENT, &properties, false, false);
-  printer->print_xml(_value);
-  printer->end_element(PROPERTY_ELEMENT, false, true);
-}
-
-void IdealGraphPrinter::Property::print_as_attribute(IdealGraphPrinter *printer) {
-
-  printer->output()->print(_name);
-  printer->output()->print("=\"");
-  printer->print_xml(_value);
-  printer->output()->print("\"");
-}
-
-
-bool IdealGraphPrinter::Property::equals(Property* p) {
-
-  if (is_null() && p->is_null()) return true;
-  if (is_null()) return false;
-  if (p->is_null()) return false;
-
-  int cmp1 = strcmp(p->_name, _name);
-  if (cmp1 != 0) return false;
-
-  int cmp2 = strcmp(p->_value, _value);
-  if (cmp2 != 0) return false;
-
-  return true;
-}
-
-void IdealGraphPrinter::print_xml(const char *value) {
-  size_t len = strlen(value);
-
-  char buf[2];
-  buf[1] = 0;
-  for (size_t i = 0; i < len; i++) {
-    char c = value[i];
-
-    switch(c) {
-      case '<':
-        output()->print("&lt;");
-        break;
-
-      case '>':
-        output()->print("&gt;");
-        break;
-
-      default:
-        buf[0] = c;
-        output()->print(buf);
-        break;
-    }
-  }
+  return _xml;
 }
 
 #endif
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -82,222 +82,42 @@
   static const char *METHOD_SHORT_NAME_PROPERTY;
   static const char *ASSEMBLY_ELEMENT;
 
-  class Property {
-
-  private:
-
-    const char *_name;
-    const char *_value;
-
-  public:
-
-    Property();
-    Property(const Property* p);
-    ~Property();
-    Property(const char *name, const char *value);
-    Property(const char *name, int value);
-    bool equals(Property* p);
-    void print(IdealGraphPrinter *printer);
-    void print_as_attribute(IdealGraphPrinter *printer);
-    bool is_null();
-    void clean();
-    const char *name();
-
-    static const char* dup(const char *str) {
-      char * copy = new char[strlen(str)+1];
-      strcpy(copy, str);
-      return copy;
-    }
-
-  };
-
-  class Properties {
-
-  private:
-
-    GrowableArray<Property *> *list;
-
-  public:
-
-    Properties();
-    ~Properties();
-    void add(Property *p);
-    void remove(const char *name);
-    bool equals(Properties* p);
-    void print(IdealGraphPrinter *printer);
-    void print_as_attributes(IdealGraphPrinter *printer);
-    void clean();
-
-  };
-
-
-  class Description {
-
-  private:
-
-    State _state;
-
-  public:
-
-    Description();
-
-    State state();
-    void set_state(State s);
-    void print(IdealGraphPrinter *printer);
-    virtual void print_changed(IdealGraphPrinter *printer) = 0;
-    virtual void print_removed(IdealGraphPrinter *printer) = 0;
-
-  };
-
-  class NodeDescription : public Description{
-
-  public:
-
-    static int count;
-
-  private:
-
-    GrowableArray<NodeDescription *> _succs;
-    int _block_index;
-    uintptr_t _id;
-    Properties _properties;
-    Node* _node;
-
-  public:
-
-    NodeDescription(Node* node);
-    ~NodeDescription();
-    Node* node();
-
-    // void set_node(Node* node);
-    GrowableArray<NodeDescription *>* succs();
-    void init_succs();
-    void clear_succs();
-    void add_succ(NodeDescription *desc);
-    int block_index();
-    void set_block_index(int i);
-    Properties* properties();
-    virtual void print_changed(IdealGraphPrinter *printer);
-    virtual void print_removed(IdealGraphPrinter *printer);
-    bool equals(NodeDescription *desc);
-    uint id();
-
-  };
-
-  class Block {
-
-  private:
-
-    NodeDescription *_start;
-    NodeDescription *_proj;
-    GrowableArray<int> _succs;
-    GrowableArray<NodeDescription *> _nodes;
-    GrowableArray<int> _dominates;
-    GrowableArray<int> _children;
-    int _semi;
-    int _parent;
-    GrowableArray<int> _pred;
-    GrowableArray<int> _bucket;
-    int _index;
-    int _dominator;
-    int _ancestor;
-    int _label;
-
-  public:
-
-    Block();
-    Block(int index);
-
-    void add_node(NodeDescription *n);
-    GrowableArray<NodeDescription *>* nodes();
-    GrowableArray<int>* children();
-    void add_child(int i);
-    void add_succ(int index);
-    GrowableArray<int>* succs();
-    GrowableArray<int>* dominates();
-    void add_dominates(int i);
-    NodeDescription *start();
-    NodeDescription *proj();
-    void set_start(NodeDescription *n);
-    void set_proj(NodeDescription *n);
-
-    int label();
-    void set_label(int i);
-    int ancestor();
-    void set_ancestor(int i);
-    int index();
-    int dominator();
-    void set_dominator(int i);
-    int parent();
-    void set_parent(int i);
-    int semi();
-    GrowableArray<int>* bucket();
-    void add_to_bucket(int i);
-    void clear_bucket();
-    GrowableArray<int>* pred();
-    void set_semi(int i);
-    void add_pred(int i);
-
-  };
-
-  class EdgeDescription : public Description {
-
-  private:
-
-    int _from;
-    int _to;
-    int _index;
-  public:
-
-    EdgeDescription(int from, int to, int index);
-    ~EdgeDescription();
-
-    virtual void print_changed(IdealGraphPrinter *printer);
-    virtual void print_removed(IdealGraphPrinter *printer);
-    bool equals(EdgeDescription *desc);
-    int from();
-    int to();
-  };
-
+  elapsedTimer _walk_time;
+  elapsedTimer _output_time;
+  elapsedTimer _build_blocks_time;
 
   static int _file_count;
   networkStream *_stream;
+  xmlStream *_xml;
   outputStream *_output;
   ciMethod *_current_method;
-  GrowableArray<NodeDescription *> _nodes;
-  GrowableArray<EdgeDescription *> _edges;
   int _depth;
-  Arena *_arena;
   char buffer[128];
   bool _should_send_method;
   PhaseChaitin* _chaitin;
-  bool _clear_nodes;
-  Matcher* _matcher;
   bool _traverse_outs;
-
-  void start_element_helper(const char *name, Properties *properties, bool endElement, bool print_indent = false, bool print_return = true);
-  NodeDescription *create_node_description(Node* node);
+  Compile *C;
 
   static void pre_node(Node* node, void *env);
   static void post_node(Node* node, void *env);
 
-  void schedule_latest(int **common_dominator, GrowableArray<Block>* blocks);
-  void build_common_dominator(int **common_dominator, int index, GrowableArray<Block>* blocks);
-  void compress(int index, GrowableArray<Block>* blocks);
-  int eval(int index, GrowableArray<Block>* blocks);
-  void link(int index1, int index2, GrowableArray<Block>* blocks);
-  void build_dominators(GrowableArray<Block>* blocks);
-  void build_blocks(Node *node);
-  void walk(Node *n);
-  void start_element(const char *name, Properties *properties = NULL, bool print_indent = false, bool print_return = true);
-  void simple_element(const char *name, Properties *properties = NULL, bool print_indent = false);
-  void end_element(const char *name, bool print_indent = false, bool print_return = true);
-  void print_edge(int from, int to, int index);
   void print_indent();
   void print_method(ciMethod *method, int bci, InlineTree *tree);
   void print_inline_tree(InlineTree *tree);
-  void clear_nodes();
-
+  void visit_node(Node *n, void *param);
+  void walk_nodes(Node *start, void *param);
+  void begin_elem(const char *s);
+  void end_elem();
+  void begin_head(const char *s);
+  void end_head();
+  void print_attr(const char *name, const char *val);
+  void print_attr(const char *name, intptr_t val);
+  void print_prop(const char *name, const char *val);
+  void print_prop(const char *name, int val);
+  void tail(const char *name);
+  void head(const char *name);
+  void text(const char *s);
+  intptr_t get_node_id(Node *n);
   IdealGraphPrinter();
   ~IdealGraphPrinter();
 
@@ -308,7 +128,6 @@
 
   bool traverse_outs();
   void set_traverse_outs(bool b);
-  void print_ifg(PhaseIFG* ifg);
   outputStream *output();
   void print_inlining(Compile* compile);
   void begin_method(Compile* compile);
--- a/hotspot/src/share/vm/opto/library_call.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/library_call.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -2194,14 +2194,15 @@
     pre_barrier(control(), base, adr, alias_idx, newval, value_type, T_OBJECT);
 #ifdef _LP64
     if (adr->bottom_type()->is_ptr_to_narrowoop()) {
+      Node *newval_enc = _gvn.transform(new (C, 2) EncodePNode(newval, newval->bottom_type()->make_narrowoop()));
+      Node *oldval_enc = _gvn.transform(new (C, 2) EncodePNode(oldval, oldval->bottom_type()->make_narrowoop()));
       cas = _gvn.transform(new (C, 5) CompareAndSwapNNode(control(), mem, adr,
-                                                           EncodePNode::encode(&_gvn, newval),
-                                                           EncodePNode::encode(&_gvn, oldval)));
+                                                          newval_enc, oldval_enc));
     } else
 #endif
-      {
-        cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval));
-      }
+    {
+      cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval));
+    }
     post_barrier(control(), cas, base, adr, alias_idx, newval, T_OBJECT, true);
     break;
   default:
--- a/hotspot/src/share/vm/opto/loopTransform.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -690,7 +690,7 @@
   // (the main-loop trip-counter exit value) because we will be changing
   // the exit value (via unrolling) so we cannot constant-fold away the zero
   // trip guard until all unrolling is done.
-  Node *zer_opaq = new (C, 2) Opaque1Node(incr);
+  Node *zer_opaq = new (C, 2) Opaque1Node(C, incr);
   Node *zer_cmp  = new (C, 3) CmpINode( zer_opaq, limit );
   Node *zer_bol  = new (C, 2) BoolNode( zer_cmp, b_test );
   register_new_node( zer_opaq, new_main_exit );
@@ -760,7 +760,7 @@
   // pre-loop, the main-loop may not execute at all.  Later in life this
   // zero-trip guard will become the minimum-trip guard when we unroll
   // the main-loop.
-  Node *min_opaq = new (C, 2) Opaque1Node(limit);
+  Node *min_opaq = new (C, 2) Opaque1Node(C, limit);
   Node *min_cmp  = new (C, 3) CmpINode( pre_incr, min_opaq );
   Node *min_bol  = new (C, 2) BoolNode( min_cmp, b_test );
   register_new_node( min_opaq, new_pre_exit );
@@ -810,7 +810,7 @@
 
   // Save the original loop limit in this Opaque1 node for
   // use by range check elimination.
-  Node *pre_opaq  = new (C, 3) Opaque1Node(pre_limit, limit);
+  Node *pre_opaq  = new (C, 3) Opaque1Node(C, pre_limit, limit);
 
   register_new_node( pre_limit, pre_head->in(0) );
   register_new_node( pre_opaq , pre_head->in(0) );
--- a/hotspot/src/share/vm/opto/loopUnswitch.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/loopUnswitch.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -205,7 +205,7 @@
 
   Node *cont      = _igvn.intcon(1);
   set_ctrl(cont, C->root());
-  Node* opq       = new (C, 2) Opaque1Node(cont);
+  Node* opq       = new (C, 2) Opaque1Node(C, cont);
   register_node(opq, outer_loop, entry, dom_depth(entry));
   Node *bol       = new (C, 2) Conv2BNode(opq);
   register_node(bol, outer_loop, entry, dom_depth(entry));
--- a/hotspot/src/share/vm/opto/loopnode.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/loopnode.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -1072,8 +1072,6 @@
       phase->_igvn.add_users_to_worklist(l->fast_out(i));
   }
 
-  phase->C->print_method("After beautify loops", 3);
-
   // Now recursively beautify nested loops
   if( _child ) result |= _child->beautify_loops( phase );
   if( _next  ) result |= _next ->beautify_loops( phase );
@@ -1470,6 +1468,8 @@
       }
       // Reset loop nesting depth
       _ltree_root->set_nest( 0 );
+
+      C->print_method("After beautify loops", 3);
     }
   }
 
--- a/hotspot/src/share/vm/opto/loopopts.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/loopopts.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -41,7 +41,7 @@
   const Type* type = n->bottom_type();
   const TypeOopPtr *t_oop = _igvn.type(n)->isa_oopptr();
   Node *phi;
-  if( t_oop != NULL && t_oop->is_instance_field() ) {
+  if( t_oop != NULL && t_oop->is_known_instance_field() ) {
     int iid    = t_oop->instance_id();
     int index  = C->get_alias_index(t_oop);
     int offset = t_oop->offset();
@@ -2685,7 +2685,7 @@
       if( !cle->stride_is_con() ) continue;
       // Hit!  Refactor use to use the post-incremented tripcounter.
       // Compute a post-increment tripcounter.
-      Node *opaq = new (C, 2) Opaque2Node( cle->incr() );
+      Node *opaq = new (C, 2) Opaque2Node( C, cle->incr() );
       register_new_node( opaq, u_ctrl );
       Node *neg_stride = _igvn.intcon(-cle->stride_con());
       set_ctrl(neg_stride, C->root());
--- a/hotspot/src/share/vm/opto/machnode.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/machnode.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -262,17 +262,19 @@
     // Now we have collected every part of the ADLC MEMORY_INTER.
     // See if it adds up to a base + offset.
     if (index != NULL) {
-      if (!index->is_Con()) {
-        const TypeNarrowOop* narrowoop = index->bottom_type()->isa_narrowoop();
-        if (narrowoop != NULL) {
-          // Memory references through narrow oops have a
-          // funny base so grab the type from the index.
-          adr_type = narrowoop->make_oopptr();
-          return NULL;
-        }
+      const Type* t_index = index->bottom_type();
+      if (t_index->isa_narrowoop()) { // EncodeN, LoadN, LoadConN, LoadNKlass.
+        // Memory references through narrow oops have a
+        // funny base so grab the type from the index:
+        // [R12 + narrow_oop_reg<<3 + offset]
+        assert(base == NULL, "Memory references through narrow oops have no base");
+        offset = disp;
+        adr_type = t_index->make_ptr()->add_offset(offset);
+        return NULL;
+      } else if (!index->is_Con()) {
         disp = Type::OffsetBot;
       } else if (disp != Type::OffsetBot) {
-        const TypeX* ti = index->bottom_type()->isa_intptr_t();
+        const TypeX* ti = t_index->isa_intptr_t();
         if (ti == NULL) {
           disp = Type::OffsetBot;  // a random constant??
         } else {
--- a/hotspot/src/share/vm/opto/macro.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/macro.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -320,9 +320,9 @@
 
 // Search the last value stored into the object's field.
 Node *PhaseMacroExpand::value_from_mem(Node *sfpt_mem, BasicType ft, const Type *ftype, const TypeOopPtr *adr_t, Node *alloc) {
-  assert(adr_t->is_instance_field(), "instance required");
-  uint instance_id = adr_t->instance_id();
-  assert(instance_id == alloc->_idx, "wrong allocation");
+  assert(adr_t->is_known_instance_field(), "instance required");
+  int instance_id = adr_t->instance_id();
+  assert((uint)instance_id == alloc->_idx, "wrong allocation");
 
   int alias_idx = C->get_alias_index(adr_t);
   int offset = adr_t->offset();
@@ -354,7 +354,7 @@
       const TypeOopPtr* atype = mem->as_Store()->adr_type()->isa_oopptr();
       assert(atype != NULL, "address type must be oopptr");
       assert(C->get_alias_index(atype) == alias_idx &&
-             atype->is_instance_field() && atype->offset() == offset &&
+             atype->is_known_instance_field() && atype->offset() == offset &&
              atype->instance_id() == instance_id, "store is correct memory slice");
       done = true;
     } else if (mem->is_Phi()) {
@@ -598,7 +598,7 @@
           field_type = TypeOopPtr::make_from_klass(elem_type->as_klass());
         }
         if (UseCompressedOops) {
-          field_type = field_type->is_oopptr()->make_narrowoop();
+          field_type = field_type->make_narrowoop();
           basic_elem_type = T_NARROWOOP;
         }
       } else {
@@ -666,9 +666,11 @@
       if (UseCompressedOops && field_type->isa_narrowoop()) {
         // Enable "DecodeN(EncodeP(Allocate)) --> Allocate" transformation
         // to be able scalar replace the allocation.
-        _igvn.set_delay_transform(false);
-        field_val = DecodeNNode::decode(&_igvn, field_val);
-        _igvn.set_delay_transform(true);
+        if (field_val->is_EncodeP()) {
+          field_val = field_val->in(1);
+        } else {
+          field_val = transform_later(new (C, 2) DecodeNNode(field_val, field_val->bottom_type()->make_ptr()));
+        }
       }
       sfpt->add_req(field_val);
     }
@@ -1674,7 +1676,14 @@
         success = eliminate_locking_node(n->as_AbstractLock());
         break;
       default:
-        assert(false, "unknown node type in macro list");
+        if (n->Opcode() == Op_Opaque1 || n->Opcode() == Op_Opaque2) {
+          _igvn.add_users_to_worklist(n);
+          _igvn.hash_delete(n);
+          _igvn.subsume_node(n, n->in(1));
+          success = true;
+        } else {
+          assert(false, "unknown node type in macro list");
+        }
       }
       assert(success == (C->macro_count() < old_macro_count), "elimination reduces macro count");
       progress = progress || success;
--- a/hotspot/src/share/vm/opto/matcher.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/matcher.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -51,6 +51,7 @@
   PhaseTransform( Phase::Ins_Select ),
 #ifdef ASSERT
   _old2new_map(C->comp_arena()),
+  _new2old_map(C->comp_arena()),
 #endif
   _shared_nodes(C->comp_arena()),
   _reduceOp(reduceOp), _leftOp(leftOp), _rightOp(rightOp),
@@ -82,6 +83,7 @@
   idealreg2debugmask[Op_RegF] = NULL;
   idealreg2debugmask[Op_RegD] = NULL;
   idealreg2debugmask[Op_RegP] = NULL;
+  debug_only(_mem_node = NULL;)   // Ideal memory node consumed by mach node
 }
 
 //------------------------------warp_incoming_stk_arg------------------------
@@ -834,10 +836,16 @@
             if( n->is_Proj() && n->in(0)->is_Multi()) {       // Projections?
               // Convert to machine-dependent projection
               m = n->in(0)->as_Multi()->match( n->as_Proj(), this );
+#ifdef ASSERT
+              _new2old_map.map(m->_idx, n);
+#endif
               if (m->in(0) != NULL) // m might be top
                 collect_null_checks(m);
             } else {                // Else just a regular 'ol guy
               m = n->clone();       // So just clone into new-space
+#ifdef ASSERT
+              _new2old_map.map(m->_idx, n);
+#endif
               // Def-Use edges will be added incrementally as Uses
               // of this node are matched.
               assert(m->outcnt() == 0, "no Uses of this clone yet");
@@ -886,6 +894,9 @@
             // || op == Op_BoxLock  // %%%% enable this and remove (+++) in chaitin.cpp
             ) {
           m = m->clone();
+#ifdef ASSERT
+          _new2old_map.map(m->_idx, n);
+#endif
           mstack.push(m, Post_Visit, n, i); // Don't neet to visit
           mstack.push(m->in(0), Visit, m, 0);
         } else {
@@ -1153,7 +1164,10 @@
 
   // StoreNodes require their Memory input to match any LoadNodes
   Node *mem = n->is_Store() ? n->in(MemNode::Memory) : (Node*)1 ;
-
+#ifdef ASSERT
+  Node* save_mem_node = _mem_node;
+  _mem_node = n->is_Store() ? (Node*)n : NULL;
+#endif
   // State object for root node of match tree
   // Allocate it on _states_arena - stack allocation can cause stack overflow.
   State *s = new (&_states_arena) State;
@@ -1186,6 +1200,7 @@
   MachNode *m = ReduceInst( s, s->_rule[mincost], mem );
 #ifdef ASSERT
   _old2new_map.map(n->_idx, m);
+  _new2old_map.map(m->_idx, (Node*)n);
 #endif
 
   // Add any Matcher-ignored edges
@@ -1205,6 +1220,7 @@
     }
   }
 
+  debug_only( _mem_node = save_mem_node; )
   return m;
 }
 
@@ -1445,8 +1461,30 @@
   }
 
   // If a Memory was used, insert a Memory edge
-  if( mem != (Node*)1 )
+  if( mem != (Node*)1 ) {
     mach->ins_req(MemNode::Memory,mem);
+#ifdef ASSERT
+    // Verify adr type after matching memory operation
+    const MachOper* oper = mach->memory_operand();
+    if (oper != NULL && oper != (MachOper*)-1 &&
+        mach->adr_type() != TypeRawPtr::BOTTOM) { // non-direct addressing mode
+      // It has a unique memory operand.  Find corresponding ideal mem node.
+      Node* m = NULL;
+      if (leaf->is_Mem()) {
+        m = leaf;
+      } else {
+        m = _mem_node;
+        assert(m != NULL && m->is_Mem(), "expecting memory node");
+      }
+      if (m->adr_type() != mach->adr_type()) {
+        m->dump();
+        tty->print_cr("mach:");
+        mach->dump(1);
+      }
+      assert(m->adr_type() == mach->adr_type(), "matcher should not change adr type");
+    }
+#endif
+  }
 
   // If the _leaf is an AddP, insert the base edge
   if( leaf->is_AddP() )
@@ -1464,6 +1502,9 @@
     for( uint i=0; i<mach->req(); i++ ) {
       mach->set_req(i,NULL);
     }
+#ifdef ASSERT
+    _new2old_map.map(ex->_idx, s->_leaf);
+#endif
   }
 
   // PhaseChaitin::fixup_spills will sometimes generate spill code
@@ -1510,7 +1551,9 @@
     assert( newrule >= _LAST_MACH_OPER, "Do NOT chain from internal operand");
     mach->_opnds[1] = s->MachOperGenerator( _reduceOp[catch_op], C );
     Node *mem1 = (Node*)1;
+    debug_only(Node *save_mem_node = _mem_node;)
     mach->add_req( ReduceInst(s, newrule, mem1) );
+    debug_only(_mem_node = save_mem_node;)
   }
   return;
 }
@@ -1520,6 +1563,7 @@
   if( s->_leaf->is_Load() ) {
     Node *mem2 = s->_leaf->in(MemNode::Memory);
     assert( mem == (Node*)1 || mem == mem2, "multiple Memories being matched at once?" );
+    debug_only( if( mem == (Node*)1 ) _mem_node = s->_leaf;)
     mem = mem2;
   }
   if( s->_leaf->in(0) != NULL && s->_leaf->req() > 1) {
@@ -1563,7 +1607,9 @@
         //             --> ReduceInst( newrule )
         mach->_opnds[num_opnds++] = s->MachOperGenerator( _reduceOp[catch_op], C );
         Node *mem1 = (Node*)1;
+        debug_only(Node *save_mem_node = _mem_node;)
         mach->add_req( ReduceInst( newstate, newrule, mem1 ) );
+        debug_only(_mem_node = save_mem_node;)
       }
     }
     assert( mach->_opnds[num_opnds-1], "" );
@@ -1594,6 +1640,7 @@
   if( s->_leaf->is_Load() ) {
     assert( mem == (Node*)1, "multiple Memories being matched at once?" );
     mem = s->_leaf->in(MemNode::Memory);
+    debug_only(_mem_node = s->_leaf;)
   }
   if( s->_leaf->in(0) && s->_leaf->req() > 1) {
     if( !mach->in(0) )
@@ -1618,7 +1665,9 @@
       // Reduce the instruction, and add a direct pointer from this
       // machine instruction to the newly reduced one.
       Node *mem1 = (Node*)1;
+      debug_only(Node *save_mem_node = _mem_node;)
       mach->add_req( ReduceInst( kid, newrule, mem1 ) );
+      debug_only(_mem_node = save_mem_node;)
     }
   }
 }
@@ -1731,8 +1780,8 @@
       }
       case Op_ConN: {  // Convert narrow pointers above the centerline to NUL
         TypeNode *tn = n->as_Type(); // Constants derive from type nodes
-        const TypePtr* tp = tn->type()->is_narrowoop()->make_oopptr();
-        if (tp->_ptr == TypePtr::AnyNull) {
+        const TypePtr* tp = tn->type()->make_ptr();
+        if (tp && tp->_ptr == TypePtr::AnyNull) {
           tn->set_type(TypeNarrowOop::NULL_PTR);
         }
         break;
--- a/hotspot/src/share/vm/opto/matcher.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/matcher.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -84,6 +84,7 @@
   Node_Array _shared_nodes;
 
   debug_only(Node_Array _old2new_map;)   // Map roots of ideal-trees to machine-roots
+  debug_only(Node_Array _new2old_map;)   // Maps machine nodes back to ideal
 
   // Accessors for the inherited field PhaseTransform::_nodes:
   void   grow_new_node_array(uint idx_limit) {
@@ -104,6 +105,8 @@
 #ifdef ASSERT
   // Make sure only new nodes are reachable from this node
   void verify_new_nodes_only(Node* root);
+
+  Node* _mem_node;   // Ideal memory node consumed by mach node
 #endif
 
 public:
@@ -388,5 +391,9 @@
 
 #ifdef ASSERT
   void dump_old2new_map();      // machine-independent to machine-dependent
+
+  Node* find_old_node(Node* new_node) {
+    return _new2old_map[new_node->_idx];
+  }
 #endif
 };
--- a/hotspot/src/share/vm/opto/memnode.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/memnode.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -91,7 +91,7 @@
 
 Node *MemNode::optimize_simple_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) {
   const TypeOopPtr *tinst = t_adr->isa_oopptr();
-  if (tinst == NULL || !tinst->is_instance_field())
+  if (tinst == NULL || !tinst->is_known_instance_field())
     return mchain;  // don't try to optimize non-instance types
   uint instance_id = tinst->instance_id();
   Node *prev = NULL;
@@ -125,7 +125,7 @@
 
 Node *MemNode::optimize_memory_chain(Node *mchain, const TypePtr *t_adr, PhaseGVN *phase) {
   const TypeOopPtr *t_oop = t_adr->isa_oopptr();
-  bool is_instance = (t_oop != NULL) && t_oop->is_instance_field();
+  bool is_instance = (t_oop != NULL) && t_oop->is_known_instance_field();
   PhaseIterGVN *igvn = phase->is_IterGVN();
   Node *result = mchain;
   result = optimize_simple_memory_chain(result, t_adr, phase);
@@ -134,8 +134,8 @@
     assert(mphi->bottom_type() == Type::MEMORY, "memory phi required");
     const TypePtr *t = mphi->adr_type();
     if (t == TypePtr::BOTTOM || t == TypeRawPtr::BOTTOM ||
-        t->isa_oopptr() && !t->is_oopptr()->is_instance() &&
-        t->is_oopptr()->cast_to_instance(t_oop->instance_id()) == t_oop) {
+        t->isa_oopptr() && !t->is_oopptr()->is_known_instance() &&
+        t->is_oopptr()->cast_to_instance_id(t_oop->instance_id()) == t_oop) {
       // clone the Phi with our address type
       result = mphi->split_out_instance(t_adr, igvn);
     } else {
@@ -470,7 +470,7 @@
         return mem;         // let caller handle steps (c), (d)
       }
 
-    } else if (addr_t != NULL && addr_t->is_instance_field()) {
+    } else if (addr_t != NULL && addr_t->is_known_instance_field()) {
       // Can't use optimize_simple_memory_chain() since it needs PhaseGVN.
       if (mem->is_Proj() && mem->in(0)->is_Call()) {
         CallNode *call = mem->in(0)->as_Call();
@@ -769,15 +769,8 @@
   case T_OBJECT:
 #ifdef _LP64
     if (adr->bottom_type()->is_ptr_to_narrowoop()) {
-      const TypeNarrowOop* narrowtype;
-      if (rt->isa_narrowoop()) {
-        narrowtype = rt->is_narrowoop();
-      } else {
-        narrowtype = rt->is_oopptr()->make_narrowoop();
-      }
-      Node* load  = gvn.transform(new (C, 3) LoadNNode(ctl, mem, adr, adr_type, narrowtype));
-
-      return DecodeNNode::decode(&gvn, load);
+      Node* load  = gvn.transform(new (C, 3) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop()));
+      return new (C, 2) DecodeNNode(load, load->bottom_type()->make_ptr());
     } else
 #endif
     {
@@ -923,7 +916,7 @@
       in(MemNode::Address)->is_AddP() ) {
     const TypeOopPtr* t_oop = in(MemNode::Address)->bottom_type()->isa_oopptr();
     // Only instances.
-    if( t_oop != NULL && t_oop->is_instance_field() &&
+    if( t_oop != NULL && t_oop->is_known_instance_field() &&
         t_oop->offset() != Type::OffsetBot &&
         t_oop->offset() != Type::OffsetTop) {
       return true;
@@ -1146,7 +1139,7 @@
   const TypeOopPtr *t_oop = addr_t->isa_oopptr();
 
   assert(mem->is_Phi() && (t_oop != NULL) &&
-         t_oop->is_instance_field(), "invalide conditions");
+         t_oop->is_known_instance_field(), "invalide conditions");
 
   Node *region = mem->in(0);
   if (region == NULL) {
@@ -1314,7 +1307,7 @@
     }
     const TypeOopPtr *t_oop = addr_t->isa_oopptr();
     if (can_reshape && opt_mem->is_Phi() &&
-        (t_oop != NULL) && t_oop->is_instance_field()) {
+        (t_oop != NULL) && t_oop->is_known_instance_field()) {
       // Split instance field load through Phi.
       Node* result = split_through_phi(phase);
       if (result != NULL) return result;
@@ -1549,7 +1542,7 @@
   }
 
   const TypeOopPtr *tinst = tp->isa_oopptr();
-  if (tinst != NULL && tinst->is_instance_field()) {
+  if (tinst != NULL && tinst->is_known_instance_field()) {
     // If we have an instance type and our memory input is the
     // programs's initial memory state, there is no matching store,
     // so just return a zero of the appropriate type
@@ -1631,9 +1624,8 @@
   assert(adr_type != NULL, "expecting TypeOopPtr");
 #ifdef _LP64
   if (adr_type->is_ptr_to_narrowoop()) {
-    const TypeNarrowOop* narrowtype = tk->is_oopptr()->make_narrowoop();
-    Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, narrowtype));
-    return DecodeNNode::decode(&gvn, load_klass);
+    Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowoop()));
+    return new (C, 2) DecodeNNode(load_klass, load_klass->bottom_type()->make_ptr());
   }
 #endif
   assert(!adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop");
@@ -1843,15 +1835,10 @@
 //------------------------------Value------------------------------------------
 const Type *LoadNKlassNode::Value( PhaseTransform *phase ) const {
   const Type *t = klass_value_common(phase);
-
-  if (t == TypePtr::NULL_PTR) {
-    return TypeNarrowOop::NULL_PTR;
-  }
-  if (t != Type::TOP && !t->isa_narrowoop()) {
-    assert(t->is_oopptr(), "sanity");
-    t = t->is_oopptr()->make_narrowoop();
-  }
-  return t;
+  if (t == Type::TOP)
+    return t;
+
+  return t->make_narrowoop();
 }
 
 //------------------------------Identity---------------------------------------
@@ -1864,7 +1851,7 @@
   if( t == Type::TOP ) return x;
   if( t->isa_narrowoop()) return x;
 
-  return EncodePNode::encode(phase, x);
+  return phase->transform(new (phase->C, 2) EncodePNode(x, t->make_narrowoop()));
 }
 
 //------------------------------Value-----------------------------------------
@@ -1930,14 +1917,13 @@
     if (adr->bottom_type()->is_ptr_to_narrowoop() ||
         (UseCompressedOops && val->bottom_type()->isa_klassptr() &&
          adr->bottom_type()->isa_rawptr())) {
-      const TypePtr* type = val->bottom_type()->is_ptr();
-      Node* cp = EncodePNode::encode(&gvn, val);
-      return new (C, 4) StoreNNode(ctl, mem, adr, adr_type, cp);
+      val = gvn.transform(new (C, 2) EncodePNode(val, val->bottom_type()->make_narrowoop()));
+      return new (C, 4) StoreNNode(ctl, mem, adr, adr_type, val);
     } else
 #endif
-      {
-        return new (C, 4) StorePNode(ctl, mem, adr, adr_type, val);
-      }
+    {
+      return new (C, 4) StorePNode(ctl, mem, adr, adr_type, val);
+    }
   }
   ShouldNotReachHere();
   return (StoreNode*)NULL;
@@ -2151,7 +2137,7 @@
   const TypeOopPtr *adr_oop = phase->type(adr)->isa_oopptr();
   if (adr_oop == NULL)
     return false;
-  if (!adr_oop->is_instance_field())
+  if (!adr_oop->is_known_instance_field())
     return false; // if not a distinct instance, there may be aliases of the address
   for (DUIterator_Fast imax, i = adr->fast_outs(imax); i < imax; i++) {
     Node *use = adr->fast_out(i);
--- a/hotspot/src/share/vm/opto/node.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/node.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -1387,7 +1387,7 @@
   }
 #ifdef ASSERT
   // Search along debug_orig edges last:
-  for (Node* orig = n->debug_orig(); orig != NULL; orig = orig->debug_orig()) {
+  for (Node* orig = n->debug_orig(); orig != NULL && n != orig; orig = orig->debug_orig()) {
     if (NotANode(orig))  break;
     find_recur( result, orig, idx, only_ctrl, old_space, new_space );
   }
--- a/hotspot/src/share/vm/opto/output.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/output.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -447,6 +447,7 @@
             // We've got a winner.  Replace this branch.
             MachNode *replacement = mach->short_branch_version(this);
             b->_nodes.map(j, replacement);
+            mach->subsume_by(replacement);
 
             // Update the jmp_end size to save time in our
             // next pass.
--- a/hotspot/src/share/vm/opto/parse2.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/parse2.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -67,12 +67,9 @@
   const Type*       elemtype = arytype->elem();
 
   if (UseUniqueSubclasses && result2 != NULL) {
-    const Type* el = elemtype;
-    if (elemtype->isa_narrowoop()) {
-      el = elemtype->is_narrowoop()->make_oopptr();
-    }
-    const TypeInstPtr* toop = el->isa_instptr();
-    if (toop) {
+    const Type* el = elemtype->make_ptr();
+    if (el && el->isa_instptr()) {
+      const TypeInstPtr* toop = el->is_instptr();
       if (toop->klass()->as_instance_klass()->unique_concrete_subklass()) {
         // If we load from "AbstractClass[]" we must see "ConcreteSubClass".
         const Type* subklass = Type::get_const_type(toop->klass());
@@ -2223,7 +2220,7 @@
     sprintf(buffer, "Bytecode %d: %s", bci(), Bytecodes::name(bc()));
     bool old = printer->traverse_outs();
     printer->set_traverse_outs(true);
-    printer->print_method(C, buffer, 3);
+    printer->print_method(C, buffer, 4);
     printer->set_traverse_outs(old);
   }
 #endif
--- a/hotspot/src/share/vm/opto/subnode.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/subnode.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -45,10 +45,13 @@
     return in(2)->in(2);
   }
 
-  // Convert "(X+Y) - Y" into X
+  // Convert "(X+Y) - Y" into X and "(X+Y) - X" into Y
   if( in(1)->Opcode() == Op_AddI ) {
     if( phase->eqv(in(1)->in(2),in(2)) )
       return in(1)->in(1);
+    if (phase->eqv(in(1)->in(1),in(2)))
+      return in(1)->in(2);
+
     // Also catch: "(X + Opaque2(Y)) - Y".  In this case, 'Y' is a loop-varying
     // trip counter and X is likely to be loop-invariant (that's how O2 Nodes
     // are originally used, although the optimizer sometimes jiggers things).
@@ -740,8 +743,8 @@
 // Simplify an CmpN (compare 2 pointers) node, based on local information.
 // If both inputs are constants, compare them.
 const Type *CmpNNode::sub( const Type *t1, const Type *t2 ) const {
-  const TypePtr *r0 = t1->is_narrowoop()->make_oopptr(); // Handy access
-  const TypePtr *r1 = t2->is_narrowoop()->make_oopptr();
+  const TypePtr *r0 = t1->make_ptr(); // Handy access
+  const TypePtr *r1 = t2->make_ptr();
 
   // Undefined inputs makes for an undefined result
   if( TypePtr::above_centerline(r0->_ptr) ||
--- a/hotspot/src/share/vm/opto/superword.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/superword.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -1424,9 +1424,9 @@
 //---------------------------container_type---------------------------
 // Smallest type containing range of values
 const Type* SuperWord::container_type(const Type* t) {
-  if (t->isa_narrowoop()) t = t->is_narrowoop()->make_oopptr();
-  if (t->isa_aryptr()) {
-    t = t->is_aryptr()->elem();
+  const Type* tp = t->make_ptr();
+  if (tp && tp->isa_aryptr()) {
+    t = tp->is_aryptr()->elem();
   }
   if (t->basic_type() == T_INT) {
     if (t->higher_equal(TypeInt::BOOL))  return TypeInt::BOOL;
--- a/hotspot/src/share/vm/opto/type.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/type.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -491,14 +491,8 @@
 // commutative and the lattice is symmetric.
 const Type *Type::meet( const Type *t ) const {
   if (isa_narrowoop() && t->isa_narrowoop()) {
-    const Type* result = is_narrowoop()->make_oopptr()->meet(t->is_narrowoop()->make_oopptr());
-    if (result->isa_oopptr()) {
-      return result->isa_oopptr()->make_narrowoop();
-    } else if (result == TypePtr::NULL_PTR) {
-      return TypeNarrowOop::NULL_PTR;
-    } else {
-      return result;
-    }
+    const Type* result = make_ptr()->meet(t->make_ptr());
+    return result->make_narrowoop();
   }
 
   const Type *mt = xmeet(t);
@@ -520,23 +514,8 @@
     bool    t_interface =    t_inst->klass()->is_interface();
     interface_vs_oop = this_interface ^ t_interface;
   }
-  const Type *tdual = t->_dual;
-  const Type *thisdual = _dual;
-  // strip out instances
-  if (t2t->isa_oopptr() != NULL) {
-    t2t = t2t->isa_oopptr()->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
-  }
-  if (t2this->isa_oopptr() != NULL) {
-    t2this = t2this->isa_oopptr()->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
-  }
-  if (tdual->isa_oopptr() != NULL) {
-    tdual = tdual->isa_oopptr()->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
-  }
-  if (thisdual->isa_oopptr() != NULL) {
-    thisdual = thisdual->isa_oopptr()->cast_to_instance(TypeOopPtr::UNKNOWN_INSTANCE);
-  }
-
-  if( !interface_vs_oop && (t2t != tdual || t2this != thisdual) ) {
+
+  if( !interface_vs_oop && (t2t != t->_dual || t2this != _dual) ) {
     tty->print_cr("=== Meet Not Symmetric ===");
     tty->print("t   =                   ");         t->dump(); tty->cr();
     tty->print("this=                   ");            dump(); tty->cr();
@@ -1764,7 +1743,7 @@
 //------------------------------make-------------------------------------------
 const TypeAry *TypeAry::make( const Type *elem, const TypeInt *size) {
   if (UseCompressedOops && elem->isa_oopptr()) {
-    elem = elem->is_oopptr()->make_narrowoop();
+    elem = elem->make_narrowoop();
   }
   size = normalize_array_size(size);
   return (TypeAry*)(new TypeAry(elem,size))->hashcons();
@@ -1849,9 +1828,8 @@
   if (_elem == BOTTOM)      return false;  // general array not exact
   if (_elem == TOP   )      return false;  // inverted general array not exact
   const TypeOopPtr*  toop = NULL;
-  if (UseCompressedOops) {
-    const TypeNarrowOop* noop = _elem->isa_narrowoop();
-    if (noop) toop = noop->make_oopptr()->isa_oopptr();
+  if (UseCompressedOops && _elem->isa_narrowoop()) {
+    toop = _elem->make_ptr()->isa_oopptr();
   } else {
     toop = _elem->isa_oopptr();
   }
@@ -1861,16 +1839,18 @@
   if (!tklass->is_loaded()) return false;  // unloaded class
   const TypeInstPtr* tinst;
   if (_elem->isa_narrowoop())
-    tinst = _elem->is_narrowoop()->make_oopptr()->isa_instptr();
+    tinst = _elem->make_ptr()->isa_instptr();
   else
     tinst = _elem->isa_instptr();
-  if (tinst)                return tklass->as_instance_klass()->is_final();
+  if (tinst)
+    return tklass->as_instance_klass()->is_final();
   const TypeAryPtr*  tap;
   if (_elem->isa_narrowoop())
-    tap = _elem->is_narrowoop()->make_oopptr()->isa_aryptr();
+    tap = _elem->make_ptr()->isa_aryptr();
   else
     tap = _elem->isa_aryptr();
-  if (tap)                  return tap->ary()->ary_must_be_exact();
+  if (tap)
+    return tap->ary()->ary_must_be_exact();
   return false;
 }
 
@@ -2227,7 +2207,7 @@
   ciKlass*  k = ciKlassKlass::make();
   bool      xk = false;
   ciObject* o = NULL;
-  return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, UNKNOWN_INSTANCE))->hashcons();
+  return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, InstanceBot))->hashcons();
 }
 
 
@@ -2239,7 +2219,7 @@
 }
 
 //-----------------------------cast_to_instance-------------------------------
-const TypeOopPtr *TypeOopPtr::cast_to_instance(int instance_id) const {
+const TypeOopPtr *TypeOopPtr::cast_to_instance_id(int instance_id) const {
   // There are no instances of a general oop.
   // Return self unchanged.
   return this;
@@ -2333,7 +2313,7 @@
 const Type *TypeOopPtr::xdual() const {
   assert(klass() == ciKlassKlass::make(), "no klasses here");
   assert(const_oop() == NULL,             "no constants here");
-  return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance()  );
+  return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id()  );
 }
 
 //--------------------------make_from_klass_common-----------------------------
@@ -2547,7 +2527,9 @@
   case         0: break;
   default:        st->print("+%d",_offset); break;
   }
-  if (_instance_id != UNKNOWN_INSTANCE)
+  if (_instance_id == InstanceTop)
+    st->print(",iid=top");
+  else if (_instance_id != InstanceBot)
     st->print(",iid=%d",_instance_id);
 }
 #endif
@@ -2579,20 +2561,24 @@
   return make( _ptr, xadd_offset(offset) );
 }
 
-const TypeNarrowOop* TypeOopPtr::make_narrowoop() const {
-  return TypeNarrowOop::make(this);
+//------------------------------meet_instance_id--------------------------------
+int TypeOopPtr::meet_instance_id( int instance_id ) const {
+  // Either is 'TOP' instance?  Return the other instance!
+  if( _instance_id == InstanceTop ) return  instance_id;
+  if(  instance_id == InstanceTop ) return _instance_id;
+  // If either is different, return 'BOTTOM' instance
+  if( _instance_id != instance_id ) return InstanceBot;
+  return _instance_id;
 }
 
-int TypeOopPtr::meet_instance(int iid) const {
-  if (iid == 0) {
-    return (_instance_id < 0)  ? _instance_id : UNKNOWN_INSTANCE;
-  } else if (_instance_id == UNKNOWN_INSTANCE) {
-    return (iid < 0)  ? iid : UNKNOWN_INSTANCE;
-  } else {
-    return (_instance_id == iid) ? iid : UNKNOWN_INSTANCE;
-  }
+//------------------------------dual_instance_id--------------------------------
+int TypeOopPtr::dual_instance_id( ) const {
+  if( _instance_id == InstanceTop ) return InstanceBot; // Map TOP into BOTTOM
+  if( _instance_id == InstanceBot ) return InstanceTop; // Map BOTTOM into TOP
+  return _instance_id;              // Map everything else into self
 }
 
+
 //=============================================================================
 // Convenience common pre-built types.
 const TypeInstPtr *TypeInstPtr::NOTNULL;
@@ -2624,7 +2610,7 @@
   // Ptr is never Null
   assert( ptr != Null, "NULL pointers are not typed" );
 
-  if (instance_id != UNKNOWN_INSTANCE)
+  if ( instance_id > 0 )
     xk = true;  // instances are always exactly typed
   if (!UseExactTypes)  xk = false;
   if (ptr == Constant) {
@@ -2649,7 +2635,7 @@
   if( ptr == _ptr ) return this;
   // Reconstruct _sig info here since not a problem with later lazy
   // construction, _sig will show up on demand.
-  return make(ptr, klass(), klass_is_exact(), const_oop(), _offset);
+  return make(ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id);
 }
 
 
@@ -2665,13 +2651,13 @@
 }
 
 //-----------------------------cast_to_instance-------------------------------
-const TypeOopPtr *TypeInstPtr::cast_to_instance(int instance_id) const {
-  if( instance_id == _instance_id) return this;
-  bool exact = true;
-  PTR  ptr_t = NotNull;
-  if (instance_id == UNKNOWN_INSTANCE) {
-    exact = _klass_is_exact;
-    ptr_t = _ptr;
+const TypeOopPtr *TypeInstPtr::cast_to_instance_id(int instance_id) const {
+  if( instance_id == _instance_id ) return this;
+  bool exact = _klass_is_exact;
+  PTR  ptr_t = _ptr;
+  if ( instance_id > 0 ) { // instances are always exactly typed
+    if (UseExactTypes) exact = true;
+    ptr_t = NotNull;
   }
   return make(ptr_t, klass(), exact, const_oop(), _offset, instance_id);
 }
@@ -2754,16 +2740,17 @@
     const TypeAryPtr *tp = t->is_aryptr();
     int offset = meet_offset(tp->offset());
     PTR ptr = meet_ptr(tp->ptr());
-    int iid = meet_instance(tp->instance_id());
+    int instance_id = meet_instance_id(tp->instance_id());
     switch (ptr) {
     case TopPTR:
     case AnyNull:                // Fall 'down' to dual of object klass
       if (klass()->equals(ciEnv::current()->Object_klass())) {
-        return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, iid);
+        return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id);
       } else {
         // cannot subclass, so the meet has to fall badly below the centerline
         ptr = NotNull;
-        return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, iid);
+        instance_id = InstanceBot;
+        return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id);
       }
     case Constant:
     case NotNull:
@@ -2774,14 +2761,15 @@
         // then we can subclass in the Java class heirarchy.
         if (klass()->equals(ciEnv::current()->Object_klass())) {
           // that is, tp's array type is a subtype of my klass
-          return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, iid);
+          return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id);
         }
       }
       // The other case cannot happen, since I cannot be a subtype of an array.
       // The meet falls down to Object class below centerline.
       if( ptr == Constant )
          ptr = NotNull;
-      return make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, iid );
+      instance_id = InstanceBot;
+      return make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id );
     default: typerr(t);
     }
   }
@@ -2793,9 +2781,11 @@
     PTR ptr = meet_ptr(tp->ptr());
     switch (tp->ptr()) {
     case TopPTR:
-    case AnyNull:
+    case AnyNull: {
+      int instance_id = meet_instance_id(InstanceTop);
       return make(ptr, klass(), klass_is_exact(),
-                  (ptr == Constant ? const_oop() : NULL), offset);
+                  (ptr == Constant ? const_oop() : NULL), offset, instance_id);
+    }
     case NotNull:
     case BotPTR:
       return TypeOopPtr::make(ptr, offset);
@@ -2811,10 +2801,13 @@
     switch (tp->ptr()) {
     case Null:
       if( ptr == Null ) return TypePtr::make( AnyPtr, ptr, offset );
+      // else fall through to AnyNull
     case TopPTR:
-    case AnyNull:
+    case AnyNull: {
+      int instance_id = meet_instance_id(InstanceTop);
       return make( ptr, klass(), klass_is_exact(),
-                   (ptr == Constant ? const_oop() : NULL), offset );
+                   (ptr == Constant ? const_oop() : NULL), offset, instance_id);
+    }
     case NotNull:
     case BotPTR:
       return TypePtr::make( AnyPtr, ptr, offset );
@@ -2843,7 +2836,7 @@
     const TypeInstPtr *tinst = t->is_instptr();
     int off = meet_offset( tinst->offset() );
     PTR ptr = meet_ptr( tinst->ptr() );
-    int instance_id = meet_instance(tinst->instance_id());
+    int instance_id = meet_instance_id(tinst->instance_id());
 
     // Check for easy case; klasses are equal (and perhaps not loaded!)
     // If we have constants, then we created oops so classes are loaded
@@ -2912,7 +2905,7 @@
         // Find out which constant.
         o = (this_klass == klass()) ? const_oop() : tinst->const_oop();
       }
-      return make( ptr, k, xk, o, off );
+      return make( ptr, k, xk, o, off, instance_id );
     }
 
     // Either oop vs oop or interface vs interface or interface vs Object
@@ -2999,7 +2992,7 @@
 
     // Now we find the LCA of Java classes
     ciKlass* k = this_klass->least_common_ancestor(tinst_klass);
-    return make( ptr, k, false, NULL, off );
+    return make( ptr, k, false, NULL, off, instance_id );
   } // End of case InstPtr
 
   case KlassPtr:
@@ -3026,7 +3019,7 @@
 // Dual: do NOT dual on klasses.  This means I do NOT understand the Java
 // inheritence mechanism.
 const Type *TypeInstPtr::xdual() const {
-  return new TypeInstPtr( dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance()  );
+  return new TypeInstPtr( dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id()  );
 }
 
 //------------------------------eq---------------------------------------------
@@ -3078,7 +3071,9 @@
   }
 
   st->print(" *");
-  if (_instance_id != UNKNOWN_INSTANCE)
+  if (_instance_id == InstanceTop)
+    st->print(",iid=top");
+  else if (_instance_id != InstanceBot)
     st->print(",iid=%d",_instance_id);
 }
 #endif
@@ -3106,7 +3101,7 @@
   assert(!(k == NULL && ary->_elem->isa_int()),
          "integral arrays must be pre-equipped with a class");
   if (!xk)  xk = ary->ary_must_be_exact();
-  if (instance_id != UNKNOWN_INSTANCE)
+  if ( instance_id > 0 )
     xk = true;  // instances are always exactly typed
   if (!UseExactTypes)  xk = (ptr == Constant);
   return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id))->hashcons();
@@ -3118,7 +3113,7 @@
          "integral arrays must be pre-equipped with a class");
   assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" );
   if (!xk)  xk = (o != NULL) || ary->ary_must_be_exact();
-  if (instance_id != UNKNOWN_INSTANCE)
+  if ( instance_id > 0 )
     xk = true;  // instances are always exactly typed
   if (!UseExactTypes)  xk = (ptr == Constant);
   return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id))->hashcons();
@@ -3127,7 +3122,7 @@
 //------------------------------cast_to_ptr_type-------------------------------
 const Type *TypeAryPtr::cast_to_ptr_type(PTR ptr) const {
   if( ptr == _ptr ) return this;
-  return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset);
+  return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset, _instance_id);
 }
 
 
@@ -3140,13 +3135,13 @@
 }
 
 //-----------------------------cast_to_instance-------------------------------
-const TypeOopPtr *TypeAryPtr::cast_to_instance(int instance_id) const {
-  if( instance_id == _instance_id) return this;
-  bool exact = true;
-  PTR  ptr_t = NotNull;
-  if (instance_id == UNKNOWN_INSTANCE) {
-    exact = _klass_is_exact;
-    ptr_t = _ptr;
+const TypeOopPtr *TypeAryPtr::cast_to_instance_id(int instance_id) const {
+  if( instance_id == _instance_id ) return this;
+  bool exact = _klass_is_exact;
+  PTR  ptr_t = _ptr;
+  if ( instance_id > 0 ) { // instances are always exactly typed
+    if (UseExactTypes) exact = true;
+    ptr_t = NotNull;
   }
   return make(ptr_t, const_oop(), _ary, klass(), exact, _offset, instance_id);
 }
@@ -3199,7 +3194,7 @@
     new_size = TypeInt::ZERO; // intermediate dead fast-path goo
   if (new_size == size())  return this;
   const TypeAry* new_ary = TypeAry::make(elem(), new_size);
-  return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset);
+  return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id);
 }
 
 
@@ -3251,8 +3246,11 @@
     PTR ptr = meet_ptr(tp->ptr());
     switch (tp->ptr()) {
     case TopPTR:
-    case AnyNull:
-      return make(ptr, (ptr == Constant ? const_oop() : NULL), _ary, _klass, _klass_is_exact, offset);
+    case AnyNull: {
+      int instance_id = meet_instance_id(InstanceTop);
+      return make(ptr, (ptr == Constant ? const_oop() : NULL),
+                  _ary, _klass, _klass_is_exact, offset, instance_id);
+    }
     case BotPTR:
     case NotNull:
       return TypeOopPtr::make(ptr, offset);
@@ -3273,8 +3271,12 @@
       return TypePtr::make(AnyPtr, ptr, offset);
     case Null:
       if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset);
-    case AnyNull:
-      return make( ptr, (ptr == Constant ? const_oop() : NULL), _ary, _klass, _klass_is_exact, offset );
+      // else fall through to AnyNull
+    case AnyNull: {
+      int instance_id = meet_instance_id(InstanceTop);
+      return make( ptr, (ptr == Constant ? const_oop() : NULL),
+                  _ary, _klass, _klass_is_exact, offset, instance_id);
+    }
     default: ShouldNotReachHere();
     }
   }
@@ -3286,7 +3288,7 @@
     int off = meet_offset(tap->offset());
     const TypeAry *tary = _ary->meet(tap->_ary)->is_ary();
     PTR ptr = meet_ptr(tap->ptr());
-    int iid = meet_instance(tap->instance_id());
+    int instance_id = meet_instance_id(tap->instance_id());
     ciKlass* lazy_klass = NULL;
     if (tary->_elem->isa_int()) {
       // Integral array element types have irrelevant lattice relations.
@@ -3307,7 +3309,7 @@
     case TopPTR:
       // Compute new klass on demand, do not use tap->_klass
       xk = (tap->_klass_is_exact | this->_klass_is_exact);
-      return make( ptr, const_oop(), tary, lazy_klass, xk, off, iid );
+      return make( ptr, const_oop(), tary, lazy_klass, xk, off, instance_id );
     case Constant: {
       ciObject* o = const_oop();
       if( _ptr == Constant ) {
@@ -3319,7 +3321,7 @@
         o = tap->const_oop();
       }
       xk = true;
-      return TypeAryPtr::make( ptr, o, tary, tap->_klass, xk, off, iid );
+      return TypeAryPtr::make( ptr, o, tary, tap->_klass, xk, off, instance_id );
     }
     case NotNull:
     case BotPTR:
@@ -3330,7 +3332,7 @@
             xk = this->_klass_is_exact;
       else  xk = (tap->_klass_is_exact & this->_klass_is_exact) &&
               (klass() == tap->klass()); // Only precise for identical arrays
-      return TypeAryPtr::make( ptr, NULL, tary, lazy_klass, xk, off, iid );
+      return TypeAryPtr::make( ptr, NULL, tary, lazy_klass, xk, off, instance_id );
     default: ShouldNotReachHere();
     }
   }
@@ -3340,16 +3342,17 @@
     const TypeInstPtr *tp = t->is_instptr();
     int offset = meet_offset(tp->offset());
     PTR ptr = meet_ptr(tp->ptr());
-    int iid = meet_instance(tp->instance_id());
+    int instance_id = meet_instance_id(tp->instance_id());
     switch (ptr) {
     case TopPTR:
     case AnyNull:                // Fall 'down' to dual of object klass
       if( tp->klass()->equals(ciEnv::current()->Object_klass()) ) {
-        return TypeAryPtr::make( ptr, _ary, _klass, _klass_is_exact, offset, iid );
+        return TypeAryPtr::make( ptr, _ary, _klass, _klass_is_exact, offset, instance_id );
       } else {
         // cannot subclass, so the meet has to fall badly below the centerline
         ptr = NotNull;
-        return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, iid);
+        instance_id = InstanceBot;
+        return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id);
       }
     case Constant:
     case NotNull:
@@ -3360,14 +3363,15 @@
         // then we can subclass in the Java class heirarchy.
         if( tp->klass()->equals(ciEnv::current()->Object_klass()) ) {
           // that is, my array type is a subtype of 'tp' klass
-          return make( ptr, _ary, _klass, _klass_is_exact, offset, iid );
+          return make( ptr, _ary, _klass, _klass_is_exact, offset, instance_id );
         }
       }
       // The other case cannot happen, since t cannot be a subtype of an array.
       // The meet falls down to Object class below centerline.
       if( ptr == Constant )
          ptr = NotNull;
-      return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, iid);
+      instance_id = InstanceBot;
+      return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id);
     default: typerr(t);
     }
   }
@@ -3382,7 +3386,7 @@
 //------------------------------xdual------------------------------------------
 // Dual: compute field-by-field dual
 const Type *TypeAryPtr::xdual() const {
-  return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance() );
+  return new TypeAryPtr( dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id() );
 }
 
 //------------------------------dump2------------------------------------------
@@ -3419,7 +3423,9 @@
     }
   }
   st->print(" *");
-  if (_instance_id != UNKNOWN_INSTANCE)
+  if (_instance_id == InstanceTop)
+    st->print(",iid=top");
+  else if (_instance_id != InstanceBot)
     st->print(",iid=%d",_instance_id);
 }
 #endif
@@ -3494,7 +3500,7 @@
     return this;
 
   case NarrowOop: {
-    const Type* result = _ooptype->xmeet(t->is_narrowoop()->make_oopptr());
+    const Type* result = _ooptype->xmeet(t->make_ptr());
     if (result->isa_ptr()) {
       return TypeNarrowOop::make(result->is_ptr());
     }
@@ -3604,7 +3610,7 @@
   const TypeAryPtr *tary;
   const Type* el = elem();
   if (el->isa_narrowoop()) {
-    el = el->is_narrowoop()->make_oopptr();
+    el = el->make_ptr();
   }
 
   // Get element klass
--- a/hotspot/src/share/vm/opto/type.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/opto/type.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -225,6 +225,12 @@
   virtual bool      is_finite() const;           // Has a finite value
   virtual bool      is_nan()    const;           // Is not a number (NaN)
 
+  // Returns this ptr type or the equivalent ptr type for this compressed pointer.
+  const TypePtr* make_ptr() const;
+  // Returns this compressed pointer or the equivalent compressed version
+  // of this pointer type.
+  const TypeNarrowOop* make_narrowoop() const;
+
   // Special test for register pressure heuristic
   bool is_floatingpoint() const;        // True if Float or Double base type
 
@@ -648,7 +654,8 @@
   virtual int  hash() const;             // Type specific hashing
   virtual bool singleton(void) const;    // TRUE if type is a singleton
   enum {
-   UNKNOWN_INSTANCE = 0
+   InstanceTop = -1,   // undefined instance
+   InstanceBot = 0     // any possible instance
   };
 protected:
 
@@ -661,14 +668,15 @@
   bool          _klass_is_exact;
   bool          _is_ptr_to_narrowoop;
 
-  int           _instance_id;  // if not UNKNOWN_INSTANCE, indicates that this is a particular instance
-                               // of this type which is distinct.  This is the  the node index of the
-                               // node creating this instance
+  // If not InstanceTop or InstanceBot, indicates that this is
+  // a particular instance of this type which is distinct.
+  // This is the the node index of the allocation node creating this instance.
+  int           _instance_id;
 
   static const TypeOopPtr* make_from_klass_common(ciKlass* klass, bool klass_change, bool try_for_exact);
 
-  int dual_instance()      const { return -_instance_id; }
-  int meet_instance(int uid) const;
+  int dual_instance_id() const;
+  int meet_instance_id(int uid) const;
 
 public:
   // Creates a type given a klass. Correctly handles multi-dimensional arrays
@@ -701,9 +709,9 @@
   // compressed oop references.
   bool is_ptr_to_narrowoop_nv() const { return _is_ptr_to_narrowoop; }
 
-  bool is_instance()       const { return _instance_id != UNKNOWN_INSTANCE; }
-  uint instance_id()       const { return _instance_id; }
-  bool is_instance_field() const { return _instance_id != UNKNOWN_INSTANCE && _offset >= 0; }
+  bool is_known_instance()       const { return _instance_id > 0; }
+  int  instance_id()             const { return _instance_id; }
+  bool is_known_instance_field() const { return is_known_instance() && _offset >= 0; }
 
   virtual intptr_t get_con() const;
 
@@ -711,16 +719,13 @@
 
   virtual const Type *cast_to_exactness(bool klass_is_exact) const;
 
-  virtual const TypeOopPtr *cast_to_instance(int instance_id) const;
+  virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
 
   // corresponding pointer to klass, for a given instance
   const TypeKlassPtr* as_klass_type() const;
 
   virtual const TypePtr *add_offset( int offset ) const;
 
-  // returns the equivalent compressed version of this pointer type
-  virtual const TypeNarrowOop* make_narrowoop() const;
-
   virtual const Type *xmeet( const Type *t ) const;
   virtual const Type *xdual() const;    // Compute dual right now.
 
@@ -775,7 +780,7 @@
   }
 
   // Make a pointer to an oop.
-  static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = 0 );
+  static const TypeInstPtr *make(PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id = InstanceBot );
 
   // If this is a java.lang.Class constant, return the type for it or NULL.
   // Pass to Type::get_const_type to turn it to a type, which will usually
@@ -786,7 +791,7 @@
 
   virtual const Type *cast_to_exactness(bool klass_is_exact) const;
 
-  virtual const TypeOopPtr *cast_to_instance(int instance_id) const;
+  virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
 
   virtual const TypePtr *add_offset( int offset ) const;
 
@@ -820,9 +825,9 @@
   const Type*    elem() const { return _ary->_elem; }
   const TypeInt* size() const { return _ary->_size; }
 
-  static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = 0);
+  static const TypeAryPtr *make( PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
   // Constant pointer to array
-  static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = 0);
+  static const TypeAryPtr *make( PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id = InstanceBot);
 
   // Convenience
   static const TypeAryPtr *make(ciObject* o);
@@ -832,7 +837,7 @@
 
   virtual const Type *cast_to_exactness(bool klass_is_exact) const;
 
-  virtual const TypeOopPtr *cast_to_instance(int instance_id) const;
+  virtual const TypeOopPtr *cast_to_instance_id(int instance_id) const;
 
   virtual const TypeAryPtr* cast_to_size(const TypeInt* size) const;
 
@@ -911,7 +916,7 @@
 // between the normal and the compressed form.
 class TypeNarrowOop : public Type {
 protected:
-  const TypePtr* _ooptype;
+  const TypePtr* _ooptype; // Could be TypePtr::NULL_PTR
 
   TypeNarrowOop( const TypePtr* ooptype): Type(NarrowOop),
     _ooptype(ooptype) {
@@ -940,8 +945,8 @@
     return make(TypeOopPtr::make_from_constant(con));
   }
 
-  // returns the equivalent oopptr type for this compressed pointer
-  virtual const TypePtr *make_oopptr() const {
+  // returns the equivalent ptr type for this compressed pointer
+  const TypePtr *make_oopptr() const {
     return _ooptype;
   }
 
@@ -1128,6 +1133,16 @@
   return (TypeKlassPtr*)this;
 }
 
+inline const TypePtr* Type::make_ptr() const {
+  return (_base == NarrowOop) ? is_narrowoop()->make_oopptr() :
+                                (isa_ptr() ? is_ptr() : NULL);
+}
+
+inline const TypeNarrowOop* Type::make_narrowoop() const {
+  return (_base == NarrowOop) ? is_narrowoop() :
+                                (isa_ptr() ? TypeNarrowOop::make(is_ptr()) : NULL);
+}
+
 inline bool Type::is_floatingpoint() const {
   if( (_base == FloatCon)  || (_base == FloatBot) ||
       (_base == DoubleCon) || (_base == DoubleBot) )
--- a/hotspot/src/share/vm/prims/jni.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/prims/jni.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -631,7 +631,7 @@
   DTRACE_PROBE2(hotspot_jni, FatalError__entry, env, msg);
   tty->print_cr("FATAL ERROR in native method: %s", msg);
   thread->print_stack();
-  os::abort(false); // Prevent core dump, causes a jck failure.
+  os::abort(); // Dump core and abort
 JNI_END
 
 
--- a/hotspot/src/share/vm/prims/jvm.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/prims/jvm.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -624,6 +624,30 @@
   if (PrintJVMWarnings) warning("JVM_ResolveClass not implemented");
 JVM_END
 
+// Rationale behind JVM_FindClassFromBootLoader
+// a> JVM_FindClassFromClassLoader was never exported in the export tables.
+// b> because of (a) java.dll has a direct dependecy on the  unexported
+//    private symbol "_JVM_FindClassFromClassLoader@20".
+// c> the launcher cannot use the private symbol as it dynamically opens
+//    the entry point, so if something changes, the launcher will fail
+//    unexpectedly at runtime, it is safest for the launcher to dlopen a
+//    stable exported interface.
+// d> re-exporting JVM_FindClassFromClassLoader as public, will cause its
+//    signature to change from _JVM_FindClassFromClassLoader@20 to
+//    JVM_FindClassFromClassLoader and will not be backward compatible
+//    with older JDKs.
+// Thus a public/stable exported entry point is the right solution,
+// public here means public in linker semantics, and is exported only
+// to the JDK, and is not intended to be a public API.
+
+JVM_ENTRY(jclass, JVM_FindClassFromBootLoader(JNIEnv* env,
+                                              const char* name,
+                                              jboolean throwError))
+  JVMWrapper3("JVM_FindClassFromBootLoader %s throw %s", name,
+              throwError ? "error" : "exception");
+  return JVM_FindClassFromClassLoader(env, name, JNI_FALSE,
+                                      (jobject)NULL, throwError);
+JVM_END
 
 JVM_ENTRY(jclass, JVM_FindClassFromClassLoader(JNIEnv* env, const char* name,
                                                jboolean init, jobject loader,
--- a/hotspot/src/share/vm/prims/jvm.h	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/prims/jvm.h	Wed Jul 05 16:38:46 2017 +0200
@@ -390,6 +390,17 @@
                              jobject loader, jboolean throwError);
 
 /*
+ * Find a class from a boot class loader. Throw ClassNotFoundException
+ * or NoClassDefFoundError depending on the value of the last
+ * argument. This is the same as FindClassFromClassLoader but provided
+ * as a convenience method exported correctly on all platforms for
+ * JSR 277 launcher class loading.
+ */
+JNIEXPORT jclass JNICALL
+JVM_FindClassFromBootLoader(JNIEnv *env, const char *name,
+                            jboolean throwError);
+
+/*
  * Find a class from a given class.
  */
 JNIEXPORT jclass JNICALL
--- a/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -946,6 +946,9 @@
   diagnostic(bool, UseIncDec, true,                                         \
           "Use INC, DEC instructions on x86")                               \
                                                                             \
+  product(bool, UseNewLongLShift, false,                                    \
+          "Use optimized bitwise shift left")                               \
+                                                                            \
   product(bool, UseStoreImmI16, true,                                       \
           "Use store immediate 16-bits value instruction on x86")           \
                                                                             \
--- a/hotspot/src/share/vm/runtime/hpi.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/runtime/hpi.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -66,6 +66,8 @@
   static inline int    socket_shutdown(int fd, int howto);
   static inline int    recv(int fd, char *buf, int nBytes, int flags);
   static inline int    send(int fd, char *buf, int nBytes, int flags);
+  // Variant of send that doesn't support interruptible I/O
+  static inline int    raw_send(int fd, char *buf, int nBytes, int flags);
   static inline int    timeout(int fd, long timeout);
   static inline int    listen(int fd, int count);
   static inline int    connect(int fd, struct sockaddr *him, int len);
--- a/hotspot/src/share/vm/runtime/java.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/runtime/java.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -502,9 +502,9 @@
   os::shutdown();
 }
 
-void vm_abort() {
+void vm_abort(bool dump_core) {
   vm_perform_shutdown_actions();
-  os::abort(PRODUCT_ONLY(false));
+  os::abort(dump_core);
   ShouldNotReachHere();
 }
 
@@ -538,18 +538,24 @@
   java_lang_Throwable::print_stack_trace(exception(), tty);
   tty->cr();
   vm_notify_during_shutdown(NULL, NULL);
-  vm_abort();
+
+  // Failure during initialization, we don't want to dump core
+  vm_abort(false);
 }
 
 void vm_exit_during_initialization(symbolHandle ex, const char* message) {
   ResourceMark rm;
   vm_notify_during_shutdown(ex->as_C_string(), message);
-  vm_abort();
+
+  // Failure during initialization, we don't want to dump core
+  vm_abort(false);
 }
 
 void vm_exit_during_initialization(const char* error, const char* message) {
   vm_notify_during_shutdown(error, message);
-  vm_abort();
+
+  // Failure during initialization, we don't want to dump core
+  vm_abort(false);
 }
 
 void vm_shutdown_during_initialization(const char* error, const char* message) {
--- a/hotspot/src/share/vm/runtime/java.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/runtime/java.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -37,7 +37,7 @@
 // Shutdown the VM but do not exit the process
 extern void vm_shutdown();
 // Shutdown the VM and abort the process
-extern void vm_abort();
+extern void vm_abort(bool dump_core=true);
 
 // Trigger any necessary notification of the VM being shutdown
 extern void notify_vm_shutdown();
--- a/hotspot/src/share/vm/utilities/debug.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/utilities/debug.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -208,7 +208,9 @@
     Thread* thread = ThreadLocalStorage::get_thread_slow();
     VMError(thread, size, message, file_name, line_no).report_and_die();
   }
-  vm_abort();
+
+  // Dump core and abort
+  vm_abort(true);
 }
 
 void report_vm_out_of_memory_vararg(const char* file_name, int line_no, size_t size, const char* format, ...) {
--- a/hotspot/src/share/vm/utilities/ostream.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/utilities/ostream.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -753,21 +753,28 @@
   write(str, len);
 }
 
-bufferedStream::bufferedStream(size_t initial_size) : outputStream() {
+bufferedStream::bufferedStream(size_t initial_size, size_t bufmax) : outputStream() {
   buffer_length = initial_size;
   buffer        = NEW_C_HEAP_ARRAY(char, buffer_length);
   buffer_pos    = 0;
   buffer_fixed  = false;
+  buffer_max    = bufmax;
 }
 
-bufferedStream::bufferedStream(char* fixed_buffer, size_t fixed_buffer_size) : outputStream() {
+bufferedStream::bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax) : outputStream() {
   buffer_length = fixed_buffer_size;
   buffer        = fixed_buffer;
   buffer_pos    = 0;
   buffer_fixed  = true;
+  buffer_max    = bufmax;
 }
 
 void bufferedStream::write(const char* s, size_t len) {
+
+  if(buffer_pos + len > buffer_max) {
+    flush();
+  }
+
   size_t end = buffer_pos + len;
   if (end >= buffer_length) {
     if (buffer_fixed) {
@@ -811,7 +818,7 @@
 #endif
 
 // Network access
-networkStream::networkStream() {
+networkStream::networkStream() : bufferedStream(1024*10, 1024*10) {
 
   _socket = -1;
 
@@ -831,7 +838,9 @@
 
 void networkStream::flush() {
   if (size() != 0) {
-    hpi::send(_socket, (char *)base(), (int)size(), 0);
+    int result = hpi::raw_send(_socket, (char *)base(), (int)size(), 0);
+    assert(result != -1, "connection error");
+    assert(result == (int)size(), "didn't send enough data");
   }
   reset();
 }
--- a/hotspot/src/share/vm/utilities/ostream.hpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/utilities/ostream.hpp	Wed Jul 05 16:38:46 2017 +0200
@@ -206,11 +206,12 @@
  protected:
   char*  buffer;
   size_t buffer_pos;
+  size_t buffer_max;
   size_t buffer_length;
   bool   buffer_fixed;
  public:
-  bufferedStream(size_t initial_bufsize = 256);
-  bufferedStream(char* fixed_buffer, size_t fixed_buffer_size);
+  bufferedStream(size_t initial_bufsize = 256, size_t bufmax = 1024*1024*10);
+  bufferedStream(char* fixed_buffer, size_t fixed_buffer_size, size_t bufmax = 1024*1024*10);
   ~bufferedStream();
   virtual void write(const char* c, size_t len);
   size_t      size() { return buffer_pos; }
--- a/hotspot/src/share/vm/utilities/xmlstream.cpp	Wed Jul 09 10:04:09 2008 -0700
+++ b/hotspot/src/share/vm/utilities/xmlstream.cpp	Wed Jul 05 16:38:46 2017 +0200
@@ -59,6 +59,7 @@
   if (!is_open())  return;
 
   out()->write(s, len);
+  update_position(s, len);
 }
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6714694/Tester.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,820 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6714694
+ * @summary assertion in 64bit server vm (store->find_edge(load) != -1,"missing precedence edge") with COOPs
+ * @run main/othervm -Xcomp Tester
+ */
+
+/* Complexity upper bound: 38602 ops */
+
+interface Tester_Interface_0 {
+}
+
+
+abstract class Tester_Class_1 implements Tester_Interface_0 {
+    static int var_1 = (false ? (short)'b' : (short)-2.4256387E38F) | (byte)('g' * -7.660532860983624E307);
+    float var_2;
+    byte var_3;
+    static boolean var_4 = true;
+    double var_5 = 8.818325751338691E307;
+    Object var_6;
+    static short var_7;
+    final static char var_8 = 'x';
+    final static float var_9 = 2.2030989E38F;
+
+
+    public Tester_Class_1()
+    {
+        var_6 = (var_6 = (var_6 = "xkx"));
+        switch (var_7 = (var_3 = (byte)var_5))
+        {
+            case 113:
+
+            case 114:
+                Object var_12;
+                var_4 = 4.9121917E37F < 1957795258;
+                var_4 |= (var_4 ^= !var_4) ^ (var_4 |= var_4);
+                var_3 = (var_3 = (var_3 = (byte)+6010964363045275648L));
+                break;
+
+            case 102:
+
+        }
+        final float var_13 = 1.2443151E38F;
+        var_3 = (byte)(var_1 |= (var_7 = (var_3 = (byte)var_5)));
+        var_2 = (long)(var_7 = (var_3 = (byte)var_8)) - (var_7 = (byte)386742565);
+        var_4 &= var_4;
+        var_2 = (long)((var_3 = (var_3 = (byte)var_8)) / ((var_4 ^= (var_5 /= var_9) <= (var_1 &= var_1)) ? (var_7 = (short)6872886933545336832L) : (byte)var_8));
+        var_6 = "uqflj";
+        {
+            switch (((new String[var_3 = (byte)var_5])[var_3 = (byte)8097442298927900672L]).charAt(1540148550))
+            {
+                case 'l':
+
+            }
+            var_2 = (var_7 = (byte)2.9859440663042714E307);
+            {
+                Object var_14;
+            }
+            var_3 = (var_3 = (var_3 = (byte)3.3634427195550136E307));
+            var_5 += '_';
+        }
+        var_6 = "tempfdjen";
+        var_3 = (((var_4 ^= new String("jmwiwmk").endsWith("rtlstmnuo")) ? !true : !false) ? true : (var_4 = false)) ? (var_3 = (byte)var_5) : (var_3 = (var_3 = (byte)var_5));
+        var_4 ^= false;
+        if (1.6435436003809043E307 != var_9)
+        {
+            boolean var_15 = true;
+        }
+        else
+        {
+            var_4 = false;
+        }
+        {
+            Object var_16 = ((new Tester_Class_1[(byte)71832757][(byte)1.0694914E38F])[(byte)1315653071][(byte)(var_7 = (var_7 = (byte)var_8))]).var_6 = new int[(byte)var_8][var_3 = (byte)1933656747];
+        }
+        var_7 = (var_4 = var_4) ? (short)2.756967E37F : (short)'K';
+        byte var_17;
+    }
+
+
+
+    abstract public Tester_Interface_0 func_0(double[][] arg_0, final Object arg_1);
+
+
+    final double func_0(final float arg_0, final short arg_1, final boolean arg_2)
+    {
+        var_6 = (var_6 = "lmshbl");
+        var_3 = (var_3 = (new byte[(new byte[(byte)arg_1])[var_3 = (byte)arg_0]])[var_3 = (var_3 = (byte)(var_1 >>>= var_1))]);
+        var_5 %= (var_3 = (byte)1909375874);
+        var_1 /= (char)(short)'i';
+        {
+            "vgar".length();
+        }
+        int var_10;
+        {
+            var_3 = (var_4 &= true) ? (byte)(var_5 *= 6375499657746206720L) : (byte)+ (var_5 /= var_9);
+            var_7 = (var_4 = true) ? (byte)(false ? (short)749593632 : (byte)8.692758043260743E307) : (byte)var_1;
+            ((new Tester_Class_1[(byte)1.2890904018345944E308])[(byte)var_1]).var_3 = (var_3 = (byte)arg_0);
+            var_4 = true ^ var_4;
+        }
+        {
+            var_1 ^= (var_3 = (var_3 = (var_3 = (byte)'U')));
+        }
+        var_3 = (var_3 = (var_3 = (var_3 = (byte)arg_1)));
+        char var_11;
+        var_1 += (var_2 = (var_7 = arg_1));
+        {
+            var_7 = (var_7 = arg_1);
+        }
+        var_7 = arg_1;
+        var_6 = (new char[(byte)1985094111797788672L][var_3 = (byte)3112604683090268160L])[var_3 = (byte)~ (var_3 = (byte)(var_5 += var_1))];
+        var_3 = (var_3 = (var_3 = (var_3 = (byte)3694858000202921984L)));
+        var_1 /= ~ ((byte)1311538336);
+        (((var_4 |= arg_2 ? !true && arg_2 : false) ? arg_2 : arg_2) ? "iih".substring(~ (var_3 = (byte)3.5401308E37F), 'g' * arg_1) : "gynskmvoj").trim();
+        var_3 = (var_3 = arg_2 ? (byte)+ ~5247392660383928320L : (byte)8392160279007184896L);
+        var_3 = (var_3 = (var_3 = (byte)var_8));
+        return (var_5 += 7.157559E37F) + (var_11 = 'V');
+    }
+
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Tester_Class_1.var_7 = "; result += Tester.Printer.print(var_7);
+        result += "\n";
+        result += "Tester_Class_1.var_3 = "; result += Tester.Printer.print(var_3);
+        result += "\n";
+        result += "Tester_Class_1.var_8 = "; result += Tester.Printer.print(var_8);
+        result += "\n";
+        result += "Tester_Class_1.var_1 = "; result += Tester.Printer.print(var_1);
+        result += "\n";
+        result += "Tester_Class_1.var_4 = "; result += Tester.Printer.print(var_4);
+        result += "\n";
+        result += "Tester_Class_1.var_5 = "; result += Tester.Printer.print(var_5);
+        result += "\n";
+        result += "Tester_Class_1.var_2 = "; result += Tester.Printer.print(var_2);
+        result += "\n";
+        result += "Tester_Class_1.var_9 = "; result += Tester.Printer.print(var_9);
+        result += "\n";
+        result += "Tester_Class_1.var_6 = "; result += Tester.Printer.print(var_6);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+}
+
+
+class Tester_Class_2 extends Tester_Class_1 implements Tester_Interface_0 {
+    final static String var_18 = false | Tester_Class_1.var_4 | (Tester_Class_1.var_4 &= (Tester_Class_1.var_4 |= (Tester_Class_1.var_4 = var_4))) ? "tbobyhqne" : "";
+    static String var_19 = "acxfj";
+
+
+    public Tester_Class_2()
+    {
+        Tester_Class_1.var_4 = !Tester_Class_1.var_4;
+        var_1++;
+        var_2 = (byte)2.4009747E38F;
+        new String();
+        var_6 = (var_19 = "hsshyw");
+        var_19 = var_19;
+    }
+
+
+    public Tester_Interface_0 func_0(double[][] arg_0, final Object arg_1)
+    {
+        var_5 = 4.0352057E37F;
+        (((false && ! ((Tester_Class_1.var_4 |= !true) ^ (Tester_Class_1.var_4 ^ false))) ^ (var_4 &= true) ? var_4 : (var_4 ^= true)) ? "spskwj" : "xcqianm").length();
+        ((var_4 |= (Tester_Class_1.var_4 ^= Tester_Class_1.var_4) ? (Tester_Class_1.var_4 &= false) : (Tester_Class_1.var_4 |= Tester_Class_1.var_4)) ? (Tester_Class_1)(var_6 = new double[(byte)6.628342687109622E307]) : (Tester_Class_1)arg_1).var_6 = arg_0;
+        var_7 = (short)(byte)(short)8775325134193811456L;
+        var_4 ^= (var_4 &= !false);
+        ((Tester_Class_1)arg_1).var_3 = (var_3 = (byte)(var_5 %= 8.933448E37F));
+        Tester_Class_1 var_20 = Tester_Class_1.var_4 ? (Tester_Class_1)arg_1 : (Tester_Class_1)arg_1;
+        {
+            var_19.endsWith(var_19);
+            var_6 = var_20;
+            (var_20 = (var_20 = var_20)).var_2 = (short)('p' <= 1986176769 % (int)2242661265280256000L % 2664882044098145280L ? ~ (var_3 = (byte)1.1892553447967157E308) & ~1806805036550279168L : (var_7 = (byte)var_8));
+        }
+        final boolean var_21 = Tester_Class_1.var_4;
+        var_20.var_3 = (var_3 = (var_20.var_3 = (byte)'t'));
+        boolean var_22 = true;
+        Tester_Class_1.var_4 |= (var_4 = var_21);
+        var_19 = "ocn";
+        var_19 = var_19;
+        var_1 *= Tester_Class_1.var_8;
+        var_20 = var_22 ? var_20 : var_20;
+        var_7 = var_21 ? (byte)+ ((byte)var_1) : ((var_20 = (var_20 = var_20)).var_3 = (var_3 = (var_3 = (byte)'L')));
+        return true ? (var_20 = var_20) : (new Tester_Interface_0[(byte)5618282952859970560L])[var_3 = (byte)Tester_Class_1.var_8];
+    }
+
+
+    public boolean equals(Object obj)
+    {
+        Tester_Class_1.var_7 = (var_7 = (((Tester_Class_1)obj).var_3 = (byte)var_9));
+        {
+            final Tester_Class_1 var_23 = (Tester_Class_1)obj;
+        }
+        ++Tester_Class_1.var_1;
+        var_5 = (Tester_Class_1.var_7 = var_4 ? (Tester_Class_1.var_7 = (((Tester_Class_1)obj).var_3 = (byte)Tester_Class_1.var_8)) : (var_7 = (byte)var_9));
+        ((Tester_Class_1)obj).var_6 = var_18.replace(Tester_Class_1.var_8, Tester_Class_1.var_8);
+        ((new Tester_Class_1[((Tester_Class_1)(obj = new char[var_3 = (byte)Tester_Class_1.var_8])).var_3 = (((Tester_Class_1)obj).var_3 = (byte)(var_1 %= 787509251458841600L))])[(new byte[var_3 = (byte)Tester_Class_1.var_1])[((Tester_Class_1)obj).var_3 = (byte)1.2382548E38F]]).var_3 = (((Tester_Class_1)obj).var_3 = var_4 ? (byte)Tester_Class_1.var_8 : (byte)4.1085164E36F);
+        var_1 &= var_8;
+        var_7 = var_4 ? (var_3 = (byte)var_8) : (byte)var_5;
+        var_19 = var_18;
+        ("o".compareTo("kwlfk") > (var_2 = 5289241662482067456L) ? (Tester_Class_1)obj : (Tester_Class_1)obj).var_5 -= (((Tester_Class_1)obj).var_3 = (((Tester_Class_1)obj).var_3 = (((Tester_Class_1)obj).var_3 = (byte)var_9)));
+        return true;
+    }
+
+
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Tester_Class_2.var_7 = "; result += Tester.Printer.print(var_7);
+        result += "\n";
+        result += "Tester_Class_2.var_8 = "; result += Tester.Printer.print(var_8);
+        result += "\n";
+        result += "Tester_Class_2.var_3 = "; result += Tester.Printer.print(var_3);
+        result += "\n";
+        result += "Tester_Class_2.var_18 = "; result += Tester.Printer.print(var_18);
+        result += "\n";
+        result += "Tester_Class_2.var_19 = "; result += Tester.Printer.print(var_19);
+        result += "\n";
+        result += "Tester_Class_2.var_1 = "; result += Tester.Printer.print(var_1);
+        result += "\n";
+        result += "Tester_Class_2.var_4 = "; result += Tester.Printer.print(var_4);
+        result += "\n";
+        result += "Tester_Class_2.var_5 = "; result += Tester.Printer.print(var_5);
+        result += "\n";
+        result += "Tester_Class_2.var_2 = "; result += Tester.Printer.print(var_2);
+        result += "\n";
+        result += "Tester_Class_2.var_9 = "; result += Tester.Printer.print(var_9);
+        result += "\n";
+        result += "Tester_Class_2.var_6 = "; result += Tester.Printer.print(var_6);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+}
+
+
+class Tester_Class_3 extends Tester_Class_2 implements Tester_Interface_0 {
+    long var_24 = 9026266006808413184L;
+    char var_25;
+    String var_26 = ((var_4 ^= Tester_Class_1.var_4) ? (!true ? false : (var_4 |= true)) : (Tester_Class_2.var_4 ^= var_4)) ? "dkmhvhl" : (var_19 = (Tester_Class_2.var_19 = (Tester_Class_2.var_19 = var_18)));
+    static Tester_Class_2 var_27;
+    short var_28 = Tester_Class_2.var_7 = (short)(Tester_Class_2.var_1 &= (var_3 = (var_3 = (var_3 = (byte)Tester_Class_2.var_9))));
+    static boolean var_29 = false;
+    static Object[][] var_30;
+    int var_31 = 750583762;
+    Tester_Class_2 var_32;
+    final static long var_33 = 3050784555932008448L;
+
+
+    public Tester_Class_3()
+    {
+        byte[] var_34;
+        var_4 &= (Tester_Class_1.var_4 = true);
+        Tester_Class_1.var_1--;
+        switch (var_28 >>= ~ ((byte)var_28))
+        {
+            case 9:
+
+            case 26:
+                Tester_Class_1.var_4 ^= Tester_Class_1.var_4;
+                (Tester_Class_2.var_19 = "pwtic").indexOf(Tester_Class_2.var_18);
+                var_26.indexOf(var_19);
+                ((Tester_Class_1)(new Tester_Interface_0[(byte)var_5])[var_24 <= var_31 ? (byte)'^' : (byte)var_24]).var_2 = 5611775846881101824L;
+                var_29 |= (Tester_Class_2.var_4 ^= var_29);
+                Tester_Class_2 var_35;
+                var_24 <<= (var_31 >>= (var_25 = var_8));
+                break;
+
+            case 28:
+
+        }
+        new String();
+        var_5 %= (var_25 = 'n');
+        ((Tester_Class_2)(Tester_Class_1)(((Tester_Class_1)(var_6 = Tester_Class_2.var_18)).var_6 = (var_26 = ""))).var_2 = var_31;
+        --var_1;
+    }
+
+
+
+
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Tester_Class_3.var_8 = "; result += Tester.Printer.print(var_8);
+        result += "\n";
+        result += "Tester_Class_3.var_25 = "; result += Tester.Printer.print(var_25);
+        result += "\n";
+        result += "Tester_Class_3.var_1 = "; result += Tester.Printer.print(var_1);
+        result += "\n";
+        result += "Tester_Class_3.var_31 = "; result += Tester.Printer.print(var_31);
+        result += "\n";
+        result += "Tester_Class_3.var_30 = "; result += Tester.Printer.print(var_30);
+        result += "\n";
+        result += "Tester_Class_3.var_24 = "; result += Tester.Printer.print(var_24);
+        result += "\n";
+        result += "Tester_Class_3.var_33 = "; result += Tester.Printer.print(var_33);
+        result += "\n";
+        result += "Tester_Class_3.var_5 = "; result += Tester.Printer.print(var_5);
+        result += "\n";
+        result += "Tester_Class_3.var_2 = "; result += Tester.Printer.print(var_2);
+        result += "\n";
+        result += "Tester_Class_3.var_9 = "; result += Tester.Printer.print(var_9);
+        result += "\n";
+        result += "Tester_Class_3.var_7 = "; result += Tester.Printer.print(var_7);
+        result += "\n";
+        result += "Tester_Class_3.var_28 = "; result += Tester.Printer.print(var_28);
+        result += "\n";
+        result += "Tester_Class_3.var_3 = "; result += Tester.Printer.print(var_3);
+        result += "\n";
+        result += "Tester_Class_3.var_18 = "; result += Tester.Printer.print(var_18);
+        result += "\n";
+        result += "Tester_Class_3.var_19 = "; result += Tester.Printer.print(var_19);
+        result += "\n";
+        result += "Tester_Class_3.var_26 = "; result += Tester.Printer.print(var_26);
+        result += "\n";
+        result += "Tester_Class_3.var_4 = "; result += Tester.Printer.print(var_4);
+        result += "\n";
+        result += "Tester_Class_3.var_29 = "; result += Tester.Printer.print(var_29);
+        result += "\n";
+        result += "Tester_Class_3.var_27 = "; result += Tester.Printer.print(var_27);
+        result += "\n";
+        result += "Tester_Class_3.var_32 = "; result += Tester.Printer.print(var_32);
+        result += "\n";
+        result += "Tester_Class_3.var_6 = "; result += Tester.Printer.print(var_6);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+}
+
+public class Tester {
+    static double var_36 = 2.679028326789642E307;
+    float var_37;
+    String var_38 = Tester_Class_2.var_18;
+    static Tester_Interface_0 var_39;
+    static char var_40 = 'D';
+    Tester_Class_1 var_41;
+    static int var_42;
+    final static boolean var_43 = false;
+
+
+    final static Tester_Class_2 func_0(Tester_Class_1 arg_0, final Tester_Class_2 arg_1)
+    {
+        "ooots".replaceFirst("rdxor", ((new Tester_Class_3[arg_1.var_3 = (byte)2.7836305E38F])[arg_0.var_3 = (byte)+ + +1.4958218616334936E307]).var_26);
+        if (true)
+        {
+            arg_0 = (Tester_Class_3)arg_0;
+            ((Tester_Class_3)arg_0).var_25 = var_40;
+            final Tester_Class_2 var_44 = (Tester_Class_2)((Tester_Class_3.var_29 |= var_43) ? arg_0 : (arg_0.var_6 = Tester_Class_3.var_18));
+        }
+        else
+        {
+            var_39 = (Tester_Class_3.var_27 = (Tester_Class_3)arg_1);
+        }
+        Tester_Class_3.var_19 = "onndgsil";
+        var_39 = arg_0;
+        return (Tester_Class_2.var_4 &= Tester_Class_2.var_4 ^ true) ? (((Tester_Class_3)arg_0).var_32 = (Tester_Class_3)arg_1) : (((Tester_Class_3)arg_0).var_32 = (Tester_Class_3)arg_1);
+    }
+
+    private final static float func_1(final short arg_0, int[][] arg_1, final long arg_2)
+    {
+        Tester_Class_2.var_1 *= arg_0;
+        double var_45 = 6.841391103184752E307;
+        long var_46;
+        Tester_Class_2.var_1--;
+        --var_40;
+        ++var_40;
+        ++Tester_Class_3.var_1;
+        Tester_Class_1.var_4 = false;
+        var_36 %= 'X';
+        ++Tester_Class_2.var_1;
+        Tester_Class_1.var_1++;
+        return 3.2422038E38F;
+    }
+
+    private final static char func_2(double arg_0, final byte arg_1, int arg_2)
+    {
+        --Tester_Class_3.var_1;
+        if (Tester_Class_1.var_4)
+        {
+            if (var_43)
+            {
+                Tester_Class_3.var_1++;
+            }
+            else
+            {
+                var_40 <<= 1329560515532651520L;
+            }
+            (false & Tester_Class_2.var_4 ? (new Tester_Class_1[arg_1])[arg_1] : (new Tester_Class_1[arg_1][arg_1])[arg_1][arg_1]).var_3 = arg_1;
+            Tester_Class_2.var_19 = Tester_Class_3.var_19;
+            --var_40;
+            final long var_47 = ~Tester_Class_3.var_33 << var_40--;
+            ((Tester_Class_3)(new Tester_Class_2[arg_1][arg_1])[arg_1][arg_1]).var_24 *= (var_36 *= (long)arg_1 * ~arg_1);
+            Tester_Class_2.var_19 = Tester_Class_2.var_19;
+            ++((new Tester_Class_3[arg_1])[arg_1]).var_24;
+        }
+        else
+        {
+            var_40++;
+        }
+        var_40 <<= var_40;
+        if (true)
+        {
+            ++arg_2;
+        }
+        else
+        {
+            Tester_Class_2.var_7 = arg_1;
+        }
+        boolean var_48 = true;
+        var_36 /= arg_1;
+        final short var_49 = 15276;
+        Tester_Interface_0 var_50;
+        ((Tester_Class_2.var_19 = (Tester_Class_2.var_19 = Tester_Class_2.var_19)) + "xhi").toString();
+        arg_2++;
+        return var_40;
+    }
+
+    public final static char func_4(final boolean arg_0)
+    {
+        float var_52 = 2.8063675E38F;
+        var_40--;
+        Object var_53;
+        Tester_Class_3.var_29 |= (Tester_Class_3.var_29 &= true);
+        if (!Tester_Class_1.var_4)
+        {
+            --var_40;
+        }
+        else
+        {
+            var_52 %= 2027756834;
+        }
+        int var_54 = Tester_Class_1.var_1++;
+        var_40--;
+        long var_55;
+        byte var_56 = 97;
+        var_36 *= 9.75628909363086E307 % + -1.9812653793936264E306;
+        int var_57;
+        boolean var_58 = Tester_Class_1.var_4 ^= var_43;
+        return 'J';
+    }
+
+    static float func_5(final Object arg_0, float arg_1, final Tester_Class_2 arg_2)
+    {
+        var_39 = arg_2;
+        Tester_Class_3.var_27 = arg_2;
+        arg_1 %= 1.7777554E38F;
+        var_39 = (Tester_Class_3.var_27 = arg_2);
+        Tester_Class_3 var_59;
+        {
+            var_40 -= arg_1 - ~ (((Tester_Class_3)arg_2).var_3 = (byte)1455854212);
+        }
+        Object var_60 = Tester_Class_1.var_4 ? arg_0 : new String[arg_2.var_3 = (byte)arg_1][(byte)((Tester_Class_3)arg_0).var_28];
+        Tester_Class_3.var_27 = (Tester_Class_2)(var_39 = arg_2);
+        ((Tester_Class_3.var_4 |= var_43) ? (var_59 = (var_59 = (var_59 = (Tester_Class_3)var_60))) : (var_59 = (Tester_Class_3)arg_2)).var_24 ^= Tester_Class_3.var_1;
+        return Tester_Class_1.var_9;
+    }
+
+    private static void func_6(char arg_0, final Tester_Class_3 arg_1, String arg_2, final double arg_3)
+    {
+        ((new Tester_Class_1[(byte)arg_1.var_28])[(arg_1.var_32 = arg_1).var_3 = (byte)var_40]).var_2 = Tester_Class_3.var_9;
+        double var_61;
+        (true ? (arg_1.var_32 = arg_1) : (arg_1.var_32 = (Tester_Class_3.var_27 = (arg_1.var_32 = arg_1)))).var_6 = var_43 | (Tester_Class_2.var_4 = !Tester_Class_3.var_4) ? (arg_1.var_26 = arg_2) : (Tester_Class_2.var_19 = Tester_Class_2.var_18);
+    }
+
+    private final char func_7(int arg_0)
+    {
+        Tester_Class_2.var_4 &= var_43;
+        float var_62 = Tester_Class_3.var_9;
+        --var_40;
+        int var_63 = Tester_Class_1.var_1++;
+        {
+            "nncjfoit".indexOf((new int[(byte)'\\'])[(byte)var_36]);
+            if (var_43)
+            {
+                ((new Tester_Class_3[(byte)var_40][(byte)Tester_Class_2.var_1])[(byte)5046997225818337280L][(byte)var_63]).var_24 >>>= var_40;
+            }
+            else
+            {
+                --var_40;
+            }
+            --Tester_Class_2.var_1;
+            --var_63;
+        }
+        {
+            final byte var_64 = Tester_Class_1.var_4 ? (byte)'M' : (byte)(var_62 -= + ((byte)Tester_Class_1.var_8));
+            float var_65;
+            var_62 *= ((Tester_Class_3)(new Tester_Interface_0[var_64])[var_64]).var_24++;
+            var_36 /= var_64;
+            {
+                double var_66;
+            }
+            var_40 += 3500240160155094016L;
+            ((new Tester_Class_1[var_64][var_64])[var_64][var_64]).var_3 = (byte)(Tester_Class_2.var_7 = (Tester_Class_1.var_7 = (Tester_Class_1.var_7 = (Tester_Class_1.var_7 = var_64))));
+            ++Tester_Class_3.var_1;
+        }
+        --arg_0;
+        {
+            arg_0++;
+        }
+        Tester_Class_2.var_1++;
+        var_40 &= (short)((byte)Tester_Class_2.var_8 >> (((new Tester_Class_3[(byte)var_36])[(byte)(var_40 = Tester_Class_3.var_8)]).var_3 = (byte)((byte)3.3531374E38F * var_40)));
+        var_36 %= (var_62 = (byte)900943133);
+        var_36 = Tester_Class_3.var_33;
+        var_62 += (var_40 /= (byte)6766658341842315264L % (byte)'p') * (short)2019461672;
+        --var_40;
+        if (true)
+        {
+            var_62 *= 365879806965555200L;
+        }
+        else
+        {
+            var_36 -= ~9163555887358003200L;
+        }
+        Tester_Class_1.var_4 = Tester_Class_1.var_4;
+        {
+            var_40 <<= var_63;
+        }
+        var_40++;
+        String var_67;
+        return Tester_Class_1.var_8;
+    }
+
+    private final static Tester_Interface_0 func_8(char arg_0, final Tester_Class_2 arg_1, final String arg_2)
+    {
+        ((new Tester[(byte)((Tester_Class_3)arg_1).var_28])[((Tester_Class_1)(var_39 = arg_1)).var_3 = ((Tester_Class_3.var_27 = (Tester_Class_3)arg_1).var_3 = (byte)+ -9.9100855E36F)]).var_38 = (var_43 ? "k" : Tester_Class_2.var_19).substring(350785312);
+        return (new Tester_Interface_0[(byte)'l'])[((Tester_Class_1)(var_39 = (Tester_Class_3.var_27 = (Tester_Class_3)arg_1))).var_3 = ((Tester_Class_3.var_27 = arg_1).var_3 = (((Tester_Class_3)arg_1).var_3 = (arg_1.var_3 = (arg_1.var_3 = (byte)'['))))];
+    }
+
+    private final int func_9(Tester_Class_3 arg_0, char arg_1)
+    {
+        final float var_68 = Tester_Class_3.var_9;
+        Tester_Class_2.var_18.toLowerCase();
+        double var_69;
+        {
+            Tester_Class_3.var_29 ^= !false || Tester_Class_2.var_4;
+        }
+        Tester_Class_1 var_70;
+        (Tester_Class_3.var_27 = (Tester_Class_2)(var_70 = arg_0)).var_6 = (Tester_Class_2)((var_41 = arg_0).var_6 = (arg_0.var_6 = arg_0));
+        "hv".codePointBefore(--Tester_Class_2.var_1);
+        var_41 = arg_0;
+        return ~ (((arg_0 = arg_0).var_24 &= arg_1) == 3.0764282E38F ? (byte)457565863 : ((arg_0 = arg_0).var_3 = (byte)arg_0.var_28));
+    }
+
+    private static void func_10(double arg_0, final Tester_Class_3 arg_1, double arg_2)
+    {
+        arg_1.var_32 = 'g' != 1.520646515461986E307 ? (arg_1.var_32 = arg_1) : arg_1;
+        Tester_Class_2.var_19.startsWith(Tester_Class_2.var_19 = Tester_Class_3.var_18);
+        Tester_Class_1.var_4 ^= true & (arg_1.var_3 = (arg_1.var_3 = (byte)- ((byte)1.4509185661781193E308))) > (arg_1.var_2 = var_40);
+        var_36 += Tester_Class_3.var_9;
+    }
+
+    Tester_Interface_0 func_12(final Object arg_0, float arg_1)
+    {
+        switch (((Tester_Class_3)arg_0).var_3 = (byte)arg_1)
+        {
+            case 4:
+                var_41 = (Tester_Class_3)(var_39 = (Tester_Class_3.var_27 = (Tester_Class_3.var_27 = (Tester_Class_3)arg_0)));
+                double var_72 = (double)3858573493713776640L;
+                byte var_73 = (var_41 = (Tester_Class_2)arg_0).var_3 = (((Tester_Class_3)arg_0).var_3 = (byte)var_72);
+                break;
+
+            case 13:
+                (Tester_Class_3.var_27 = (((Tester_Class_3)arg_0).var_32 = (Tester_Class_3)(Tester_Class_2)arg_0)).var_3 = (Tester_Class_2.var_1 *= ((Tester_Class_3)arg_0).var_24) == (byte)Tester_Class_3.var_33 ? (byte)188693954866039808L : (byte)Tester_Class_2.var_8;
+                break;
+
+            default:
+                var_40 <<= (byte)157510337;
+                break;
+
+            case 26:
+
+            case 122:
+
+        }
+        Tester_Interface_0 var_74;
+        long var_75;
+        var_41 = (var_41 = (var_41 = (Tester_Class_2)arg_0));
+        arg_1 *= 1601420762;
+        var_74 = (var_41 = Tester_Class_1.var_4 ? (Tester_Class_3)arg_0 : (Tester_Class_2)arg_0);
+        (Tester_Class_1.var_4 ? (Tester_Class_3)(var_39 = (Tester_Class_3)arg_0) : (true ? (Tester_Class_3)arg_0 : (Tester_Class_3)arg_0)).var_28 *= 1066935145;
+        var_40 >>>= (byte)6.643183E36F / - ((byte)1.277596E37F);
+        {
+            ((Tester_Class_3)(((Tester_Class_3)((Tester_Class_3.var_29 ^= (Tester_Class_3.var_29 &= var_43)) ? (Tester_Class_2)arg_0 : (Tester_Class_2)arg_0)).var_32 = (Tester_Class_3.var_27 = (Tester_Class_2)arg_0))).var_28--;
+        }
+        var_38 = "qad";
+        byte var_76 = ((Tester_Class_2)(var_39 = (Tester_Class_3)arg_0)).var_3 = true ? ((var_41 = (var_41 = (Tester_Class_3)arg_0)).var_3 = (byte)1.7128118638075888E308) : (byte)1.6562746603631249E308;
+        return var_39 = (Tester_Class_3)((var_41 = (Tester_Class_3)arg_0).var_6 = Tester_Class_2.var_18);
+    }
+
+    protected final String func_13()
+    {
+        float var_77;
+        var_38 = (Tester_Class_2.var_19 = var_38);
+        Tester_Class_2.var_4 ^= !var_43 | (Tester_Class_3.var_29 ^= Tester_Class_1.var_4);
+        Tester_Class_3.var_1--;
+        Tester_Class_2.var_1++;
+        return Tester_Class_2.var_18;
+    }
+
+    public static String execute()
+    {
+        try {
+            Tester t = new Tester();
+            try { t.test(); }
+            catch(Throwable e) { }
+            try { return t.toString(); }
+            catch (Throwable e) { return "Error during result conversion to String"; }
+        } catch (Throwable e) { return "Error during test execution"; }
+    }
+
+    public static void main(String[] args)
+    {
+        try {
+            Tester t = new Tester();
+            try { t.test(); }
+            catch(Throwable e) { }
+            try { System.out.println(t); }
+            catch(Throwable e) { }
+        } catch (Throwable e) { }
+    }
+
+    private void test()
+    {
+        int var_78 = 0;
+        var_39 = (new Tester_Class_1[(byte)var_40])[(byte)Tester_Class_3.var_33];
+        while (var_43 && (var_78 < 70 && true))
+        {
+            var_40 *= ~ ~Tester_Class_3.var_33 % Tester_Class_3.var_9;
+            var_78++;
+            var_39 = new Tester_Class_3();
+            var_39 = (var_41 = (Tester_Class_3.var_27 = new Tester_Class_2()));
+        }
+        final Tester_Class_3 var_79 = (Tester_Class_1.var_4 ? ~Tester_Class_3.var_33 : var_36) == 1433764895112462336L ? new Tester_Class_3() : new Tester_Class_3();
+        Tester_Class_2 var_80;
+    }
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Tester.var_40 = "; result += Printer.print(var_40);
+        result += "\n";
+        result += "Tester.var_42 = "; result += Printer.print(var_42);
+        result += "\n";
+        result += "Tester.var_36 = "; result += Printer.print(var_36);
+        result += "\n";
+        result += "Tester.var_37 = "; result += Printer.print(var_37);
+        result += "\n";
+        result += "Tester.var_39 = "; result += Printer.print(var_39);
+        result += "\n";
+        result += "Tester.var_38 = "; result += Printer.print(var_38);
+        result += "\n";
+        result += "Tester.var_43 = "; result += Printer.print(var_43);
+        result += "\n";
+        result += "Tester.var_41 = "; result += Printer.print(var_41);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+    static class Printer
+    {
+        public static String print(boolean arg) { return String.valueOf(arg); }
+        public static String print(byte arg)    { return String.valueOf(arg); }
+        public static String print(short arg)   { return String.valueOf(arg); }
+        public static String print(char arg)    { return String.valueOf((int)arg); }
+        public static String print(int arg)     { return String.valueOf(arg); }
+        public static String print(long arg)    { return String.valueOf(arg); }
+        public static String print(float arg)   { return String.valueOf(arg); }
+        public static String print(double arg)  { return String.valueOf(arg); }
+
+
+        public static String print(Object arg)
+        {
+            return print_r(new java.util.Stack(), arg);
+        }
+
+        private static String print_r(java.util.Stack visitedObjects, Object arg)
+        {
+            String result = "";
+            if (arg == null)
+                result += "null";
+            else
+            if (arg.getClass().isArray())
+            {
+                for (int i = 0; i < visitedObjects.size(); i++)
+                    if (visitedObjects.elementAt(i) == arg) return "<recursive>";
+
+                visitedObjects.push(arg);
+
+                final String delimiter = ", ";
+                result += "[";
+
+                if (arg instanceof Object[])
+                {
+                    Object[] array = (Object[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print_r(visitedObjects, array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof boolean[])
+                {
+                    boolean[] array = (boolean[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof byte[])
+                {
+                    byte[] array = (byte[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof short[])
+                {
+                    short[] array = (short[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof char[])
+                {
+                    char[] array = (char[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof int[])
+                {
+                     int[] array = (int[]) arg;
+                     for (int i = 0; i < array.length; i++)
+                     {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                     }
+                }
+                else
+                if (arg instanceof long[])
+                {
+                    long[] array = (long[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof float[])
+                {
+                    float[] array = (float[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof double[])
+                {
+                    double[] array = (double[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+
+                result += "]";
+                visitedObjects.pop();
+
+            } else
+            {
+                result += arg.toString();
+            }
+
+            return result;
+        }
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/compiler/6716441/Tester.java	Wed Jul 05 16:38:46 2017 +0200
@@ -0,0 +1,940 @@
+/*
+ * Copyright 2008 Sun Microsystems, Inc.  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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/*
+ * @test
+ * @bug 6716441
+ * @summary error in meet with +DoEscapeAnalysis
+ * @run main/othervm -Xcomp -XX:+AggressiveOpts Tester
+ */
+
+/* Complexity upper bound: 70070 ops */
+
+class Tester_Class_0 {
+    Object var_1;
+
+
+    public Tester_Class_0()
+    {
+        var_1 = "cmlv";
+        {
+            final Object var_7 = false ? (var_1 = "flwnujmm") : (var_1 = "");
+        }
+        float var_8 = 0F;
+        boolean var_9;
+        do
+        {
+            ((var_9 = (var_9 = (var_9 = false))) && true ? new String("yvirc") : "rmfkjbx").indexOf(99854165);
+            var_8++;
+            boolean var_10 = true;
+            var_10 |= true ? true : false;
+            var_10 |= false | var_10 ? (var_10 |= true) : true;
+        } while (var_8 < 1 && "tpb".charAt(~ ((byte)2449669946597620736L)) >>> (byte)1.704554E38F >= ('t' < var_8 ? (short)var_8 : 1237471887 / +4199632387838836736L));
+        var_1 = (var_1 = "y");
+        switch ((var_9 = "".equalsIgnoreCase("kqalxwsnu") | false) ? (new char[(byte)1.3230508534158742E308])[(byte)(short)93390917] : 'c')
+        {
+            case 'U':
+
+            case 'W':
+
+            case 'A':
+
+            case 72:
+
+        }
+        var_9 = (var_9 = false);
+        float var_11 = 0F;
+        var_9 = true;
+        for (var_1 = (var_1 = new boolean[(new byte[(byte)'O'])[(byte)'l']]); var_11 < 2; var_1 = (true ? "" : "nn").toUpperCase())
+        {
+            var_9 = true;
+            var_11++;
+            var_9 = true;
+            int var_12 = (new short[(byte)1825213428])[(byte)1.6151095881186834E308] + (byte)(short)'V';
+        }
+        var_1 = (new boolean[(byte)1546704177][(byte)6314352927310996480L][(byte)6838913812451802112L])["e".equalsIgnoreCase("d") ? (byte)3.964472879846357E307 : (byte)'L'];
+        var_9 = (var_9 = false);
+    }
+
+
+
+    protected Object clone()
+    {
+        var_1 = (var_1 = "dbogknllu");
+        var_1 = "jljax";
+        var_1 = (var_1 = false ? "s" : "upqinst");
+        if (false)
+        {
+            var_1 = (var_1 = (var_1 = "nwhu"));
+        }
+        else
+        {
+            short var_2;
+            var_2 = false ? (byte)((short)'e' - (byte)2.267975E38F) : (byte)1.28920093132789E308;
+        }
+        (((byte)2.3450009E38F >= (byte)- (+ - -1.6256751428449317E306 * 954071273906192384L) ? true : true) ? "gpv".substring(468176669, 1915798010) : "macqbvf").offsetByCodePoints("ivwivjege".charAt(1819923298) >>> (byte)((- ~653213024937366528L + 'N') * +1.0297164E38F) + (short)~ + -4535402293751053312L, (short)3837656677199316992L + (new byte[(byte)2.1586717E38F])[(byte)((short)719847962 - 8.599263E37F)]);
+        new String((char)650047353 > (short)'I' ? "maygldu".replaceAll("hpn", "bacoyows") : "nkx").endsWith(new String("h" + "vx"));
+        byte var_3;
+        return var_1 = "vbiccvdu";
+    }
+
+    public boolean equals(Object obj)
+    {
+        var_1 = "rxpocj";
+        obj = "ndogtwvuh";
+        {
+            {
+                var_1 = "vmdkvs";
+            }
+            final boolean var_4 = false;
+            long var_5;
+            var_5 = (short)'G' >> + ((byte)1.1872624048733707E308);
+        }
+        var_1 = (new byte[(byte)(short)1.7804576633213148E308][(byte)(short)8.300151422843056E307])[(byte)3110360603258978304L];
+        obj = "fudebwroh";
+        obj = new Object[(false && false) & false ? (byte)8796624364629753856L : (byte)- +1.5843542184394165E308];
+        if (true)
+        {
+            var_1 = new float[(byte)1372189277][(byte)((byte)8.352642520619892E307 == (! !false ^ true ? (short)1.3871033E37F : (byte)'f') ? 7.33899E37F - (short)2.2558552E37F : 2.6072269E38F)];
+        }
+        else
+        {
+            var_1 = obj;
+            obj = new boolean[(byte)8.623747E37F][(byte)~ ((byte)(short)(byte)2100816354)];
+        }
+        var_1 = new int[(new byte[(byte)7410132537719084032L])[(byte)1524949007]][(byte)((long)9188640 ^ 'n')];
+        if (-3.0364305E38F > 8.114229090672013E307)
+        {
+            var_1 = (var_1 = new boolean[(byte)1.0354788699727844E308][(byte)-4867581638981979136L]);
+        }
+        else
+        {
+            obj = (obj = obj);
+            obj = (new int[(byte)'f'][(byte)7563033606293564416L])[(byte)2052737645];
+        }
+        long var_6;
+        var_6 = (+ + ~3862500564271147008L != (short)8549491352795953152L || (byte)+ + (var_6 = 'D') > (var_6 = 1687952259)) && true ? (short)1756260278 : (byte)(short)3.202384E36F;
+        return false ^ ((false ? !true : true) ? false : (true ? ! !false : false));
+    }
+
+
+
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Tester_Class_0.var_1 = "; result += Tester.Printer.print(var_1);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+}
+
+
+interface Tester_Interface_1 {
+}
+
+
+final class Tester_Class_2 extends Tester_Class_0 {
+    static char var_13;
+    final static long var_14 = ~ ~ (((false ? !true ^ !true : !false | true) ? (byte)1.4363583E38F : (byte)(short)'X') * + + +3767002589844008960L << (var_13 = (var_13 = 'X')));
+
+
+    public Tester_Class_2()
+    {
+        ((true ? (byte)- ((byte)2.6338962E38F) : (byte)'H') <= (short)8.671266E37F || !false & true ? (Tester_Class_0)(var_1 = "tgoexsr") : (Tester_Class_0)(var_1 = "mptusv")).var_1 = "tbxbgyti";
+        var_1 = true ? (var_1 = "islgpxwa") : "rypkbu";
+        var_1 = "vngiif";
+        var_13 = (var_13 = (short)~ (-3250577075350561792L + +2983539228635145216L - '`') < 861590495 * (short)1.5299644E38F ? 'V' : 'G');
+        Object[] var_27;
+        var_1 = (var_1 = "glu");
+    }
+
+
+
+
+
+    private static int func_0(Tester_Interface_1 arg_0, Tester_Interface_1 arg_1, final int arg_2)
+    {
+        var_13 = 'i';
+        new String();
+        (true ? "pu" : "oltbcysyd").substring(1236315614);
+        byte var_15;
+        var_15 = (new byte[(byte)1582653493940204544L][(byte)(char)-1.5806537192822515E308])[(byte)1.2986292E38F][(byte)(short)arg_2];
+        if (true || true)
+        {
+            ((new Tester_Class_2[var_15 = (byte)'q'])[var_15 = 7.653082E37F < (var_13 = 'o') ? (byte)- - + +3.1640875E38F : (byte)-6820511772487837696L]).var_1 = (new Tester_Class_0[(byte)(short)(new byte[(byte)1080194717])[(byte)8297829563314362368L]])[var_15 = (var_15 = (var_15 = (var_15 = (byte)'t')))];
+            double[] var_16;
+        }
+        else
+        {
+            arg_1 = (arg_1 = arg_0);
+        }
+        var_13 = (var_13 = 'o');
+        var_13 = (false || false ^ false) ^ !true ? 'Z' : (var_13 = 'i');
+        return true ? (var_15 = (byte)'C') : 1120493294;
+    }
+
+    static double func_1(final int arg_0, long arg_1, long arg_2)
+    {
+        "ghtfhmbeg".compareToIgnoreCase("djn");
+        {
+            ((true ? true : ! !true) ? "" : "ioowivxge").substring(1844979226, "ppsk".startsWith("lllmn") | false ? arg_0 * arg_0 : (byte)663320199);
+            ((Tester_Class_0)(((new Tester_Class_2[(byte)4797509007239530496L])[(byte)(- -2.8961086E38F - arg_1)]).var_1 = new float[(byte)('m' / 6.0657416E37F)])).var_1 = new boolean[(byte)(short)(+4.515459E37F - (short)arg_0)][(byte)(-1.3002677717712297E308 + (var_13 = "bcjfdnc".charAt(arg_0)) * (arg_2 - 1.6058080036165979E308))];
+            var_13 = 'E';
+        }
+        float var_17 = 0F;
+        --arg_1;
+        do
+        {
+            final String[] var_18 = new String[(byte)(short)arg_0];
+            var_17++;
+            Object var_19 = (new Object[(byte)var_17])[(false ? "xfkx".equalsIgnoreCase("j") : !false) ^ !false ? (byte)(1.6627987E35F * 2.62825E38F) : (byte)var_17];
+        } while (var_17 < 2 && false | ((byte)1.4661115E38F | arg_0 - 'l') < ('J' & (byte)+ ((float)1200013759)));
+        long var_20 = 0L;
+        arg_2--;
+        for (var_13 = (var_13 = (var_13 = (var_13 = (var_13 = (var_13 = 'p'))))); var_20 < 4; var_13 = 'y')
+        {
+            new String((true | true ? "oxpfy" : "gaynucv") + (true ? "cmrrk".substring(653981013, arg_0) : "ociewl" + "srhbvcgci"));
+            var_20++;
+            arg_2 >>= arg_0;
+            arg_2 = false ? (byte)'l' : (byte)(~var_20 - (byte)1.1290483681734838E308);
+        }
+        ((new Tester_Class_2[(byte)arg_1++])[(byte)685259385]).var_1 = new Tester_Interface_1[(byte)arg_0];
+        --arg_1;
+        var_13 = 483446392 - (byte)'P' < ((short)(true ? (var_13 = 't') : 'n') & (short)'l') ? (var_13 = 'q') : (var_13 = (var_13 = 'h'));
+        var_13 = 'y';
+        return 1.097000731360761E308;
+    }
+
+    private final boolean func_2(final short[][] arg_0, byte arg_1, Object arg_2)
+    {
+        var_1 = new char[arg_1];
+        arg_1 /= (var_13 = 'A') + -var_14;
+        int var_21 = 0;
+        arg_2 = (new Tester_Class_0[arg_1 += var_14][arg_1])[arg_1 >>>= 'R' + + -var_14 - 4078879817303787520L];
+        for (arg_1--; (+ +1.1473423E38F < 'w' & false | var_21 != (short)4633877342445358080L | !false ? false | !false : true) && (var_21 < 1 && (arg_0[arg_1])[arg_1 %= 7.136449148111178E307] > 7.362329280963185E307); arg_1++)
+        {
+            arg_1 = (arg_1 %= + -9.872181578576624E307);
+            var_21++;
+            arg_1 /= 7.365334241099395E307;
+            var_13 = (var_13 = (var_13 = (var_13 = (var_13 = (var_13 = 'A')))));
+        }
+        arg_1 >>= var_14;
+        boolean var_22 = false;
+        return ((var_22 &= true) && var_22 ? (short)1.568578228250838E308 : arg_1) >= (new float[arg_1])[arg_1 /= 1.6849858816110731E308];
+    }
+
+    public final String func_3(Tester_Interface_1 arg_0)
+    {
+        arg_0 = arg_0;
+        arg_0 = (arg_0 = arg_0);
+        var_13 = (var_13 = (var_13 = (var_13 = "rqimya".charAt(390686412))));
+        ((Tester_Class_0)(var_1 = "suxd")).var_1 = new Tester_Class_0[(byte)(float)(short)1.584667675541511E308];
+        arg_0 = ((byte)+ + - +1.3636011E38F == 'L' ^ true) & (!true | true) ? (arg_0 = arg_0) : arg_0;
+        var_1 = (((Tester_Class_0)(var_1 = (Tester_Class_0)(var_1 = "ndxcurdr"))).var_1 = (var_1 = (var_1 = "schnhe")));
+        var_1 = (new Object[(byte)(var_13 = (var_13 = 'G'))])[(byte)((byte)1.5366658198344074E308 - 1.0051541518022535E308)];
+        var_13 = (var_13 = 'x');
+        (true ? (Tester_Class_0)(var_1 = "slesdph") : (Tester_Class_0)(var_1 = "wxj")).var_1 = false ? (Tester_Class_0)(var_1 = "iddvoil") : (Tester_Class_0)(var_1 = "yjbxhuip");
+        var_13 = (var_13 = 'f');
+        var_1 = (new short[(byte)1.8902424351360974E307])[(new byte[(byte)1552392028])[(byte)'V']] >= (1.2449926736063704E308 + 'K') / (short)1.0847178E38F / ((short)'M' % (1.225890077244388E308 + + ((byte)1.5358312881295287E308))) ? (Tester_Class_0)(var_1 = "khfntg".toString()) : (Tester_Class_0)(var_1 = "jkttx");
+        {
+            arg_0 = arg_0;
+        }
+        arg_0 = arg_0;
+        var_13 = (true ? "jndbffakc" : "hhcsc").charAt((byte)7322932713210745856L >> (short)(var_13 = (var_13 = 'R')));
+        var_13 = (var_13 = (var_13 = 'U'));
+        {
+            "gepdu".trim();
+        }
+        var_13 = 'H';
+        new String();
+        {
+            (false ^ (true ^ ((!true | ! !true) ^ ! (1.7800668444792402E308 * var_14 >= (var_13 = (var_13 = (var_13 = 'g')))))) ? "dsm" : "g").toUpperCase().toString();
+            ((Tester_Class_0)(var_1 = "fcdvd")).var_1 = (Tester_Class_0)(((Tester_Class_0)(var_1 = "uwhnte")).var_1 = "vpatqpd");
+        }
+        switch (((byte)((byte)((int)'n' / var_14) >>> (short)7.786475993917233E307 - (var_13 = 'm')) <= (("".endsWith("pbypgis") ^ false) & true ? (byte)func_0(arg_0, arg_0, 723551781) : (short)140766856) ? true | (!false || false) : 'F' != (var_13 = 'V')) ? (var_13 = 'j') : 'D')
+        {
+            case 'p':
+
+        }
+        var_13 = (var_13 = (var_13 = 'y'));
+        var_13 = ("" + "wwbxwyt").charAt((short)8373354379880418304L << (short)(byte)1.557224945027141E308);
+        arg_0 = true ? (arg_0 = arg_0) : arg_0;
+        ((Tester_Class_0)(((Tester_Class_0)(var_1 = "rmkvbp")).var_1 = (var_1 = "gvb"))).var_1 = new Tester_Class_0[(byte)var_14];
+        arg_0 = arg_0;
+        return 2.5245162E38F + 3.9088502076337727E307 > 1.0883030748712796E308 ? "efttufmbg" : "xy";
+    }
+
+    protected short func_4(final double arg_0, long arg_1, final Object arg_2, final byte arg_3)
+    {
+        (((("ptnmpn".startsWith("xxgxjvsie") ? !true : ! !true) ? ! !false : false) ? (true ? true : false) : (var_13 = (var_13 = 'X')) == 1948276447) ? (Tester_Class_0)(var_1 = new float[arg_3][arg_3]) : (Tester_Class_0)arg_2).var_1 = new double[(new byte[arg_3][arg_3])[arg_3][arg_3]][arg_3];
+        boolean var_23;
+        return true ? (short)'r' : (byte)(short)('\\' >>> arg_3);
+    }
+
+    final static byte func_5(final long arg_0, float arg_1, final double arg_2)
+    {
+        arg_1 = arg_2 <= ((var_13 = 'D') <= - (3463565869695079424L << 'S') ? 'a' : (var_13 = 'o')) | (true ? !false : !false) ? (byte)(short)(var_13 = 'r') : (short)(byte)'S';
+        {
+            {
+                arg_1 %= '_';
+            }
+            char var_24 = 'G';
+            "hc".lastIndexOf("");
+            arg_1 *= (arg_1 /= (byte)-8.308933840953204E306);
+            --var_24;
+            arg_1 /= ~ ((byte)2.2736606E38F) <= (3392301601783633920L == 3.015267E38F ^ ! !true ? (byte)88382550 : (byte)1.2019729E38F) ? 1027309963 : + -4.355887546298483E307;
+            ((new Tester_Class_2[(byte)arg_2])[(byte)870592870]).var_1 = "i";
+            arg_1 /= 't';
+        }
+        var_13 = 'f';
+        Tester_Class_0 var_25 = (new Tester_Class_0[(byte)arg_1])[(true | false ^ !false) & ! !true & - +2.758844E38F >= (new short[(byte)5.9160883E37F])[(byte)'r'] ? (byte)arg_0 : (byte)((short)1802078016 & arg_0)];
+        arg_1 /= (byte)arg_2;
+        var_13 = 'R';
+        boolean var_26 = (true ? false : !false) ? false : !true == ! !false;
+        arg_1 %= (var_26 ^= (byte)1101752087 <= (short)arg_1) ? arg_1 : (float)1882235314;
+        var_25 = var_25;
+        if (var_26 &= var_26)
+        {
+            var_13 = "".startsWith("vp", - ((byte)2040501187) ^ (byte)-3921263616446438400L) ? "gam".charAt(+ ((byte)arg_1)) : (var_13 = 'H');
+            arg_1 /= var_26 | ! (var_26 ^ (byte)arg_0 <= (var_13 = 'r') | (var_26 |= var_26)) ? 'N' : ~8963227563301903360L;
+        }
+        else
+        {
+            var_13 = 'l';
+            var_25 = (var_25 = var_25);
+        }
+        arg_1 += (byte)(("m".substring(837996717, 861903057).startsWith("vwpky", (var_13 = 'Z') % (byte)arg_1) ? !false ^ !var_26 : var_26) ? (byte)arg_1 : ((var_26 | var_26) ^ !false ? (short)'U' : (short)'d'));
+        ((1.3445538E38F < (arg_1 -= 1236356135) ^ (var_26 = true)) & var_26 ? var_25 : (var_25 = var_25)).var_1 = true ? (var_25.var_1 = var_25) : (var_25.var_1 = var_25);
+        var_26 |= - ((byte)251113415) < (short)arg_1 & false & false;
+        arg_1 += (var_26 &= true) ? 7.546147305340402E307 : (true & !var_26 ? (byte)1.5107802154474685E307 : (byte)arg_1);
+        var_25.var_1 = true ? "bqsewhn" : "aojssvan";
+        return (byte)(var_13 = (char)(new short[(byte)46697464])[(byte)var_14]);
+    }
+
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Tester_Class_2.var_13 = "; result += Tester.Printer.print(var_13);
+        result += "\n";
+        result += "Tester_Class_2.var_14 = "; result += Tester.Printer.print(var_14);
+        result += "\n";
+        result += "Tester_Class_2.var_1 = "; result += Tester.Printer.print(var_1);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+}
+
+public class Tester {
+    static Tester_Class_0 var_28;
+    double var_29 = 4.861846831496217E307;
+    static byte var_30 = 79;
+    static boolean var_31 = false;
+    final byte var_32 = 48;
+
+
+    public short func_0(final byte arg_0, boolean arg_1, final double arg_2)
+    {
+        --var_30;
+        new Tester_Class_2().var_1 = "xdwldeqhc";
+        char var_33 = 'd';
+        return (var_31 = var_30 < (new short[var_30])[var_30]) ? (short)(var_33 >>>= (short)2.3152642E38F) : var_30;
+    }
+
+    private final float func_1(final long arg_0, final Tester_Class_0 arg_1, Tester_Class_0 arg_2, final char arg_3)
+    {
+        {
+            new Tester_Class_0();
+        }
+        var_30 >>= (short)1.1469118780047631E308;
+        var_31 |= var_31;
+        if (true)
+        {
+            Tester_Class_2 var_34 = (var_31 ^= (var_31 ^= false)) ? (Tester_Class_2)arg_1 : (new Tester_Class_2[var_32])[var_30];
+        }
+        else
+        {
+            "shqjwg".compareToIgnoreCase(false ? "gxoyw" + "cx" : "r" + "icj");
+        }
+        ((new Tester_Class_2[var_32])[++var_30]).var_1 = (new Object[var_30][var_32][var_32])[var_30 |= var_32];
+        arg_1.var_1 = (arg_2 = arg_2);
+        arg_1.var_1 = (((new Tester_Class_2[var_30])[var_30 = var_32]).var_1 = new String[var_32]);
+        var_28 = (Tester_Class_2)((arg_2 = arg_2).var_1 = new double[var_30]);
+        arg_2 = arg_1;
+        final boolean var_35 = "qjsdfuyru".endsWith("nuw" + "bne") | arg_3 >= 1.2054153346397785E308;
+        var_31 &= (var_31 ^= var_35);
+        {
+            var_31 &= var_31 ? false : !false;
+        }
+        if (var_31)
+        {
+            var_28 = (new Tester_Class_2[var_32])[var_32];
+        }
+        else
+        {
+            arg_1.equals((new Object[var_32])[var_32]);
+        }
+        ((var_31 ^= true) ? "x" : "euc").substring(+ (var_30 ^= var_30) & (byte)(new short[var_30])[var_30 /= 4.220757896697652E307]);
+        arg_2 = var_31 ? (Tester_Class_2)arg_1 : (Tester_Class_2)arg_2;
+        arg_2 = (Tester_Class_2)(new Object[var_32][var_32])[var_30][var_32];
+        return 9.932983E36F * (Tester_Class_2.var_13 = arg_3);
+    }
+
+    public int func_2(Tester_Class_0 arg_0)
+    {
+        "ptwusxrxn".indexOf("v");
+        var_30 |= 1770666843;
+        var_29 += (short)(Tester_Class_2.var_14 / Tester_Class_2.var_14);
+        if (var_31)
+        {
+            var_30 = var_32;
+        }
+        else
+        {
+            double var_36;
+        }
+        if (true)
+        {
+            var_30 -= 2.1474216E38F;
+        }
+        else
+        {
+            var_29 += 'f';
+        }
+        var_29 -= Tester_Class_2.var_14;
+        if (false)
+        {
+            arg_0.var_1 = arg_0;
+        }
+        else
+        {
+            arg_0 = (var_28 = (var_28 = arg_0));
+        }
+        {
+            Tester_Class_2.var_13 = 'p';
+        }
+        var_29 = ~Tester_Class_2.var_14 % 'y';
+        switch (var_30 >>>= var_30)
+        {
+            case 115:
+
+        }
+        arg_0 = arg_0;
+        var_31 ^= (var_31 = true);
+        return "".charAt(~var_32) >> ((var_31 &= true) ? var_30 : var_32);
+    }
+
+    protected double func_3(boolean[] arg_0, double arg_1, long[][] arg_2)
+    {
+        switch (var_31 ? (short)(var_32 / (arg_1 /= (int)(arg_1 *= (Tester_Class_2.var_13 = ']')))) : (var_30 ^= + +Tester_Class_2.var_14 * (+ +3075166460237931520L / '[')))
+        {
+            case 31:
+
+            case 118:
+
+        }
+        Tester_Class_2.var_13 = 'm';
+        "mwkh".indexOf("hdgiquve", (new char[var_32])[var_30 &= 'S'] % var_30);
+        final boolean var_37 = false;
+        char var_38 = 'F';
+        var_28 = (new Tester_Class_2[var_30][var_30])[var_30 *= var_38][var_32];
+        new Tester_Class_0().var_1 = new char[var_32][var_30];
+        var_30 &= var_30;
+        var_31 |= (var_31 |= true);
+        int var_39 = 1769831681;
+        final Tester_Class_2 var_40 = (var_31 |= false ? var_31 : var_37) ? (Tester_Class_2)((new Object[var_30][var_30][var_32])[var_30 <<= var_30])[var_30][var_30++] : (Tester_Class_2)new Tester_Class_0();
+        var_30 -= +var_30;
+        "dvmuim".replaceFirst("clmisuxu", "".toLowerCase() + "xi");
+        var_39 = var_38 - (short)585806817;
+        arg_1 += (double)(short)(6.4329855E37F / var_32 * (var_38 += 'w'));
+        ++var_39;
+        var_40.var_1 = (var_28 = (var_28 = var_40));
+        var_29 /= 3.5705444317400964E306;
+        Tester_Interface_1 var_41;
+        return arg_1;
+    }
+
+    final char func_4(final long arg_0, int arg_1, final int arg_2)
+    {
+        {
+            Tester_Class_2.var_13 = 'D';
+            var_31 = false;
+        }
+        if (var_31)
+        {
+            var_30--;
+            Tester_Class_0 var_42 = var_28 = (new Tester_Class_0[var_32])[var_32];
+        }
+        else
+        {
+            Tester_Class_2.var_13 = (Tester_Class_2.var_13 = 'H');
+        }
+        var_28 = (Tester_Class_2)(new Tester_Class_2().var_1 = (var_28 = (new Tester_Class_0[var_30])[var_30]));
+        arg_1 &= var_32;
+        --var_30;
+        return Tester_Class_2.var_13 = 'n';
+    }
+
+    final static Object func_5()
+    {
+        var_28 = (Tester_Class_2)(! (var_31 |= true & var_31) ? (new Tester_Class_0[var_30])[var_30] : (var_28 = (new Tester_Class_0[var_30])[var_30]));
+        var_31 |= false;
+        return var_31 ? (((Tester_Class_2)(new Object[var_30])[var_30]).var_1 = (new Tester_Class_0[var_30 /= 1366944127])[var_30]) : (new Tester_Class_0[var_30][var_30])[var_30 += 1.4070924450257891E307][var_30];
+    }
+
+    static Tester_Class_2 func_6(final Object arg_0)
+    {
+        var_28 = (var_31 ^= true) ? (Tester_Class_2)arg_0 : (Tester_Class_2)arg_0;
+        ((new Tester[--var_30])[var_30]).var_29 -= -3.0029087E38F * (Tester_Class_2.var_13 = (Tester_Class_2.var_13 = 'k'));
+        var_28 = (Tester_Class_2)(var_28 = (var_28 = (var_28 = (Tester_Class_0)arg_0)));
+        return false ? new Tester_Class_2() : new Tester_Class_2();
+    }
+
+    private static Tester_Interface_1 func_7(byte arg_0, Tester_Class_2 arg_1, final int arg_2, char arg_3)
+    {
+        {
+            var_31 = var_31;
+            var_31 |= (var_31 &= (var_31 |= !true));
+            arg_0 += Tester_Class_2.var_14;
+        }
+        var_30 = (var_30 *= ((new Tester[arg_0 ^= 1039546367])[arg_0]).var_32);
+        arg_1.var_1 = (var_31 ^= (var_31 &= !var_31 && !var_31)) ? (arg_1 = (arg_1 = arg_1)) : (new Tester_Class_0[arg_0++][arg_0])[arg_0][arg_0];
+        arg_1.var_1 = var_31 ? "jpmg" : "epwvupaqp";
+        var_28 = arg_1;
+        if (false)
+        {
+            arg_1 = arg_1;
+        }
+        else
+        {
+            arg_3 += var_30 % -9.298157E37F;
+        }
+        arg_1.var_1 = ((var_28 = (var_28 = arg_1)).var_1 = ((var_28 = arg_1).var_1 = "rlmf"));
+        var_28 = (arg_1 = arg_1);
+        arg_1 = arg_1;
+        {
+            var_31 = true;
+        }
+        (arg_1 = arg_1).var_1 = (arg_1.var_1 = (arg_1 = arg_1));
+        final short[] var_43 = new short[(var_31 &= false) ? arg_0 : var_30];
+        final short var_44 = 18087;
+        return false ? (new Tester_Interface_1[var_30 %= Tester_Class_2.var_14])[arg_0 -= 8.913955E37F * +arg_0] : (new Tester_Interface_1[var_30])[var_30];
+    }
+
+    private static float func_8(final Object[] arg_0, final byte arg_1, Tester_Class_0[] arg_2)
+    {
+        ((new Tester_Class_2[var_30 /= -2.37832E38F])[((new Tester[arg_1])[(new byte[arg_1])[arg_1]]).var_32]).var_1 = new Tester_Interface_1[arg_1];
+        if (var_31)
+        {
+            var_28 = (Tester_Class_2)(var_28 = arg_2[var_30]);
+        }
+        else
+        {
+            var_30 -= Tester_Class_2.var_14;
+            final int var_45 = 1864933386;
+            final Tester_Class_0 var_46 = var_28 = (new Tester_Class_2[arg_1][var_30 |= Tester_Class_2.var_14])[((new Tester[arg_1][var_30])[var_30][var_30]).var_32][arg_1];
+            var_31 &= (var_31 ^= false);
+            var_30 += (false ? 2.7581227E37F : + +1.8832631E38F) * ('P' * -1.9479086E38F);
+        }
+        (var_28 = (Tester_Class_2)arg_2[arg_1]).var_1 = (new Tester_Class_2[var_30][arg_1][arg_1])[arg_1];
+        ++var_30;
+        (var_28 = (new Tester_Class_2[var_30])[arg_1]).var_1 = false ? (new Tester_Class_0[var_30][var_30])[var_30][arg_1] : arg_2[var_30];
+        var_31 |= false;
+        ((new Tester[arg_1][var_30 >>>= (char)1981599])[arg_1][arg_1]).var_29 = false ^ (var_31 = var_31) ? (Tester_Class_2.var_13 = "nes".charAt(1080898679)) : - (var_30 %= 'n') ^ arg_1;
+        {
+            ((new Tester[arg_1])[var_30]).var_29 = (short)(Tester_Class_2.var_13 = (Tester_Class_2.var_13 = 'h'));
+        }
+        Tester_Class_2.var_13 = 'j';
+        ((new Tester_Class_2[arg_1])[var_30]).var_1 = new byte[var_30];
+        var_31 ^= (var_31 ^= !false);
+        "wcbi".toString();
+        final byte var_47 = var_30;
+        if (true)
+        {
+            "mpbkilw".substring(199662864);
+        }
+        else
+        {
+            var_30++;
+        }
+        Tester_Class_2.var_13 = '`';
+        "yujypq".indexOf("crve" + "inmvh", false ? ~arg_1 : "vukbkc".charAt(528096652));
+        Tester_Class_2 var_48 = (Tester_Class_2)((!var_31 & (var_31 ^= false ^ !true) ? false | !true : false) ? (var_28 = (Tester_Class_2)arg_0[var_30]) : (new Tester_Class_2[arg_1])[var_30]);
+        return (float)(var_31 ^ var_31 ? (var_30 ^= (short)((new Tester[var_30])[var_30]).var_29) : (var_30 /= - -5.917837279005691E307 - - +3.2004715720509636E306));
+    }
+
+    final Tester_Class_0 func_9()
+    {
+        var_30 += -3531557622894482432L / ~var_30;
+        var_28 = (var_28 = (new Tester_Class_2[var_30 += + -7.0203367E37F])[var_30]);
+        var_31 ^= ! !false ^ false;
+        if (true)
+        {
+            byte[] var_49;
+            var_31 &= true;
+            short var_50 = 14869;
+        }
+        else
+        {
+            (((new Tester[var_32][var_30][var_32])[var_30])[var_32][var_30]).var_29 *= 'h';
+        }
+        final int var_51 = false ? +var_32 >>> ~var_30 : --var_30;
+        var_31 |= false;
+        return (new Tester_Class_0[var_32][var_32])[var_30][var_30];
+    }
+
+    public static Object func_10()
+    {
+        Tester_Class_2.var_13 = (Tester_Class_2.var_13 = 'O');
+        return ((Tester_Class_2)(new Object[--var_30])[var_30]).var_1 = (((Tester_Class_2)(new Object[var_30])[var_30]).var_1 = "iu");
+    }
+
+    protected byte func_11(final Tester_Interface_1[] arg_0)
+    {
+        {
+            --var_30;
+            var_29 *= (short)1749707986816114688L;
+            var_31 = (var_31 = (var_31 |= var_31));
+            var_30 -= 6.4575257E37F;
+        }
+        var_28 = (var_28 = func_9());
+        Tester_Class_2.var_13 = 'b';
+        var_30--;
+        var_28 = (var_28 = (var_28 = (var_28 = (Tester_Class_2)func_10())));
+        var_28 = (new Tester_Class_2[var_32])[var_30];
+        char var_52 = (var_31 = false) ? (char)+ +Tester_Class_2.var_14 : (Tester_Class_2.var_13 = (Tester_Class_2.var_13 = '_'));
+        if (false)
+        {
+            var_30 += (short)(var_32 + 840104459);
+        }
+        else
+        {
+            var_29 /= 2.5320765E38F;
+        }
+        if (true)
+        {
+            var_30 %= 379977167934025728L;
+        }
+        else
+        {
+            var_52 = var_52;
+        }
+        var_30 >>= ('A' ^ --var_30) & 'H';
+        Tester_Class_2 var_53;
+        final int var_54 = 771623383;
+        var_29 %= (+1.938582E37F - 'G') * ++var_30;
+        int var_55 = (short)6.234053079170724E306 - (int)'^' / ((var_31 &= (var_31 ^= var_31)) ? (short)var_30 : ++var_30);
+        var_55 >>>= var_55 / ~6865244393150017536L;
+        var_31 ^= !false;
+        return var_30 >>>= 4351766607072508928L >> func_0(var_32, var_31, 1.021781609675458E308);
+    }
+
+    public static String execute()
+    {
+        try {
+            Tester t = new Tester();
+            try { t.test(); }
+            catch(Throwable e) { }
+            try { return t.toString(); }
+            catch (Throwable e) { return "Error during result conversion to String"; }
+        } catch (Throwable e) { return "Error during test execution"; }
+    }
+
+    public static void main(String[] args)
+    {
+        try {
+            Tester t = new Tester();
+            try { t.test(); }
+            catch(Throwable e) { }
+            try { System.out.println(t); }
+            catch(Throwable e) { }
+        } catch (Throwable e) { }
+    }
+
+    private void test()
+    {
+        {
+            ((Tester_Class_2)(Tester_Class_0)((var_31 = true) ^ (var_31 |= false & true) ? func_10() : new Tester_Class_2[var_32])).var_1 = ((var_28 = new Tester_Class_0()).var_1 = (new Tester_Class_0().var_1 = new Tester_Class_2()));
+        }
+        new String();
+        Tester_Class_2.var_13 = '[';
+        var_28 = (Tester_Class_2)(((var_31 ^= true) ? func_9() : new Tester_Class_0()).var_1 = new Tester_Class_2());
+        var_28 = new Tester_Class_0();
+        new String();
+        {
+            if ((new boolean[var_30])[var_30] & 732877932 == 1.4654316E38F & "xpqy".replace(']', 'f').startsWith("pqrqunvfx") ? ((var_31 ^= (var_31 &= var_31)) ? !var_31 : (var_31 &= true)) : var_31)
+            {
+                var_31 &= var_31;
+            }
+            else
+            {
+                func_2(var_28 = new Tester_Class_0());
+            }
+            {
+                ((new Tester_Class_0[var_30][var_30])[var_30][var_30]).var_1 = "uwrbjvl";
+                var_28 = (Tester_Class_0)func_5();
+            }
+            Tester_Class_2.var_13 = 's';
+            Tester_Class_0 var_56 = var_28 = true ? func_6(func_5()) : (new Tester_Class_2[var_30][var_32])[var_32][var_32];
+            double var_57 = 0;
+            var_29 += 1024895641427426304L % ~ ~Tester_Class_2.var_14;
+            while ((true || (var_31 = var_31)) && var_57 < 12)
+            {
+                (false & !false ? var_56 : (var_56 = var_56)).var_1 = "vbc";
+                var_57++;
+                var_29 += func_0(var_30 /= (short)var_30 / var_32, false, var_57);
+                (var_31 ? (Tester_Class_2)var_56 : (new Tester_Class_2[var_30])[var_30]).var_1 = new double[var_31 ? (var_30 |= 177265600183083008L) : var_32];
+            }
+            switch (var_31 ^ var_31 | ! (var_31 = false) & (var_31 & false) ? (true ? (short)var_30 : func_0(var_30, true, var_57)) : func_0(var_30, var_31, var_29 /= 2.7203017E38F))
+            {
+                case 23:
+                    var_31 ^= true ? var_31 : var_31;
+                    break;
+
+                case 40:
+
+                default:
+
+                case 104:
+
+            }
+            Object var_58 = (var_31 ^= (var_31 ^= false) | (~3392263608888292352L < 1681682009 | var_31)) ? (((new Tester_Class_2[Tester_Class_2.func_5(Tester_Class_2.var_14, 3.3507317E38F, var_57)])[var_30 %= var_32]).var_1 = (var_56 = (Tester_Class_0)func_5())) : func_5();
+            (var_56 = (var_28 = (var_56 = func_6(var_58)))).var_1 = (((new Tester_Class_2[var_30])[var_30]).var_1 = new float[(byte)Tester_Class_2.var_14][var_32]);
+            new Tester_Class_2().var_1 = new double[var_30];
+            final Tester_Class_0 var_59 = var_28 = (!false & (false || (var_31 && !var_31) & false) ? var_31 : (var_31 |= !var_31)) ? (Tester_Class_2)(var_28 = new Tester_Class_2()) : (false ? new Tester_Class_2() : (Tester_Class_2)var_58);
+        }
+        var_30--;
+        {
+            var_29 += ~func_11(((new Tester_Interface_1[var_32][var_30][var_32])[var_30 ^= var_30])[var_32]);
+        }
+        float var_60 = 0F;
+        double var_61 = var_29;
+        do
+        {
+            long var_62;
+            var_60++;
+            "vcs".offsetByCodePoints((short)('w' | (short)var_30) & (new short[--var_30])[var_30], ((var_31 |= var_31) ^ (var_31 = var_31) ? var_32 : var_30) - (short)86413218);
+        } while (false && (var_60 < 100 && ((var_31 = false) ? var_31 : (var_31 ^= false)) & var_31));
+        long var_63 = 0L;
+        double var_64 = (var_31 ? (Tester_Class_2.var_13 = 'V') : 'e') - (var_29 = 'A') * (var_29 = var_30);
+        var_31 &= (short)+ var_30-- + var_30 <= var_60;
+        while (false && (var_63 < 23 && false))
+        {
+            var_30 >>= func_0(var_30, var_31, var_29) ^ ("".endsWith("mecvlajq" + "jhrbf") ? var_30 : (short)var_61);
+            var_63++;
+            var_28 = (Tester_Class_2)(var_28 = new Tester_Class_2());
+            new Tester_Class_0();
+        }
+        double var_65 = 0;
+        var_61 -= var_65;
+        for (((var_31 &= (var_31 ^= var_31)) | var_31 ? new Tester_Class_2() : new Tester_Class_2()).var_1 = ! (var_31 = false) && !var_31 ? func_10() : new Object[var_32][var_32]; var_31 | var_31 && (var_65 < 107 && (false ? !var_31 : (var_31 &= var_31))); var_30 *= Tester_Class_2.var_14)
+        {
+            var_28 = var_30 > (var_31 | true ? (Tester_Class_2.var_13 = (Tester_Class_2.var_13 = 'k')) : (Tester_Class_2.var_13 = (Tester_Class_2.var_13 = 'r'))) ? (Tester_Class_2)((var_28 = (Tester_Class_0)func_5()).var_1 = func_5()) : new Tester_Class_2();
+            var_65++;
+            var_29 = "efothsl".startsWith("qk") ? 3.2306712E37F : +1.1835607464479516E308;
+            new Tester_Class_2().var_1 = new Tester_Class_0();
+        }
+        double var_66 = 0;
+        func_6(((Tester_Class_2)((true ? (Tester_Class_2)func_10() : (Tester_Class_2)func_9()).var_1 = (var_28 = (Tester_Class_2)func_10()))).var_1 = "");
+        while (false | (new boolean[var_30][var_30])[var_30][var_32] && (var_66 < 104 && false))
+        {
+            ((var_31 ^= !false) ? "" : "slgr").toUpperCase();
+            var_66++;
+            var_28 = func_6(func_9().var_1 = func_10());
+            var_31 |= (var_31 |= true);
+        }
+        Tester_Class_2.var_13 = var_31 ? (Tester_Class_2.var_13 = 'Y') : (Tester_Class_2.var_13 = (Tester_Class_2.var_13 = (Tester_Class_2.var_13 = func_4(var_63, 137999726, 1870981930))));
+        int var_67 = 0;
+        final double var_68 = 9.955130040461458E307;
+        do
+        {
+            "".lastIndexOf(var_32 != (Tester_Class_2.var_13 = 'f') ? (Tester_Class_2.var_13 = 'C') : ~var_30, (char)3.187607E38F + (var_30 /= var_30));
+            var_67++;
+            Tester_Class_2.var_13 = (Tester_Class_2.var_13 = 'B');
+        } while (var_67 < 9 && var_31 ^ var_31);
+        int var_69 = 0;
+        (true ? func_6(func_10()) : (Tester_Class_2)func_9()).var_1 = ((var_28 = (var_28 = new Tester_Class_2())).var_1 = (func_6(new Tester_Class_2().var_1 = new Tester_Class_0()).var_1 = (Tester_Class_2)func_9()));
+        do
+        {
+            var_28 = (Tester_Class_2)(var_28 = (Tester_Class_0)(new Tester_Class_2().var_1 = "qs"));
+            var_69++;
+            var_31 ^= var_31;
+        } while (var_69 < 189);
+        (! (var_31 = true) | var_31 ? new Tester_Class_2() : (new Tester_Class_0[var_30])[var_30]).var_1 = (((new Tester_Class_2[var_30 ^= (short)var_30])[var_30]).var_1 = (var_31 ? var_31 : (var_31 |= false)) ? "lfhliyphg" : "impovq");
+        ((var_31 ? var_32 == (short)8901596111720974336L : 220705842 != var_60) ? (new Tester_Class_2[var_30])[var_32] : (new Tester_Class_2[var_30][var_32])[var_30][var_30]).var_1 = (var_28 = ((char)var_30 >= "pngjthlf".lastIndexOf("jjbuojp") & var_31 ? var_31 : var_31) ? (new Tester_Class_2[var_32])[var_30] : func_6(new Tester_Class_2().var_1 = new String[var_32]));
+        Tester_Class_2.var_13 = 'c';
+    }
+    public String toString()
+    {
+        String result =  "[\n";
+        result += "Tester.var_29 = "; result += Printer.print(var_29);
+        result += "\n";
+        result += "Tester.var_30 = "; result += Printer.print(var_30);
+        result += "\n";
+        result += "Tester.var_32 = "; result += Printer.print(var_32);
+        result += "\n";
+        result += "Tester.var_31 = "; result += Printer.print(var_31);
+        result += "\n";
+        result += "Tester.var_28 = "; result += Printer.print(var_28);
+        result += "";
+        result += "\n]";
+        return result;
+    }
+    static class Printer
+    {
+        public static String print(boolean arg) { return String.valueOf(arg); }
+        public static String print(byte arg)    { return String.valueOf(arg); }
+        public static String print(short arg)   { return String.valueOf(arg); }
+        public static String print(char arg)    { return String.valueOf((int)arg); }
+        public static String print(int arg)     { return String.valueOf(arg); }
+        public static String print(long arg)    { return String.valueOf(arg); }
+        public static String print(float arg)   { return String.valueOf(arg); }
+        public static String print(double arg)  { return String.valueOf(arg); }
+
+
+        public static String print(Object arg)
+        {
+            return print_r(new java.util.Stack(), arg);
+        }
+
+        private static String print_r(java.util.Stack visitedObjects, Object arg)
+        {
+            String result = "";
+            if (arg == null)
+                result += "null";
+            else
+            if (arg.getClass().isArray())
+            {
+                for (int i = 0; i < visitedObjects.size(); i++)
+                    if (visitedObjects.elementAt(i) == arg) return "<recursive>";
+
+                visitedObjects.push(arg);
+
+                final String delimiter = ", ";
+                result += "[";
+
+                if (arg instanceof Object[])
+                {
+                    Object[] array = (Object[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print_r(visitedObjects, array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof boolean[])
+                {
+                    boolean[] array = (boolean[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof byte[])
+                {
+                    byte[] array = (byte[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof short[])
+                {
+                    short[] array = (short[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof char[])
+                {
+                    char[] array = (char[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof int[])
+                {
+                     int[] array = (int[]) arg;
+                     for (int i = 0; i < array.length; i++)
+                     {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                     }
+                }
+                else
+                if (arg instanceof long[])
+                {
+                    long[] array = (long[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof float[])
+                {
+                    float[] array = (float[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+                else
+                if (arg instanceof double[])
+                {
+                    double[] array = (double[]) arg;
+                    for (int i = 0; i < array.length; i++)
+                    {
+                        result += print(array[i]);
+                        if (i < array.length - 1) result += delimiter;
+                    }
+                }
+
+                result += "]";
+                visitedObjects.pop();
+
+            } else
+            {
+                result += arg.toString();
+            }
+
+            return result;
+        }
+    }
+}
+
+
--- a/make/jprt.config	Wed Jul 09 10:04:09 2008 -0700
+++ b/make/jprt.config	Wed Jul 05 16:38:46 2017 +0200
@@ -142,9 +142,15 @@
 	solaris_arch=i386
     fi
 
-    # Get the SS11 compilers into path (make sure it matches ALT setting)
-    compiler_path=${jdk_devtools}/${solaris_arch}/SUNWspro/SS11/bin
-    compiler_name=SS11
+    # Get the compilers into path (make sure it matches ALT setting)
+    if [ "${JPRT_SOLARIS_COMPILER_NAME}" != "" ] ; then
+        compiler_name=${JPRT_SOLARIS_COMPILER_NAME}
+    else
+        # FIXUP: Change to SS12 when validated
+	#compiler_name=SS12
+	compiler_name=SS11
+    fi
+    compiler_path=${jdk_devtools}/${solaris_arch}/SUNWspro/${compiler_name}/bin
     ALT_COMPILER_PATH="${compiler_path}"
     export ALT_COMPILER_PATH
     dirMustExist "${compiler_path}" ALT_COMPILER_PATH