6604014: add support for ideal graph visualizer
authornever
Mon, 23 Jun 2008 18:21:18 -0700
changeset 766 d3e5868ddb33
parent 765 e0692d3d8863
child 767 64fb1fd7186d
6604014: add support for ideal graph visualizer Reviewed-by: kvn, jrose
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/removeall.gif
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/save.gif
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/saveall.gif
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/structure.gif
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/images/structured.gif
hotspot/src/share/tools/IdealGraphVisualizer/Coordinator/src/com/sun/hotspot/igv/coordinator/layer.xml
hotspot/src/share/tools/IdealGraphVisualizer/Data/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/Data/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/platform.properties
hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/Data/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEvent.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedEventProvider.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/ChangedListener.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Event.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/GraphDocument.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Group.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlock.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBlockEdge.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputBytecode.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputEdge.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputGraph.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputMethod.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/InputNode.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Pair.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Properties.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/Property.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Parser.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/Printer.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLParser.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/serialization/XMLWriter.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GraphViewer.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupCallback.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupOrganizer.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/GroupReceiver.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/InputGraphProvider.java
hotspot/src/share/tools/IdealGraphVisualizer/Data/src/com/sun/hotspot/igv/data/services/Scheduler.java
hotspot/src/share/tools/IdealGraphVisualizer/Difference/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/Difference/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/platform.properties
hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/Difference/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/Difference/src/com/sun/hotspot/igv/difference/Difference.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/Filter/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/platform.properties
hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/Filter/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/AbstractFilter.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ColorFilter.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CombineFilter.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ConnectionFilter.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/CustomFilter.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/EditFilterDialog.form
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/EditFilterDialog.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/Filter.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChain.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterChainProvider.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/FilterSetting.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/JavaSE6ScriptEngine.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/NullScriptEngine.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveFilter.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveInputsFilter.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/RemoveSelfLoopsFilter.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/ScriptEngineAbstraction.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/SplitFilter.java
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/helper.js
hotspot/src/share/tools/IdealGraphVisualizer/Filter/src/com/sun/hotspot/igv/filter/layer.xml
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/META-INF/services/com.sun.hotspot.igv.filter.FilterChainProvider
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckListView.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNode.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckNodeListModel.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/CheckRenderer.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterChainProviderImplementation.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterNode.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.form
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponent.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponentSettings.xml
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/FilterTopComponentWstcref.xml
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/FilterAction.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterDownAction.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/MoveFilterUpAction.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/NewFilterAction.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterAction.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/RemoveFilterSettingsAction.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/actions/SaveFilterSettingsAction.java
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/customRightTopWsmode.xml
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/add.gif
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/delete.gif
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/down.gif
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/minus.gif
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/plus.gif
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/images/up.gif
hotspot/src/share/tools/IdealGraphVisualizer/FilterWindow/src/com/sun/hotspot/igv/filterwindow/layer.xml
hotspot/src/share/tools/IdealGraphVisualizer/Graph/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/Graph/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/platform.properties
hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/Graph/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/AndSelector.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Block.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Connection.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Diagram.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Figure.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InputSlot.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/InvertSelector.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/MatcherSelector.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OrSelector.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/OutputSlot.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/PredecessorSelector.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Selector.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Slot.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/Source.java
hotspot/src/share/tools/IdealGraphVisualizer/Graph/src/com/sun/hotspot/igv/graph/SuccessorSelector.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/platform.properties
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterEdge.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterIngoingConnection.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterInputSlotNode.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterNode.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterOutgoingConnection.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/ClusterOutputSlotNode.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Edge.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Graph.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/InterClusterConnection.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Node.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/OldHierarchicalLayoutManager.java
hotspot/src/share/tools/IdealGraphVisualizer/HierarchicalLayout/src/com/sun/hotspot/igv/hierarchicallayout/Timing.java
hotspot/src/share/tools/IdealGraphVisualizer/Layout/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/Layout/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/platform.properties
hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/Layout/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Cluster.java
hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutGraph.java
hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/LayoutManager.java
hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Link.java
hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Port.java
hotspot/src/share/tools/IdealGraphVisualizer/Layout/src/com/sun/hotspot/igv/layout/Vertex.java
hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupReceiver
hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Client.java
hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/Server.java
hotspot/src/share/tools/IdealGraphVisualizer/NetworkConnection/src/com/sun/hotspot/igv/connection/layer.xml
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/META-INF/services/com.sun.hotspot.igv.filter.ScriptEngineAbstraction
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/RhinoScriptEngine.java
hotspot/src/share/tools/IdealGraphVisualizer/RhinoScriptEngineProxy/src/com/sun/hotspot/igv/rhino/layer.xml
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/platform.properties
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/META-INF/services/com.sun.hotspot.igv.data.services.GroupOrganizer
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/META-INF/services/com.sun.hotspot.igv.data.services.Scheduler
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/JavaGroupOrganizer.java
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/ServerCompilerScheduler.java
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/color.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/combine.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/difference.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/extendedColor.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/linestyle.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/matchingFlags.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/onlyControlFlow.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/register.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/remove.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeMemory.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeRootInputs.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeSafepointInputs.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/removeSelfLoops.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/filters/split.filter
hotspot/src/share/tools/IdealGraphVisualizer/ServerCompiler/src/com/sun/hotspot/igv/servercompiler/layer.xml
hotspot/src/share/tools/IdealGraphVisualizer/Settings/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/Settings/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/platform.properties
hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/Settings/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/Settings.java
hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsCategory.java
hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewOptionsPanelController.java
hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewPanel.form
hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/ViewPanel.java
hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/layer.xml
hotspot/src/share/tools/IdealGraphVisualizer/Settings/src/com/sun/hotspot/igv/settings/settings.gif
hotspot/src/share/tools/IdealGraphVisualizer/Util/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/Util/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/platform.properties
hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/Util/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/BoundedZoomAction.java
hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ColorIcon.java
hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ContextAction.java
hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/DoubleClickAction.java
hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/DoubleClickHandler.java
hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ExtendedSatelliteComponent.java
hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/ExtendedSelectAction.java
hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/PropertiesSheet.java
hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSlider.java
hotspot/src/share/tools/IdealGraphVisualizer/Util/src/com/sun/hotspot/igv/util/RangeSliderModel.java
hotspot/src/share/tools/IdealGraphVisualizer/View/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/View/manifest.mf
hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/platform.properties
hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/project.xml
hotspot/src/share/tools/IdealGraphVisualizer/View/nbproject/suite.properties
hotspot/src/share/tools/IdealGraphVisualizer/View/src/META-INF/services/com.sun.hotspot.igv.data.services.GraphViewer
hotspot/src/share/tools/IdealGraphVisualizer/View/src/META-INF/services/com.sun.hotspot.igv.data.services.InputGraphProvider
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/BoundedZoomAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ConnectionAnchor.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramScene.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/DiagramViewModel.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorInputGraphProvider.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.form
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/EditorTopComponent.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExportCookie.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedPanAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/ExtendedSatelliteComponent.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/FindPanel.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/GraphViewerImplementation.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/PreferenceConstants.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/SlotLayout.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/EnableBlockLayoutAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandPredecessorsAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExpandSuccessorsAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExportAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ExtractAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/HideAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/MouseOverAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/NextDiagramAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/NodeFindAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/OverviewAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PredSuccAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/PrevDiagramAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ShowAllAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ZoomInAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/actions/ZoomOutAction.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/blocks.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/expand.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/export.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/extract.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/hide.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/next_diagram.png
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/overview.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/predsucc.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/prev_diagram.png
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/search.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoomin.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/images/zoomout.gif
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/layer.xml
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/BlockWidget.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/DiagramConnectionWidget.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/FigureWidget.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/InputSlotWidget.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/LineWidget.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/MultiConnectionWidget.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/OutputSlotWidget.java
hotspot/src/share/tools/IdealGraphVisualizer/View/src/com/sun/hotspot/igv/view/widgets/SlotWidget.java
hotspot/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/frame.gif
hotspot/src/share/tools/IdealGraphVisualizer/branding/core/core.jar/org/netbeans/core/startup/splash.gif
hotspot/src/share/tools/IdealGraphVisualizer/branding/modules/org-netbeans-core-windows.jar/org/netbeans/core/windows/view/ui/Bundle.properties
hotspot/src/share/tools/IdealGraphVisualizer/build.xml
hotspot/src/share/tools/IdealGraphVisualizer/nbproject/build-impl.xml
hotspot/src/share/tools/IdealGraphVisualizer/nbproject/genfiles.properties
hotspot/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties
hotspot/src/share/tools/IdealGraphVisualizer/nbproject/project.properties
hotspot/src/share/tools/IdealGraphVisualizer/nbproject/project.xml
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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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/RhinoScriptEngineProxy/build.xml	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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	Mon Jun 23 18:21:18 2008 -0700
@@ -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>