changeset 2850:7474789a8120

Merge
author Gilles Duboscq <gilles.duboscq@oracle.com>
date Tue, 07 Jun 2011 11:19:01 +0200
parents 463657856f86 (current diff) e55543ff91fd (diff)
children 14708c03abba
files graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java graal/GraalGraph/src/com/oracle/graal/graph/EndNode.java
diffstat 56 files changed, 2620 insertions(+), 319 deletions(-) [+]
line wrap: on
line diff
--- a/graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/C1XCompilation.java	Tue Jun 07 11:19:01 2011 +0200
@@ -25,13 +25,12 @@
 
 import java.util.*;
 
-import com.oracle.graal.graph.*;
 import com.oracle.max.asm.*;
 import com.sun.c1x.alloc.*;
 import com.sun.c1x.asm.*;
 import com.sun.c1x.debug.*;
 import com.sun.c1x.gen.*;
-import com.sun.c1x.gen.LIRGenerator.*;
+import com.sun.c1x.gen.LIRGenerator.DeoptimizationStub;
 import com.sun.c1x.graph.*;
 import com.sun.c1x.lir.*;
 import com.sun.c1x.observer.*;
@@ -56,7 +55,7 @@
     public final CiAssumptions assumptions = new CiAssumptions();
     public final FrameState placeholderState;
 
-    public Graph graph = new Graph();
+    public CompilerGraph graph = new CompilerGraph();
 
     private boolean hasExceptionHandlers;
     private final C1XCompilation parent;
@@ -96,7 +95,7 @@
         this.method = method;
         this.stats = stats == null ? new CiStatistics() : stats;
         this.registerConfig = method == null ? compiler.globalStubRegisterConfig : runtime.getRegisterConfig(method);
-        this.placeholderState = method != null && method.minimalDebugInfo() ? new FrameState(0, 0, 0, 0, graph) : null;
+        this.placeholderState = method != null && method.minimalDebugInfo() ? new FrameState(method, 0, 0, 0, 0, graph) : null;
 
         if (compiler.isObserved()) {
             compiler.fireCompilationStarted(new CompilationEvent(this));
--- a/graal/GraalCompiler/src/com/sun/c1x/C1XOptions.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/C1XOptions.java	Tue Jun 07 11:19:01 2011 +0200
@@ -90,6 +90,7 @@
     public static boolean TraceRelocation                    = ____;
     public static boolean TraceLIRVisit                      = ____;
     public static boolean TraceAssembler                     = ____;
+    public static boolean TraceInlining                      = ____;
     public static int     TraceBytecodeParserLevel           = 0;
     public static boolean QuietBailout                       = ____;
 
--- a/graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/alloc/LinearScan.java	Tue Jun 07 11:19:01 2011 +0200
@@ -1884,7 +1884,7 @@
         }
     }
 
-    CiFrame computeFrameForState(int opId, FrameState state, CiBitMap frameRefMap) {
+    CiFrame computeFrameForState(FrameState state, int opId, CiBitMap frameRefMap) {
         CiValue[] values = new CiValue[state.valuesSize() + state.locksSize()];
         int valueIndex = 0;
 
@@ -1909,8 +1909,11 @@
                 }
             }
         }
-
-        return new CiFrame(null, ir.compilation.method, state.bci, values, state.localsSize(), state.stackSize(), state.locksSize());
+        CiFrame caller = null;
+        if (state.outerFrameState() != null) {
+            caller = computeFrameForState(state.outerFrameState(), opId, frameRefMap);
+        }
+        return new CiFrame(caller, state.method, state.bci, values, state.localsSize(), state.stackSize(), state.locksSize());
     }
 
     private void computeDebugInfo(IntervalWalker iw, LIRInstruction op) {
@@ -1946,7 +1949,7 @@
         if (C1XOptions.TraceLinearScanLevel >= 3) {
             TTY.println("creating debug information at opId %d", opId);
         }
-        return computeFrameForState(opId, state, frameRefMap);
+        return computeFrameForState(state, opId, frameRefMap);
     }
 
     private void assignLocations(List<LIRInstruction> instructions, IntervalWalker iw) {
--- a/graal/GraalCompiler/src/com/sun/c1x/debug/GraphvizPrinterObserver.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/debug/GraphvizPrinterObserver.java	Tue Jun 07 11:19:01 2011 +0200
@@ -99,7 +99,6 @@
             printer.addOmittedClass(FrameState.class);
         }
         printer.addClassColor(StartNode.class, "snow3");
-        printer.addClassColor(EndNode.class, "snow3");
         printer.addClassColor(LoopBegin.class, "skyblue");
         printer.addClassColor(LoopEnd.class, "skyblue3");
         printer.addClassColor(Unwind.class, "red");
--- a/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/gen/LIRGenerator.java	Tue Jun 07 11:19:01 2011 +0200
@@ -299,7 +299,7 @@
         if (Modifier.isSynchronized(compilation.method.accessFlags())) {
             bci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
         }
-        FrameState fs = new FrameState(bci, compilation.method.maxLocals(), 0, 0, compilation.graph);
+        FrameState fs = new FrameState(compilation.method, bci, compilation.method.maxLocals(), 0, 0, compilation.graph);
         for (Node node : compilation.graph.start().usages()) {
             if (node instanceof Local) {
                 Local local = (Local) node;
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/BlockMap.java	Tue Jun 07 11:19:01 2011 +0200
@@ -401,15 +401,6 @@
 
     private ExceptionBlock unwindBlock;
 
-    private ExceptionBlock makeUnwind() {
-        if (unwindBlock == null) {
-            unwindBlock = new ExceptionBlock();
-            unwindBlock.startBci = -1;
-            unwindBlock.endBci = -1;
-        }
-        return unwindBlock;
-    }
-
     private Block makeExceptionDispatch(List<RiExceptionHandler> handlers, int index) {
         RiExceptionHandler handler = handlers.get(index);
         if (handler.isCatchAll()) {
@@ -422,14 +413,10 @@
             block.endBci = -1;
             block.handler = handler;
             block.successors.add(blockMap[handler.handlerBCI()]);
-            Block next;
             if (index < handlers.size() - 1) {
-                next = makeExceptionDispatch(handlers, index + 1);
-            } else {
-                next = makeUnwind();
+                block.next = makeExceptionDispatch(handlers, index + 1);
+                block.successors.add(block.next);
             }
-            block.successors.add(next);
-            block.next = next;
             exceptionDispatch.put(handler, block);
         }
         return block;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/CompilerGraph.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.sun.c1x.graph;
+
+import com.oracle.graal.graph.*;
+import com.sun.c1x.ir.*;
+
+
+public class CompilerGraph extends Graph {
+
+    private Return returnSingleton;
+    private Unwind unwindSingleton;
+
+    public Return createReturn(Value result) {
+        assert returnSingleton == null;
+        returnSingleton = new Return(result, this);
+        return returnSingleton;
+    }
+
+    public Return getReturn() {
+        return returnSingleton;
+    }
+
+    public Unwind createUnwind(Value exception) {
+        assert unwindSingleton == null;
+        unwindSingleton = new Unwind(exception, this);
+        return unwindSingleton;
+    }
+
+    public Unwind getUnwind() {
+        return unwindSingleton;
+    }
+}
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/GraphBuilder.java	Tue Jun 07 11:19:01 2011 +0200
@@ -61,20 +61,29 @@
      */
     public static final int TRACELEVEL_STATE = 2;
 
-    private final IR ir;
     private final C1XCompilation compilation;
+    private final CompilerGraph graph;
+
     private final CiStatistics stats;
+    private final RiRuntime runtime;
+    private final RiMethod method;
+    private final RiConstantPool constantPool;
 
     private final BytecodeStream stream;           // the bytecode stream
+    private final LogStream log;
+    private final FrameStateBuilder frameState;          // the current execution state
+
     // bci-to-block mapping
     private Block[] blockFromBci;
     private ArrayList<Block> blockList;
 
-    private Block syncBlock;
+    private int nextBlockNumber;
+
+    private Value methodSynchronizedObject;
     private CiExceptionHandler syncHandler;
 
-    // the constant pool
-    private final RiConstantPool constantPool;
+    private Block unwindBlock;
+    private Block returnBlock;
 
     // the worklist of blocks, sorted by depth first number
     private final PriorityQueue<Block> workList = new PriorityQueue<Block>(10, new Comparator<Block>() {
@@ -83,14 +92,11 @@
         }
     });
 
-    private FrameStateBuilder frameState;          // the current execution state
     private Instruction lastInstr;                 // the last instruction added
 
-    private final LogStream log;
+    private final Set<Block> blocksOnWorklist = new HashSet<Block>();
+    private final Set<Block> blocksVisited = new HashSet<Block>();
 
-    private Value rootMethodSynchronizedObject;
-
-    private final Graph graph;
 
     /**
      * Creates a new, initialized, {@code GraphBuilder} instance for a given compilation.
@@ -99,15 +105,18 @@
      * @param ir the IR to build the graph into
      * @param graph
      */
-    public GraphBuilder(C1XCompilation compilation, IR ir, Graph graph) {
+    public GraphBuilder(C1XCompilation compilation, RiMethod method, CompilerGraph graph) {
         this.compilation = compilation;
-        this.ir = ir;
+        this.graph = graph;
+
+        this.runtime = compilation.runtime;
+        this.method = method;
         this.stats = compilation.stats;
-        log = C1XOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null;
-        stream = new BytecodeStream(compilation.method.code());
-        constantPool = compilation.runtime.getConstantPool(compilation.method);
-        this.graph = graph;
-        this.frameState = new FrameStateBuilder(compilation.method, graph);
+        this.log = C1XOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null;
+        this.stream = new BytecodeStream(method.code());
+
+        this.constantPool = runtime.getConstantPool(method);
+        this.frameState = new FrameStateBuilder(method, graph);
     }
 
     /**
@@ -115,20 +124,18 @@
      * @param scope the top IRScope
      */
     public void build() {
-        RiMethod rootMethod = compilation.method;
-
         if (log != null) {
             log.println();
-            log.println("Compiling " + compilation.method);
+            log.println("Compiling " + method);
         }
 
         // 2. compute the block map, setup exception handlers and get the entrypoint(s)
-        BlockMap blockMap = compilation.getBlockMap(rootMethod);
+        BlockMap blockMap = compilation.getBlockMap(method);
 
         blockList = new ArrayList<Block>(blockMap.blocks);
-        blockFromBci = new Block[rootMethod.code().length];
+        blockFromBci = new Block[method.code().length];
         for (int i = 0; i < blockList.size(); i++) {
-            int blockID = ir.nextBlockNumber();
+            int blockID = nextBlockNumber();
             assert blockID == i;
             Block block = blockList.get(i);
             if (block.startBci >= 0) {
@@ -142,18 +149,15 @@
         lastInstr = createTarget(startBlock, frameState);
         graph.start().setStart(lastInstr);
 
-        if (isSynchronized(rootMethod.accessFlags())) {
+        if (isSynchronized(method.accessFlags())) {
             // 4A.1 add a monitor enter to the start block
-            rootMethodSynchronizedObject = synchronizedObject(frameState, compilation.method);
-            genMonitorEnter(rootMethodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI);
+            methodSynchronizedObject = synchronizedObject(frameState, method);
+            genMonitorEnter(methodSynchronizedObject, Instruction.SYNCHRONIZATION_ENTRY_BCI);
             // 4A.2 finish the start block
             finishStartBlock(startBlock);
 
             // 4A.3 setup an exception handler to unlock the root method synchronized object
-            syncBlock = nextBlock(Instruction.SYNCHRONIZATION_ENTRY_BCI);
-            markOnWorkList(syncBlock);
-
-            syncHandler = new CiExceptionHandler(0, rootMethod.code().length, Instruction.SYNCHRONIZATION_ENTRY_BCI, 0, null);
+            syncHandler = new CiExceptionHandler(0, method.code().length, Instruction.SYNCHRONIZATION_ENTRY_BCI, 0, null);
         } else {
             // 4B.1 simply finish the start block
             finishStartBlock(startBlock);
@@ -165,11 +169,7 @@
         addToWorkList(blockFromBci[0]);
         iterateAllBlocks();
 
-        if (syncBlock != null && syncBlock.firstInstruction != null) {
-            // generate unlocking code if the exception handler is reachable
-            fillSyncHandler(rootMethodSynchronizedObject, syncBlock);
-        }
-
+        // remove Placeholders
         for (Node n : graph.getNodes()) {
             if (n instanceof Placeholder) {
                 Placeholder p = (Placeholder) n;
@@ -181,21 +181,13 @@
             }
         }
 
-        for (Node n : graph.getNodes()) {
-            assert !(n instanceof Placeholder);
-        }
-
-
+        // remove FrameStates
         for (Node n : graph.getNodes()) {
             if (n instanceof FrameState) {
                 boolean delete = false;
                 if (n.usages().size() == 0 && n.predecessors().size() == 0) {
                     delete = true;
                 }
-//                if (n.predecessors().size() == 0 && n.usages().size() == 1 && n.usages().get(0) instanceof BlockBegin) {
-//                    n.usages().get(0).inputs().replace(n, null);
-//                    delete = true;
-//                }
                 if (delete) {
                     n.delete();
                 }
@@ -203,15 +195,40 @@
         }
     }
 
+    private int nextBlockNumber() {
+        stats.blockCount++;
+        return nextBlockNumber++;
+    }
+
     private Block nextBlock(int bci) {
         Block block = new Block();
         block.startBci = bci;
         block.endBci = bci;
-        block.blockID = ir.nextBlockNumber();
+        block.blockID = nextBlockNumber();
         return block;
     }
 
-    private Set<Block> blocksOnWorklist = new HashSet<Block>();
+    private Block unwindBlock() {
+        if (unwindBlock == null) {
+            unwindBlock = new Block();
+            unwindBlock.startBci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
+            unwindBlock.endBci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
+            unwindBlock.blockID = nextBlockNumber();
+            addToWorkList(unwindBlock);
+        }
+        return unwindBlock;
+    }
+
+    private Block returnBlock() {
+        if (returnBlock == null) {
+            returnBlock = new Block();
+            returnBlock.startBci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
+            returnBlock.endBci = Instruction.SYNCHRONIZATION_ENTRY_BCI;
+            returnBlock.blockID = nextBlockNumber();
+            addToWorkList(returnBlock);
+        }
+        return returnBlock;
+    }
 
     private void markOnWorkList(Block block) {
         blocksOnWorklist.add(block);
@@ -221,8 +238,6 @@
         return blocksOnWorklist.contains(block);
     }
 
-    private Set<Block> blocksVisited = new HashSet<Block>();
-
     private void markVisited(Block block) {
         blocksVisited.add(block);
     }
@@ -310,10 +325,6 @@
         }
     }
 
-    public RiMethod method() {
-        return compilation.method;
-    }
-
     public BytecodeStream stream() {
         return stream;
     }
@@ -342,7 +353,7 @@
         assert bci == Instruction.SYNCHRONIZATION_ENTRY_BCI || bci == bci() : "invalid bci";
 
         RiExceptionHandler firstHandler = null;
-        RiExceptionHandler[] exceptionHandlers = compilation.method.exceptionHandlers();
+        RiExceptionHandler[] exceptionHandlers = method.exceptionHandlers();
         // join with all potential exception handlers
         if (exceptionHandlers != null) {
             for (RiExceptionHandler handler : exceptionHandlers) {
@@ -376,7 +387,7 @@
                 assert isCatchAll(firstHandler);
                 int handlerBCI = firstHandler.handlerBCI();
                 if (handlerBCI == Instruction.SYNCHRONIZATION_ENTRY_BCI) {
-                    dispatchBlock = syncBlock;
+                    dispatchBlock = unwindBlock();
                 } else {
                     dispatchBlock = blockFromBci[handlerBCI];
                 }
@@ -404,7 +415,7 @@
     }
 
     private void genLoadConstant(int cpi) {
-        Object con = constantPool().lookupConstant(cpi);
+        Object con = constantPool.lookupConstant(cpi);
 
         if (con instanceof RiType) {
             // this is a load of class constant which might be unresolved
@@ -532,7 +543,7 @@
     private void genArithmeticOp(CiKind result, int opcode, CiKind x, CiKind y, boolean canTrap) {
         Value yValue = frameState.pop(y);
         Value xValue = frameState.pop(x);
-        Value result1 = append(new ArithmeticOp(opcode, result, xValue, yValue, isStrict(method().accessFlags()), canTrap, graph));
+        Value result1 = append(new ArithmeticOp(opcode, result, xValue, yValue, isStrict(method.accessFlags()), canTrap, graph));
         frameState.push(result, result1);
     }
 
@@ -571,7 +582,7 @@
         int delta = stream().readIncrement();
         Value x = frameState.localAt(index);
         Value y = append(Constant.forInt(delta, graph));
-        frameState.storeLocal(index, append(new ArithmeticOp(IADD, CiKind.Int, x, y, isStrict(method().accessFlags()), false, graph)));
+        frameState.storeLocal(index, append(new ArithmeticOp(IADD, CiKind.Int, x, y, isStrict(method.accessFlags()), false, graph)));
     }
 
     private void genGoto(int fromBCI, int toBCI) {
@@ -610,16 +621,20 @@
     private void genThrow(int bci) {
         Value exception = frameState.apop();
         append(new NullCheck(exception, graph));
+
         Instruction entry = handleException(exception, bci);
-        if (entry == null) {
-            entry = new Unwind(exception, graph.end(), graph);
+        if (entry != null) {
+            append(entry);
+        } else {
+            frameState.clearStack();
+            frameState.apush(exception);
+            appendGoto(createTarget(unwindBlock(), frameState));
         }
-        append(entry);
     }
 
     private void genCheckCast() {
         int cpi = stream().readCPI();
-        RiType type = constantPool().lookupType(cpi, CHECKCAST);
+        RiType type = constantPool.lookupType(cpi, CHECKCAST);
         boolean isInitialized = type.isResolved();
         Value typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, isInitialized, cpi);
         Value object = frameState.apop();
@@ -632,7 +647,7 @@
 
     private void genInstanceOf() {
         int cpi = stream().readCPI();
-        RiType type = constantPool().lookupType(cpi, INSTANCEOF);
+        RiType type = constantPool.lookupType(cpi, INSTANCEOF);
         boolean isInitialized = type.isResolved();
         Value typeInstruction = genTypeOrDeopt(RiType.Representation.ObjectHub, type, isInitialized, cpi);
         Value object = frameState.apop();
@@ -644,9 +659,9 @@
     }
 
     void genNewInstance(int cpi) {
-        RiType type = constantPool().lookupType(cpi, NEW);
+        RiType type = constantPool.lookupType(cpi, NEW);
         if (type.isResolved()) {
-            NewInstance n = new NewInstance(type, cpi, constantPool(), graph);
+            NewInstance n = new NewInstance(type, cpi, constantPool, graph);
             frameState.apush(append(n));
         } else {
             append(new Deoptimize(graph));
@@ -656,13 +671,13 @@
 
     private void genNewTypeArray(int typeCode) {
         CiKind kind = CiKind.fromArrayTypeCode(typeCode);
-        RiType elementType = compilation.runtime.asRiType(kind);
+        RiType elementType = runtime.asRiType(kind);
         NewTypeArray nta = new NewTypeArray(frameState.ipop(), elementType, graph);
         frameState.apush(append(nta));
     }
 
     private void genNewObjectArray(int cpi) {
-        RiType type = constantPool().lookupType(cpi, ANEWARRAY);
+        RiType type = constantPool.lookupType(cpi, ANEWARRAY);
         Value length = frameState.ipop();
         if (type.isResolved()) {
             NewArray n = new NewObjectArray(type, length, graph);
@@ -675,14 +690,14 @@
     }
 
     private void genNewMultiArray(int cpi) {
-        RiType type = constantPool().lookupType(cpi, MULTIANEWARRAY);
+        RiType type = constantPool.lookupType(cpi, MULTIANEWARRAY);
         int rank = stream().readUByte(bci() + 3);
         Value[] dims = new Value[rank];
         for (int i = rank - 1; i >= 0; i--) {
             dims[i] = frameState.ipop();
         }
         if (type.isResolved()) {
-            NewArray n = new NewMultiArray(type, dims, cpi, constantPool(), graph);
+            NewArray n = new NewMultiArray(type, dims, cpi, constantPool, graph);
             frameState.apush(append(n));
         } else {
             append(new Deoptimize(graph));
@@ -831,7 +846,7 @@
 
     private void appendInvoke(int opcode, RiMethod target, Value[] args, int cpi, RiConstantPool constantPool) {
         CiKind resultType = returnKind(target);
-        Invoke invoke = new Invoke(bci(), opcode, resultType.stackKind(), args, target, target.signature().returnType(compilation.method.holder()), graph);
+        Invoke invoke = new Invoke(bci(), opcode, resultType.stackKind(), args, target, target.signature().returnType(method.holder()), graph);
         Value result = appendWithBCI(invoke);
         invoke.setExceptionEdge(handleException(null, bci()));
         frameState.pushReturn(resultType, result);
@@ -843,7 +858,7 @@
             exact = receiver.exactType();
             if (exact == null) {
                 if (receiver.isConstant()) {
-                    exact = compilation.runtime.getTypeOf(receiver.asConstant());
+                    exact = runtime.getTypeOf(receiver.asConstant());
                 }
                 if (exact == null) {
                     RiType declared = receiver.declaredType();
@@ -864,7 +879,7 @@
         }
         if (exactType == null && receiver instanceof Local && ((Local) receiver).index() == 0) {
             // the exact type isn't known, but the receiver is parameter 0 => use holder
-            receiverType = compilation.method.holder();
+            receiverType = method.holder();
             exactType = receiverType.exactType();
         }
         boolean needsCheck = true;
@@ -894,35 +909,23 @@
     }
 
     private void genReturn(Value x) {
-        if (method().isConstructor() && method().holder().superType() == null) {
-            callRegisterFinalizer();
+        frameState.clearStack();
+        if (x != null) {
+            frameState.push(x.kind, x);
         }
-
-        frameState.clearStack();
-        if (Modifier.isSynchronized(method().accessFlags())) {
-            // unlock before exiting the method
-            int lockNumber = frameState.locksSize() - 1;
-            MonitorAddress lockAddress = null;
-            if (compilation.runtime.sizeOfBasicObjectLock() != 0) {
-                lockAddress = new MonitorAddress(lockNumber, graph);
-                append(lockAddress);
-            }
-            append(new MonitorExit(rootMethodSynchronizedObject, lockAddress, lockNumber, graph));
-            frameState.unlock();
-        }
-        append(new Return(x, graph));
+        appendGoto(createTarget(returnBlock(), frameState));
     }
 
     private void genMonitorEnter(Value x, int bci) {
         int lockNumber = frameState.locksSize();
         MonitorAddress lockAddress = null;
-        if (compilation.runtime.sizeOfBasicObjectLock() != 0) {
+        if (runtime.sizeOfBasicObjectLock() != 0) {
             lockAddress = new MonitorAddress(lockNumber, graph);
             append(lockAddress);
         }
         MonitorEnter monitorEnter = new MonitorEnter(x, lockAddress, lockNumber, graph);
         appendWithBCI(monitorEnter);
-        frameState.lock(ir, x, lockNumber + 1);
+        frameState.lock(x);
         if (bci == Instruction.SYNCHRONIZATION_ENTRY_BCI) {
             monitorEnter.setStateAfter(frameState.create(0));
         }
@@ -934,7 +937,7 @@
             throw new CiBailout("monitor stack underflow");
         }
         MonitorAddress lockAddress = null;
-        if (compilation.runtime.sizeOfBasicObjectLock() != 0) {
+        if (runtime.sizeOfBasicObjectLock() != 0) {
             lockAddress = new MonitorAddress(lockNumber, graph);
             append(lockAddress);
         }
@@ -1067,27 +1070,6 @@
         }
     }
 
-    private void fillSyncHandler(Value lock, Block syncHandler) {
-        lastInstr = syncHandler.firstInstruction;
-        while (lastInstr.next() != null) {
-            // go forward to the end of the block
-            lastInstr = lastInstr.next();
-        }
-
-        frameState.initializeFrom(((StateSplit) syncHandler.firstInstruction).stateBefore());
-
-        assert lock != null;
-        assert frameState.locksSize() > 0 && frameState.lockAt(frameState.locksSize() - 1) == lock;
-
-        // Exit the monitor and unwind the stack.
-        genMonitorExit(lock);
-        append(new Unwind(frameState.apop(), graph.end(), graph));
-
-        // The sync handler is always the last thing to add => we can clear the frameState.
-        frameState = null;
-        lastInstr = null;
-    }
-
     private void iterateAllBlocks() {
         Block block;
         while ((block = removeFromWorkList()) != null) {
@@ -1105,7 +1087,11 @@
                 lastInstr = block.firstInstruction;
                 assert block.firstInstruction.next() == null : "instructions already appended at block " + block.blockID;
 
-                if (block instanceof ExceptionBlock) {
+                if (block == returnBlock) {
+                    createReturnBlock(block);
+                } else if (block == unwindBlock) {
+                    createUnwindBlock(block);
+                } else if (block instanceof ExceptionBlock) {
                     createExceptionDispatch((ExceptionBlock) block);
                 } else {
                     iterateBytecodesForBlock(block);
@@ -1136,33 +1122,44 @@
         }
     }
 
+    private void createUnwindBlock(Block block) {
+        if (Modifier.isSynchronized(method.accessFlags())) {
+            genMonitorExit(methodSynchronizedObject);
+        }
+        append(graph.createUnwind(frameState.apop()));
+    }
+
+    private void createReturnBlock(Block block) {
+        if (method.isConstructor() && method.holder().superType() == null) {
+            callRegisterFinalizer();
+        }
+        CiKind returnKind = method.signature().returnKind().stackKind();
+        Value x = returnKind == CiKind.Void ? null : frameState.pop(returnKind);
+        assert frameState.stackSize() == 0;
+
+        if (Modifier.isSynchronized(method.accessFlags())) {
+            genMonitorExit(methodSynchronizedObject);
+        }
+        append(graph.createReturn(x));
+    }
+
     private void createExceptionDispatch(ExceptionBlock block) {
         if (block.handler == null) {
             assert frameState.stackSize() == 1 : "only exception object expected on stack, actual size: " + frameState.stackSize();
-            if (Modifier.isSynchronized(method().accessFlags())) {
-                // unlock before exiting the method
-                int lockNumber = frameState.locksSize() - 1;
-                MonitorAddress lockAddress = null;
-                if (compilation.runtime.sizeOfBasicObjectLock() != 0) {
-                    lockAddress = new MonitorAddress(lockNumber, graph);
-                    append(lockAddress);
-                }
-                append(new MonitorExit(rootMethodSynchronizedObject, lockAddress, lockNumber, graph));
-                frameState.unlock();
-            }
-            append(new Unwind(frameState.apop(), graph.end(), graph));
+            createUnwindBlock(block);
         } else {
             assert frameState.stackSize() == 1;
 
+            Block nextBlock = block.next == null ? unwindBlock() : block.next;
             if (block.handler.catchType().isResolved()) {
                 Instruction catchSuccessor = createTarget(blockFromBci[block.handler.handlerBCI()], frameState);
-                Instruction nextDispatch = createTarget(block.next, frameState);
+                Instruction nextDispatch = createTarget(nextBlock, frameState);
                 append(new ExceptionDispatch(frameState.stackAt(0), catchSuccessor, nextDispatch, block.handler.catchType(), graph));
             } else {
                 Deoptimize deopt = new Deoptimize(graph);
                 deopt.setMessage("unresolved " + block.handler.catchType().name());
                 append(deopt);
-                Instruction nextDispatch = createTarget(block.next, frameState);
+                Instruction nextDispatch = createTarget(nextBlock, frameState);
                 appendGoto(nextDispatch);
             }
         }
@@ -1186,8 +1183,7 @@
             if (nextBlock != null && nextBlock != block) {
                 assert !nextBlock.isExceptionEntry;
                 // we fell through to the next block, add a goto and break
-                Instruction next = createTarget(nextBlock, frameState);
-                appendGoto(next);
+                appendGoto(createTarget(nextBlock, frameState));
                 break;
             }
             // read the opcode
@@ -1215,7 +1211,7 @@
 
     private void traceState() {
         if (C1XOptions.TraceBytecodeParserLevel >= TRACELEVEL_STATE && !TTY.isSuppressed()) {
-            log.println(String.format("|   state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method()));
+            log.println(String.format("|   state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method));
             for (int i = 0; i < frameState.localsSize(); ++i) {
                 Value value = frameState.localAt(i);
                 log.println(String.format("|   local[%d] = %-8s : %s", i, value == null ? "bogus" : value.kind.javaName, value));
@@ -1414,14 +1410,14 @@
             case DRETURN        : genReturn(frameState.dpop()); break;
             case ARETURN        : genReturn(frameState.apop()); break;
             case RETURN         : genReturn(null  ); break;
-            case GETSTATIC      : cpi = stream.readCPI(); genGetStatic(cpi, constantPool().lookupField(cpi, opcode)); break;
-            case PUTSTATIC      : cpi = stream.readCPI(); genPutStatic(cpi, constantPool().lookupField(cpi, opcode)); break;
-            case GETFIELD       : cpi = stream.readCPI(); genGetField(cpi, constantPool().lookupField(cpi, opcode)); break;
-            case PUTFIELD       : cpi = stream.readCPI(); genPutField(cpi, constantPool().lookupField(cpi, opcode)); break;
-            case INVOKEVIRTUAL  : cpi = stream.readCPI(); genInvokeVirtual(constantPool().lookupMethod(cpi, opcode), cpi, constantPool()); break;
-            case INVOKESPECIAL  : cpi = stream.readCPI(); genInvokeSpecial(constantPool().lookupMethod(cpi, opcode), null, cpi, constantPool()); break;
-            case INVOKESTATIC   : cpi = stream.readCPI(); genInvokeStatic(constantPool().lookupMethod(cpi, opcode), cpi, constantPool()); break;
-            case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(constantPool().lookupMethod(cpi, opcode), cpi, constantPool()); break;
+            case GETSTATIC      : cpi = stream.readCPI(); genGetStatic(cpi, constantPool.lookupField(cpi, opcode)); break;
+            case PUTSTATIC      : cpi = stream.readCPI(); genPutStatic(cpi, constantPool.lookupField(cpi, opcode)); break;
+            case GETFIELD       : cpi = stream.readCPI(); genGetField(cpi, constantPool.lookupField(cpi, opcode)); break;
+            case PUTFIELD       : cpi = stream.readCPI(); genPutField(cpi, constantPool.lookupField(cpi, opcode)); break;
+            case INVOKEVIRTUAL  : cpi = stream.readCPI(); genInvokeVirtual(constantPool.lookupMethod(cpi, opcode), cpi, constantPool); break;
+            case INVOKESPECIAL  : cpi = stream.readCPI(); genInvokeSpecial(constantPool.lookupMethod(cpi, opcode), null, cpi, constantPool); break;
+            case INVOKESTATIC   : cpi = stream.readCPI(); genInvokeStatic(constantPool.lookupMethod(cpi, opcode), cpi, constantPool); break;
+            case INVOKEINTERFACE: cpi = stream.readCPI(); genInvokeInterface(constantPool.lookupMethod(cpi, opcode), cpi, constantPool); break;
             case NEW            : genNewInstance(stream.readCPI()); break;
             case NEWARRAY       : genNewTypeArray(stream.readLocalIndex()); break;
             case ANEWARRAY      : genNewObjectArray(stream.readCPI()); break;
@@ -1465,10 +1461,6 @@
         frameState.ipush(append(new ArrayLength(frameState.apop(), graph)));
     }
 
-    private RiConstantPool constantPool() {
-        return constantPool;
-    }
-
     /**
      * Adds a block to the worklist, if it is not already in the worklist.
      * This method will keep the worklist topologically stored (i.e. the lower
--- a/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/graph/IR.java	Tue Jun 07 11:19:01 2011 +0200
@@ -22,6 +22,7 @@
  */
 package com.sun.c1x.graph;
 
+import java.lang.reflect.*;
 import java.util.*;
 
 import com.oracle.graal.graph.*;
@@ -32,6 +33,9 @@
 import com.sun.c1x.ir.*;
 import com.sun.c1x.lir.*;
 import com.sun.c1x.observer.*;
+import com.sun.c1x.value.*;
+import com.sun.cri.ci.*;
+import com.sun.cri.ri.*;
 
 /**
  * This class implements the overall container for the HIR (high-level IR) graph
@@ -49,8 +53,6 @@
      */
     public LIRBlock startBlock;
 
-    private int maxLocks;
-
     /**
      * The linear-scan ordered list of blocks.
      */
@@ -162,12 +164,227 @@
 
     private void buildGraph() {
         // Graph builder must set the startBlock and the osrEntryBlock
-        new GraphBuilder(compilation, this, compilation.graph).build();
+        new GraphBuilder(compilation, compilation.method, compilation.graph).build();
 
         verifyAndPrint("After graph building");
 
+        List<Invoke> trivialInline = new ArrayList<Invoke>();
+        List<Invoke> deoptInline = new ArrayList<Invoke>();
+        List<RiMethod> deoptMethods = new ArrayList<RiMethod>();
+        for (Node node : compilation.graph.getNodes()) {
+            if (node instanceof Invoke) {
+                Invoke invoke = (Invoke) node;
+                RiMethod target = invoke.target;
+                if (target.isResolved() && !Modifier.isNative(target.accessFlags())) {
+                    if (target.canBeStaticallyBound()) {
+                        trivialInline.add(invoke);
+                    } else {
+                        RiMethod concrete = invoke.target.holder().uniqueConcreteMethod(invoke.target);
+                        if (concrete != null) {
+                            deoptInline.add(invoke);
+                            deoptMethods.add(concrete);
+                        }
+                    }
+                }
+            }
+        }
+
+        int allowedInlinings = 50;
+        for (Invoke invoke : trivialInline) {
+            if (inlineMethod(invoke, invoke.target)) {
+                if (--allowedInlinings <= 0) {
+                    break;
+                }
+            }
+        }
+
+        for (int i = 0; i < deoptInline.size(); i++) {
+            Invoke invoke = deoptInline.get(i);
+            RiMethod method = deoptMethods.get(i);
+            if (inlineMethod(invoke, method)) {
+                if (C1XOptions.TraceInlining) {
+                    System.out.println("registering concrete method assumption...");
+                }
+                compilation.assumptions.recordConcreteMethod(invoke.target, method);
+                if (--allowedInlinings <= 0) {
+                    break;
+                }
+            }
+        }
+
         if (C1XOptions.PrintCompilation) {
-            TTY.print(String.format("%3d blocks | ", this.numberOfBlocks()));
+            TTY.print(String.format("%3d blocks | ", compilation.stats.blockCount));
+        }
+    }
+
+    private boolean inlineMethod(Invoke invoke, RiMethod method) {
+        String name = invoke.id() + ": " + CiUtil.format("%H.%n(%p):%r", method, false) + " (" + method.code().length + " bytes)";
+
+        if (method.code().length > 50) {
+            if (C1XOptions.TraceInlining) {
+                System.out.println("not inlining " + name + " because of code size");
+            }
+            return false;
+        }
+
+        Instruction exceptionEdge = invoke.exceptionEdge();
+        if (exceptionEdge != null) {
+            if (C1XOptions.TraceInlining) {
+                System.out.println("not inlining " + name + " because of exceptionEdge");
+            }
+            return false;
+        }
+        if (!method.holder().isInitialized()) {
+            if (C1XOptions.TraceInlining) {
+                System.out.println("not inlining " + name + " because of non-initialized class");
+            }
+            return false;
+        }
+
+        if (C1XOptions.TraceInlining) {
+            System.out.println("building graph: " + name);
+        }
+        CompilerGraph graph = new CompilerGraph();
+        new GraphBuilder(compilation, method, graph).build();
+
+        boolean withReceiver = !Modifier.isStatic(method.accessFlags());
+
+        int argumentCount = method.signature().argumentCount(false);
+        Value[] parameters = new Value[argumentCount + (withReceiver ? 1 : 0)];
+        int slot = withReceiver ? 1 : 0;
+        int param = withReceiver ? 1 : 0;
+        for (int i = 0; i < argumentCount; i++) {
+            parameters[param++] = invoke.argument(slot);
+            slot += method.signature().argumentKindAt(i).sizeInSlots();
+        }
+        if (withReceiver) {
+            parameters[0] = invoke.argument(0);
+        }
+
+        HashMap<Node, Node> replacements = new HashMap<Node, Node>();
+        ArrayList<Node> nodes = new ArrayList<Node>();
+        ArrayList<Node> frameStates = new ArrayList<Node>();
+        Return returnNode = null;
+        Unwind unwindNode = null;
+        StartNode startNode = null;
+        boolean invokes = false;
+        for (Node node : graph.getNodes()) {
+            if (node != null) {
+                if (node instanceof StartNode) {
+                    startNode = (StartNode) node;
+                } else if (node instanceof Local) {
+                    replacements.put(node, parameters[((Local) node).index()]);
+                } else {
+                    nodes.add(node);
+                    if (node instanceof Return) {
+                        returnNode = (Return) node;
+                    } else if (node instanceof Unwind) {
+                        unwindNode = (Unwind) node;
+                    } else if (node instanceof FrameState) {
+                        frameStates.add(node);
+                    }
+                }
+            }
+        }
+        if (unwindNode != null) {
+            if (C1XOptions.TraceInlining) {
+                System.out.println("not inlining " + name + " because of unwind node");
+            }
+            return false;
+        }
+        if (invokes) {
+            if (C1XOptions.TraceInlining) {
+                System.out.println("not inlining " + name + " because of invokes");
+            }
+            return false;
+        }
+
+        if (C1XOptions.TraceInlining) {
+            System.out.println("inlining " + name + ": " + frameStates.size() + " frame states, " + nodes.size() + " nodes");
+        }
+
+        Instruction pred;
+        if (withReceiver) {
+            pred = new NullCheck(parameters[0], compilation.graph);
+        } else {
+            pred = new Merge(compilation.graph);
+        }
+        assert invoke.predecessors().size() == 1;
+        invoke.predecessors().get(0).successors().replace(invoke, pred);
+        replacements.put(startNode, pred);
+
+        Map<Node, Node> duplicates = compilation.graph.addDuplicate(nodes, replacements);
+
+        if (returnNode != null) {
+            List<Node> usages = new ArrayList<Node>(invoke.usages());
+            for (Node usage : usages) {
+                if (returnNode.result() instanceof Local) {
+                    usage.inputs().replace(invoke, replacements.get(returnNode.result()));
+                } else {
+                    usage.inputs().replace(invoke, duplicates.get(returnNode.result()));
+                }
+            }
+            Node returnDuplicate = duplicates.get(returnNode);
+            returnDuplicate.inputs().clearAll();
+
+            assert returnDuplicate.predecessors().size() == 1;
+            Node returnPred = returnDuplicate.predecessors().get(0);
+            int index = returnDuplicate.predecessorsIndex().get(0);
+            returnPred.successors().setAndClear(index, invoke, 0);
+
+            returnDuplicate.delete();
+        }
+        FrameState stateAfter = invoke.stateAfter();
+        if (frameStates.size() > 0) {
+            FrameState outerFrameState = stateAfter.duplicateModified(invoke.bci, invoke.kind);
+            for (Node frameState : frameStates) {
+                ((FrameState) duplicates.get(frameState)).setOuterFrameState(outerFrameState);
+            }
+        }
+
+        invoke.successors().clearAll();
+        invoke.inputs().clearAll();
+        invoke.delete();
+
+        stateAfter.delete();
+
+        deleteUnused(exceptionEdge);
+
+        verifyAndPrint("After inlining " + CiUtil.format("%H.%n(%p):%r", method, false));
+        return true;
+    }
+
+    private void deleteUnused(Node node) {
+        if (node != null && node.predecessors().size() == 0) {
+            if (node instanceof ExceptionObject) {
+                Node successor = node.successors().get(0);
+                node.successors().clearAll();
+                if (successor instanceof ExceptionDispatch) {
+                    ExceptionDispatch dispatch = (ExceptionDispatch) successor;
+                    Node succ1 = dispatch.catchSuccessor();
+                    Node succ2 = dispatch.otherSuccessor();
+                    if (succ1 instanceof Merge) {
+                        ((Merge) succ1).removePhiPredecessor(dispatch);
+                    }
+                    if (succ2 instanceof Merge) {
+                        ((Merge) succ2).removePhiPredecessor(dispatch);
+                    }
+                    dispatch.successors().clearAll();
+                    deleteUnused(succ1);
+                    deleteUnused(succ2);
+                    dispatch.delete();
+                } else {
+                    assert successor instanceof Merge;
+                    System.out.println("succ: " + successor.successors().get(0));
+                    Node next = successor.successors().get(0);
+                    successor.successors().clearAll();
+                    deleteUnused(next);
+                    successor.delete();
+                }
+                node.delete();
+            } else if (node instanceof Unwind) {
+                node.delete();
+            }
         }
     }
 
@@ -203,35 +420,23 @@
         }
     }
 
-
-    public int nextBlockNumber() {
-        return compilation.stats.blockCount++;
-    }
-
-    public int numberOfBlocks() {
-        return compilation.stats.blockCount;
-    }
-
     public int numLoops() {
         return compilation.stats.loopCount;
     }
 
     /**
-     * Updates the maximum number of locks held at any one time.
-     *
-     * @param locks a lock count that will replace the current {@linkplain #maxLocks() max locks} if it is greater
-     */
-    public void updateMaxLocks(int locks) {
-        if (locks > maxLocks) {
-            maxLocks = locks;
-        }
-    }
-
-    /**
-     * Gets the number of locks.
-     * @return the number of locks
+     * Gets the maximum number of locks in the graph's frame states.
      */
     public final int maxLocks() {
+        int maxLocks = 0;
+        for (Node node : compilation.graph.getNodes()) {
+            if (node instanceof FrameState) {
+                int lockCount = ((FrameState) node).locksSize();
+                if (lockCount > maxLocks) {
+                    maxLocks = lockCount;
+                }
+            }
+        }
         return maxLocks;
     }
 
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/LoopBegin.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/LoopBegin.java	Tue Jun 07 11:19:01 2011 +0200
@@ -58,6 +58,11 @@
     }
 
     @Override
+    public String shortName() {
+        return "LoopBegin";
+    }
+
+    @Override
     public Node copy(Graph into) {
         LoopBegin x = new LoopBegin(into);
         x.setNonNull(isNonNull());
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/LoopEnd.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/LoopEnd.java	Tue Jun 07 11:19:01 2011 +0200
@@ -69,6 +69,11 @@
     }
 
     @Override
+    public String shortName() {
+        return "LoopEnd";
+    }
+
+    @Override
     public Node copy(Graph into) {
         LoopEnd x = new LoopEnd(into);
         x.setNonNull(isNonNull());
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Merge.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Merge.java	Tue Jun 07 11:19:01 2011 +0200
@@ -267,4 +267,17 @@
         x.setNonNull(isNonNull());
         return x;
     }
+
+    public void removePhiPredecessor(ExceptionDispatch successor) {
+        int predIndex = predecessors().indexOf(successor);
+        assert predIndex != -1;
+
+        for (Node usage : usages()) {
+            if (usage instanceof Phi) {
+                Phi phi = (Phi) usage;
+                assert phi.valueCount() == predecessors().size();
+                phi.removeInput(predIndex + 1);
+            }
+        }
+    }
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Phi.java	Tue Jun 07 11:19:01 2011 +0200
@@ -131,15 +131,11 @@
     @Override
     public String shortName() {
         StringBuilder str = new StringBuilder();
-        for (int i = 1; i < inputs().size(); ++i) {
-            if (i != 1) {
+        for (int i = 0; i < valueCount(); ++i) {
+            if (i != 0) {
                 str.append(' ');
             }
-            if (inputs().get(i) != null) {
-                str.append(inputs().get(i).id());
-            } else {
-                str.append("-");
-            }
+            str.append(valueAt(i) == null ? "-" : valueAt(i).id());
         }
         return "Phi: (" + str + ")";
     }
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Return.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Return.java	Tue Jun 07 11:19:01 2011 +0200
@@ -72,7 +72,6 @@
     public Return(Value result, Graph graph) {
         super(result == null ? CiKind.Void : result.kind, 0, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         setResult(result);
-        successors().set(SUCCESSOR_END, graph.end());
     }
 
     // for copying
--- a/graal/GraalCompiler/src/com/sun/c1x/ir/Unwind.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/ir/Unwind.java	Tue Jun 07 11:19:01 2011 +0200
@@ -34,8 +34,7 @@
     private static final int INPUT_COUNT = 1;
     private static final int INPUT_EXCEPTION = 0;
 
-    private static final int SUCCESSOR_COUNT = 1;
-    private static final int SUCCESSOR_END = 0;
+    private static final int SUCCESSOR_COUNT = 0;
 
     @Override
     protected int inputCount() {
@@ -64,10 +63,9 @@
         return (Value) inputs().set(super.inputCount() + INPUT_EXCEPTION, n);
     }
 
-    public Unwind(Value exception, Node successor, Graph graph) {
+    public Unwind(Value exception, Graph graph) {
         super(CiKind.Object, 0, INPUT_COUNT, SUCCESSOR_COUNT, graph);
         setException(exception);
-        successors().set(SUCCESSOR_END, successor);
     }
 
     @Override
@@ -82,7 +80,7 @@
 
     @Override
     public Node copy(Graph into) {
-        Unwind x = new Unwind(null, null, into);
+        Unwind x = new Unwind(null, into);
         x.setNonNull(isNonNull());
         return x;
     }
--- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameState.java	Tue Jun 07 11:19:01 2011 +0200
@@ -31,6 +31,7 @@
 import com.sun.c1x.debug.*;
 import com.sun.c1x.ir.*;
 import com.sun.cri.ci.*;
+import com.sun.cri.ri.*;
 
 /**
  * The {@code FrameState} class encapsulates the frame state (i.e. local variables and
@@ -38,6 +39,10 @@
  */
 public final class FrameState extends Value implements FrameStateAccess {
 
+    private static final int INPUT_COUNT = 1;
+
+    private static final int INPUT_OUTER_FRAME_STATE = 0;
+
     protected final int localsSize;
 
     protected final int stackSize;
@@ -56,12 +61,27 @@
         return super.successorCount() + SUCCESSOR_COUNT;
     }
 
+    public FrameState outerFrameState() {
+        return (FrameState) inputs().get(super.inputCount() + INPUT_OUTER_FRAME_STATE);
+    }
+
+    public FrameState setOuterFrameState(FrameState n) {
+        return (FrameState) inputs().set(super.inputCount() + INPUT_OUTER_FRAME_STATE, n);
+    }
+
+    @Override
+    public void setValueAt(int i, Value x) {
+        inputs().set(INPUT_COUNT + i, x);
+    }
+
     /**
      * The bytecode index to which this frame state applies. This will be {@code -1}
      * iff this state is mutable.
      */
     public final int bci;
 
+    public final RiMethod method;
+
     /**
      * Creates a {@code FrameState} for the given scope and maximum number of stack and local variables.
      *
@@ -70,28 +90,27 @@
      * @param stackSize size of the stack
      * @param lockSize number of locks
      */
-    public FrameState(int bci, int localsSize, int stackSize, int locksSize, Graph graph) {
-        super(CiKind.Illegal, localsSize + stackSize + locksSize, SUCCESSOR_COUNT, graph);
+    public FrameState(RiMethod method, int bci, int localsSize, int stackSize, int locksSize, Graph graph) {
+        super(CiKind.Illegal, localsSize + stackSize + locksSize + INPUT_COUNT, SUCCESSOR_COUNT, graph);
+        this.method = method;
         this.bci = bci;
         this.localsSize = localsSize;
         this.stackSize = stackSize;
         this.locksSize = locksSize;
         C1XMetrics.FrameStatesCreated++;
         C1XMetrics.FrameStateValuesCreated += localsSize + stackSize + locksSize;
-        //Exception e = new Exception();
-        //e.printStackTrace();
     }
 
-    FrameState(int bci, Value[] locals, Value[] stack, int stackSize, ArrayList<Value> locks, Graph graph) {
-        this(bci, locals.length, stackSize, locks.size(), graph);
+    FrameState(RiMethod method, int bci, Value[] locals, Value[] stack, int stackSize, ArrayList<Value> locks, Graph graph) {
+        this(method, bci, locals.length, stackSize, locks.size(), graph);
         for (int i = 0; i < locals.length; i++) {
-            inputs().set(i, locals[i]);
+            setValueAt(i, locals[i]);
         }
         for (int i = 0; i < stackSize; i++) {
-            inputs().set(localsSize + i, stack[i]);
+            setValueAt(localsSize + i, stack[i]);
         }
         for (int i = 0; i < locks.size(); i++) {
-            inputs().set(locals.length + stackSize + i, locks.get(i));
+            setValueAt(locals.length + stackSize + i, locks.get(i));
         }
     }
 
@@ -109,13 +128,14 @@
      */
     @Override
     public FrameState duplicateWithEmptyStack(int bci) {
-        FrameState other = new FrameState(bci, localsSize, 0, locksSize(), graph());
+        FrameState other = new FrameState(method, bci, localsSize, 0, locksSize(), graph());
         for (int i = 0; i < localsSize; i++) {
-            other.inputs().set(i, localAt(i));
+            other.setValueAt(i, localAt(i));
         }
         for (int i = 0; i < locksSize; i++) {
-            other.inputs().set(localsSize + i, lockAt(i));
+            other.setValueAt(localsSize + i, lockAt(i));
         }
+        other.setOuterFrameState(outerFrameState());
         return other;
     }
 
@@ -127,20 +147,21 @@
     public FrameState duplicateModified(int bci, CiKind popKind, Value... pushedValues) {
         int popSlots = popKind.sizeInSlots();
         int pushSlots = pushedValues.length;
-        FrameState other = new FrameState(bci, localsSize, stackSize - popSlots + pushSlots, locksSize(), graph());
+        FrameState other = new FrameState(method, bci, localsSize, stackSize - popSlots + pushSlots, locksSize(), graph());
         for (int i = 0; i < localsSize; i++) {
-            other.inputs().set(i, localAt(i));
+            other.setValueAt(i, localAt(i));
         }
         for (int i = 0; i < stackSize - popSlots; i++) {
-            other.inputs().set(localsSize + i, stackAt(i));
+            other.setValueAt(localsSize + i, stackAt(i));
         }
         int slot = localsSize + stackSize - popSlots;
         for (int i = 0; i < pushSlots; i++) {
-            other.inputs().set(slot++, pushedValues[i]);
+            other.setValueAt(slot++, pushedValues[i]);
         }
         for (int i = 0; i < locksSize; i++) {
-            other.inputs().set(localsSize + other.stackSize + i, lockAt(i));
+            other.setValueAt(localsSize + other.stackSize + i, lockAt(i));
         }
+        other.setOuterFrameState(outerFrameState());
         return other;
     }
 
@@ -160,6 +181,9 @@
                 return false;
             }
         }
+        if (other.outerFrameState() != outerFrameState()) {
+            return false;
+        }
         return true;
     }
 
@@ -194,7 +218,7 @@
         // note that for double word locals, the high slot should already be null
         // unless the local is actually dead and the high slot is being reused;
         // in either case, it is not necessary to null the high slot
-        inputs().set(i, null);
+        setValueAt(i, null);
     }
 
     /**
@@ -207,16 +231,16 @@
     public void storeLocal(int i, Value x) {
         assert i < localsSize : "local variable index out of range: " + i;
         invalidateLocal(i);
-        inputs().set(i, x);
+        setValueAt(i, x);
         if (isDoubleWord(x)) {
             // (tw) if this was a double word then kill i+1
-            inputs().set(i + 1, null);
+            setValueAt(i + 1, null);
         }
         if (i > 0) {
             // if there was a double word at i - 1, then kill it
             Value p = localAt(i - 1);
             if (isDoubleWord(p)) {
-                inputs().set(i - 1, null);
+                setValueAt(i - 1, null);
             }
         }
     }
@@ -229,7 +253,7 @@
      */
     public Value localAt(int i) {
         assert i < localsSize : "local variable index out of range: " + i;
-        return (Value) inputs().get(i);
+        return valueAt(i);
     }
 
     /**
@@ -240,7 +264,7 @@
      */
     public Value stackAt(int i) {
         assert i >= 0 && i < (localsSize + stackSize);
-        return (Value) inputs().get(localsSize + i);
+        return valueAt(localsSize + i);
     }
 
     /**
@@ -250,7 +274,7 @@
      */
     public Value lockAt(int i) {
         assert i >= 0;
-        return (Value) inputs().get(localsSize + stackSize + i);
+        return valueAt(localsSize + stackSize + i);
     }
 
     /**
@@ -268,7 +292,7 @@
                 }
             }
             Phi phi = new Phi(p.kind, block, graph());
-            inputs().set(localsSize + i, phi);
+            setValueAt(localsSize + i, phi);
             return phi;
         }
         return null;
@@ -303,8 +327,8 @@
      * @return the value at index {@code i} which may be {@code null}
      */
     public Value valueAt(int i) {
-        assert i < (localsSize + stackSize);
-        return (Value) inputs().get(i);
+        assert i < (localsSize + stackSize + locksSize);
+        return (Value) inputs().get(INPUT_COUNT + i);
     }
 
     /**
@@ -341,7 +365,7 @@
                                 phi.makeDead();
                             }
                         }
-                        inputs().set(i, null);
+                        setValueAt(i, null);
                         continue;
                     }
                     Phi phi = null;
@@ -382,11 +406,9 @@
     }
 
     public Merge block() {
-        if (usages().size() > 0) {
-            assert usages().size() == 1;
-            Node node = usages().get(0);
-            if (node instanceof Merge) {
-                return (Merge) node;
+        for (Node usage : usages()) {
+            if (usage instanceof Merge) {
+                return (Merge) usage;
             }
         }
         return null;
@@ -432,6 +454,9 @@
                 proc.doValue(value);
             }
         }
+        if (outerFrameState() != null) {
+            outerFrameState().forEachLiveStateValue(proc);
+        }
     }
 
     @Override
@@ -466,12 +491,12 @@
 
     @Override
     public FrameState copy() {
-        return new FrameState(bci, localsSize, stackSize, locksSize, graph());
+        return new FrameState(method, bci, localsSize, stackSize, locksSize, graph());
     }
 
 
     private FrameState copy(int newBci) {
-        return new FrameState(newBci, localsSize, stackSize, locksSize, graph());
+        return new FrameState(method, newBci, localsSize, stackSize, locksSize, graph());
     }
 
     @Override
@@ -484,13 +509,8 @@
     }
 
     @Override
-    public void setValueAt(int j, Value v) {
-        inputs().set(j, v);
-    }
-
-    @Override
     public Node copy(Graph into) {
-        FrameState x = new FrameState(bci, localsSize, stackSize, locksSize, into);
+        FrameState x = new FrameState(method, bci, localsSize, stackSize, locksSize, into);
         x.setNonNull(isNonNull());
         return x;
     }
--- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateAccess.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateAccess.java	Tue Jun 07 11:19:01 2011 +0200
@@ -46,4 +46,6 @@
 
     void setValueAt(int j, Value v);
 
+    Value outerFrameState();
+
 }
--- a/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalCompiler/src/com/sun/c1x/value/FrameStateBuilder.java	Tue Jun 07 11:19:01 2011 +0200
@@ -28,7 +28,6 @@
 import java.util.*;
 
 import com.oracle.graal.graph.*;
-import com.sun.c1x.graph.*;
 import com.sun.c1x.ir.*;
 import com.sun.cri.ci.*;
 import com.sun.cri.ri.*;
@@ -44,7 +43,10 @@
 
     private int stackIndex;
 
+    private final RiMethod method;
+
     public FrameStateBuilder(RiMethod method, Graph graph) {
+        this.method = method;
         this.graph = graph;
         this.locals = new Value[method.maxLocals()];
         this.stack = new Value[method.maxStackSize()];
@@ -97,12 +99,14 @@
     }
 
     public FrameState create(int bci) {
-        return new FrameState(bci, locals, stack, stackIndex, locks, graph);
+        return new FrameState(method, bci, locals, stack, stackIndex, locks, graph);
     }
 
     @Override
     public FrameState duplicateWithEmptyStack(int bci) {
-        return new FrameState(bci, locals, new Value[0], 0, locks, graph);
+        FrameState frameState = new FrameState(method, bci, locals, new Value[0], 0, locks, graph);
+        frameState.setOuterFrameState(outerFrameState());
+        return frameState;
     }
 
     /**
@@ -359,9 +363,8 @@
      * @param scope the IRScope in which this locking operation occurs
      * @param obj the object being locked
      */
-    public void lock(IR ir, Value obj, int totalNumberOfLocks) {
+    public void lock(Value obj) {
         locks.add(obj);
-        ir.updateMaxLocks(totalNumberOfLocks);
     }
 
     /**
@@ -496,4 +499,8 @@
         }
     }
 
+    @Override
+    public FrameState outerFrameState() {
+        return null;
+    }
 }
--- a/graal/GraalGraph/src/com/oracle/graal/graph/EndNode.java	Tue Jun 07 11:18:18 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-package com.oracle.graal.graph;
-
-public class EndNode extends Node {
-
-    private static final int INPUT_COUNT = 0;
-
-    private static final int SUCCESSOR_COUNT = 0;
-
-    @Override
-    protected int inputCount() {
-        return super.inputCount() + INPUT_COUNT;
-    }
-
-    @Override
-    protected int successorCount() {
-        return super.successorCount() + SUCCESSOR_COUNT;
-    }
-
-    EndNode(Graph graph) {
-        super(INPUT_COUNT, SUCCESSOR_COUNT, graph);
-    }
-
-    @Override
-    public Node replace(Node other) {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public void delete() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public Node copy(Graph into) {
-        throw new UnsupportedOperationException();
-    }
-}
--- a/graal/GraalGraph/src/com/oracle/graal/graph/Graph.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalGraph/src/com/oracle/graal/graph/Graph.java	Tue Jun 07 11:19:01 2011 +0200
@@ -34,13 +34,11 @@
 
     private final ArrayList<Node> nodes;
     private final StartNode start;
-    private final EndNode end;
     int nextId;
 
     public Graph() {
         nodes = new ArrayList<Node>();
         start = new StartNode(this);
-        end = new EndNode(this);
     }
 
     public List<Node> getNodes() {
@@ -61,10 +59,6 @@
         return start;
     }
 
-    public EndNode end() {
-        return end;
-    }
-
     public NodeBitMap createNodeBitMap() {
         return new NodeBitMap(this);
     }
@@ -73,7 +67,7 @@
         return new NodeMap<T>(this);
     }
 
-    public void addDuplicate(Collection<Node> nodes, Map<Node, Node> replacements) {
+    public Map<Node, Node> addDuplicate(Collection<Node> nodes, Map<Node, Node> replacements) {
         Map<Node, Node> newNodes = new HashMap<Node, Node>();
         // create node duplicates
         for (Node node : nodes) {
@@ -131,5 +125,6 @@
                 }
             }
         }
+        return newNodes;
     }
 }
--- a/graal/GraalGraph/src/com/oracle/graal/graph/Node.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalGraph/src/com/oracle/graal/graph/Node.java	Tue Jun 07 11:19:01 2011 +0200
@@ -80,7 +80,7 @@
         return graph;
     }
 
-    public <T> T lookup(Class<T> clazz) {
+    public <T extends Op> T lookup(Class<T> clazz) {
         return null;
     }
 
@@ -118,7 +118,7 @@
 
     public void delete() {
         assert !isDeleted();
-        assert usages.size() == 0 && predecessors.size() == 0;
+        assert usages.size() == 0 && predecessors.size() == 0 : "usages: " + usages.size() + ", predecessors: " + predecessors().size();
         assert predecessorsIndex.size() == 0;
         for (int i = 0; i < inputs.size(); ++i) {
             inputs.set(i, Null);
--- a/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java	Tue Jun 07 11:18:18 2011 +0200
+++ b/graal/GraalGraph/src/com/oracle/graal/graph/NodeArray.java	Tue Jun 07 11:19:01 2011 +0200
@@ -127,8 +127,10 @@
             if (value.predecessors.get(i) == clearedNode && value.predecessorsIndex.get(i) == clearedIndex) {
                 value.predecessors.set(i, self());
                 value.predecessorsIndex.set(i, index);
+                return;
             }
         }
+        assert false;
     }
 
     public int size() {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/GraalGraph/src/com/oracle/graal/graph/Op.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.graph;
+
+
+public interface Op {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/GraalGraph/src/com/oracle/graal/graph/Phase.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.graph;
+
+public abstract class Phase {
+
+    public final void apply(Graph graph) {
+        assert graph != null;
+        run(graph);
+    }
+
+    protected abstract void run(Graph graph);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/build.xml	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- You may freely edit this file. See harness/README in the NetBeans platform -->
+<!-- for some information on what you could do (e.g. targets to override). -->
+<!-- If you delete this file and reopen the project it will be recreated. -->
+<project name="at.ssw.visualizer.texteditor" default="netbeans" basedir=".">
+    <description>Builds, tests, and runs the project at.ssw.visualizer.texteditor.</description>
+    <import file="nbproject/build-impl.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/manifest.mf	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,6 @@
+Manifest-Version: 1.0
+OpenIDE-Module: at.ssw.visualizer.texteditor
+OpenIDE-Module-Layer: at/ssw/visualizer/texteditor/layer.xml
+OpenIDE-Module-Localizing-Bundle: at/ssw/visualizer/texteditor/Bundle.properties
+OpenIDE-Module-Specification-Version: 1.0
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/build-impl.xml	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+*** GENERATED FROM project.xml - DO NOT EDIT  ***
+***         EDIT ../build.xml INSTEAD         ***
+-->
+<project name="at.ssw.visualizer.texteditor-impl" basedir="..">
+    <fail message="Please build using Ant 1.7.1 or higher.">
+        <condition>
+            <not>
+                <antversion atleast="1.7.1"/>
+            </not>
+        </condition>
+    </fail>
+    <property file="nbproject/private/suite-private.properties"/>
+    <property file="nbproject/suite.properties"/>
+    <fail unless="suite.dir">You must set 'suite.dir' to point to your containing module suite</fail>
+    <property file="${suite.dir}/nbproject/private/platform-private.properties"/>
+    <property file="${suite.dir}/nbproject/platform.properties"/>
+    <macrodef name="property" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="name"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{name}" value="${@{value}}"/>
+        </sequential>
+    </macrodef>
+    <macrodef name="evalprops" uri="http://www.netbeans.org/ns/nb-module-project/2">
+        <attribute name="property"/>
+        <attribute name="value"/>
+        <sequential>
+            <property name="@{property}" value="@{value}"/>
+        </sequential>
+    </macrodef>
+    <property file="${user.properties.file}"/>
+    <nbmproject2:property name="harness.dir" value="nbplatform.${nbplatform.active}.harness.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:property name="nbplatform.active.dir" value="nbplatform.${nbplatform.active}.netbeans.dest.dir" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <nbmproject2:evalprops property="cluster.path.evaluated" value="${cluster.path}" xmlns:nbmproject2="http://www.netbeans.org/ns/nb-module-project/2"/>
+    <fail message="Path to 'platform' cluster missing in $${cluster.path} property or using corrupt Netbeans Platform (missing harness).">
+        <condition>
+            <not>
+                <contains string="${cluster.path.evaluated}" substring="platform"/>
+            </not>
+        </condition>
+    </fail>
+    <import file="${harness.dir}/build.xml"/>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/genfiles.properties	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=be4656f4
+build.xml.script.CRC32=eccfca0f
+build.xml.stylesheet.CRC32=a56c6a5b@1.45.1
+# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
+# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
+nbproject/build-impl.xml.data.CRC32=be4656f4
+nbproject/build-impl.xml.script.CRC32=72c794c1
+nbproject/build-impl.xml.stylesheet.CRC32=238281d1@1.45.1
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/platform.properties	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,125 @@
+# Deprecated since 5.0u1; for compatibility with 5.0:
+disabled.clusters=\
+    apisupport1,\
+    enterprise4,\
+    harness,\
+    java1,\
+    mobility8,\
+    nb6.0,\
+    profiler2,\
+    ruby1,\
+    uml4,\
+    visualweb1,\
+    xml1
+disabled.modules=\
+    org.apache.xml.resolver,\
+    org.netbeans.api.debugger,\
+    org.netbeans.api.xml,\
+    org.netbeans.core.ide,\
+    org.netbeans.core.multiview,\
+    org.netbeans.core.output2,\
+    org.netbeans.insane,\
+    org.netbeans.lib.cvsclient,\
+    org.netbeans.libs.commons_logging,\
+    org.netbeans.libs.freemarker,\
+    org.netbeans.libs.ini4j,\
+    org.netbeans.libs.jsch,\
+    org.netbeans.libs.jsr223,\
+    org.netbeans.libs.lucene,\
+    org.netbeans.libs.svnClientAdapter,\
+    org.netbeans.libs.xerces,\
+    org.netbeans.modules.autoupdate.services,\
+    org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.classfile,\
+    org.netbeans.modules.core.kit,\
+    org.netbeans.modules.css.visual,\
+    org.netbeans.modules.db,\
+    org.netbeans.modules.db.core,\
+    org.netbeans.modules.db.kit,\
+    org.netbeans.modules.db.sql.editor,\
+    org.netbeans.modules.db.sql.visualeditor,\
+    org.netbeans.modules.dbapi,\
+    org.netbeans.modules.defaults,\
+    org.netbeans.modules.diff,\
+    org.netbeans.modules.editor.bookmarks,\
+    org.netbeans.modules.editor.bracesmatching,\
+    org.netbeans.modules.editor.codetemplates,\
+    org.netbeans.modules.editor.completion,\
+    org.netbeans.modules.editor.errorstripe,\
+    org.netbeans.modules.editor.errorstripe.api,\
+    org.netbeans.modules.editor.guards,\
+    org.netbeans.modules.editor.highlights,\
+    org.netbeans.modules.editor.indent,\
+    org.netbeans.modules.editor.kit,\
+    org.netbeans.modules.editor.structure,\
+    org.netbeans.modules.extbrowser,\
+    org.netbeans.modules.favorites,\
+    org.netbeans.modules.html,\
+    org.netbeans.modules.html.editor,\
+    org.netbeans.modules.html.editor.lib,\
+    org.netbeans.modules.html.lexer,\
+    org.netbeans.modules.httpserver,\
+    org.netbeans.modules.ide.kit,\
+    org.netbeans.modules.image,\
+    org.netbeans.modules.javahelp,\
+    org.netbeans.modules.jumpto,\
+    org.netbeans.modules.languages,\
+    org.netbeans.modules.languages.bat,\
+    org.netbeans.modules.languages.css,\
+    org.netbeans.modules.languages.diff,\
+    org.netbeans.modules.languages.javascript,\
+    org.netbeans.modules.languages.manifest,\
+    org.netbeans.modules.languages.sh,\
+    org.netbeans.modules.localhistory,\
+    org.netbeans.modules.project.ant,\
+    org.netbeans.modules.project.libraries,\
+    org.netbeans.modules.projectapi,\
+    org.netbeans.modules.projectui,\
+    org.netbeans.modules.projectuiapi,\
+    org.netbeans.modules.properties,\
+    org.netbeans.modules.properties.syntax,\
+    org.netbeans.modules.refactoring.api,\
+    org.netbeans.modules.schema2beans,\
+    org.netbeans.modules.servletapi,\
+    org.netbeans.modules.subversion,\
+    org.netbeans.modules.tasklist.kit,\
+    org.netbeans.modules.tasklist.projectint,\
+    org.netbeans.modules.tasklist.todo,\
+    org.netbeans.modules.tasklist.ui,\
+    org.netbeans.modules.templates,\
+    org.netbeans.modules.timers,\
+    org.netbeans.modules.usersguide,\
+    org.netbeans.modules.utilities,\
+    org.netbeans.modules.utilities.project,\
+    org.netbeans.modules.versioning,\
+    org.netbeans.modules.versioning.system.cvss,\
+    org.netbeans.modules.versioning.util,\
+    org.netbeans.modules.web.flyingsaucer,\
+    org.netbeans.modules.xml.axi,\
+    org.netbeans.modules.xml.catalog,\
+    org.netbeans.modules.xml.core,\
+    org.netbeans.modules.xml.lexer,\
+    org.netbeans.modules.xml.multiview,\
+    org.netbeans.modules.xml.retriever,\
+    org.netbeans.modules.xml.schema.completion,\
+    org.netbeans.modules.xml.schema.model,\
+    org.netbeans.modules.xml.tax,\
+    org.netbeans.modules.xml.text,\
+    org.netbeans.modules.xml.tools,\
+    org.netbeans.modules.xml.wsdl.model,\
+    org.netbeans.modules.xml.xam,\
+    org.netbeans.modules.xml.xdm,\
+    org.netbeans.modules.xsl,\
+    org.netbeans.spi.debugger.ui,\
+    org.netbeans.spi.editor.hints,\
+    org.netbeans.spi.navigator,\
+    org.netbeans.spi.palette,\
+    org.netbeans.spi.tasklist,\
+    org.netbeans.spi.viewmodel,\
+    org.netbeans.swing.dirchooser,\
+    org.openide.compat,\
+    org.openide.util.enumerations
+enabled.clusters=\
+    ide8,\
+    platform7
+nbplatform.active=default
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/project.properties	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,2 @@
+javac.source=1.5
+javac.compilerargs=-Xlint -Xlint:-serial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/project.xml	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,148 @@
+<?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>at.ssw.visualizer.texteditor</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.modules.editor</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>3</release-version>
+                        <specification-version>1.42.1.3.9.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.editor.fold</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.10.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.editor.lib</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>3</release-version>
+                        <specification-version>3.8.1.13.8</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.editor.lib2</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.28.1.2</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.editor.mimelookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.11.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.editor.settings</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.24.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.netbeans.modules.editor.util</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <release-version>1</release-version>
+                        <specification-version>1.28.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.actions</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.9.1.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.awt</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>7.23.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.9.1.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.text</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>6.22.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.22.1.1</specification-version>
+                    </run-dependency>
+                </dependency>
+                <dependency>
+                    <code-name-base>org.openide.util.lookup</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency>
+                        <specification-version>8.3.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.26.1</specification-version>
+                    </run-dependency>
+                </dependency>
+            </module-dependencies>
+            <public-packages>
+                <package>at.ssw.visualizer.texteditor</package>
+                <package>at.ssw.visualizer.texteditor.fold</package>
+                <package>at.ssw.visualizer.texteditor.highlight</package>
+                <package>at.ssw.visualizer.texteditor.hyperlink</package>
+                <package>at.ssw.visualizer.texteditor.model</package>
+                <package>at.ssw.visualizer.texteditor.tooltip</package>
+                <package>at.ssw.visualizer.texteditor.view</package>
+            </public-packages>
+        </data>
+    </configuration>
+</project>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/suite.properties	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,1 @@
+suite.dir=${basedir}/..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/core/selection/Selection.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,72 @@
+package at.ssw.visualizer.core.selection;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.swing.Timer;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class Selection {
+    private Map<Class, Object> elements;
+    private List<ChangeListener> listeners;
+    private Timer eventTimer;
+
+    private ActionListener eventTimerListener = new ActionListener() {
+        public void actionPerformed(ActionEvent event) {
+            doFireChangeEvent();
+        }
+    };
+
+    public Selection() {
+        elements = new HashMap<Class, Object>();
+        listeners = new ArrayList<ChangeListener>();
+        eventTimer = new Timer(100, eventTimerListener);
+        eventTimer.setRepeats(false);
+    }
+
+    private void doPut(Class<?> clazz, Object element) {
+        elements.put(clazz, element);
+        for (Class<?> i : clazz.getInterfaces()) {
+            doPut(i, element);
+        }
+    }
+    
+    public void put(Object element) {
+        doPut(element.getClass(), element);
+        fireChangeEvent();
+        SelectionManager.getDefault().fireChangeEvent();
+    }
+
+    @SuppressWarnings(value = "unchecked")
+    public <T> T get(Class<T> clazz) {
+        return (T) elements.get(clazz);
+    }
+
+
+    protected void doFireChangeEvent() {
+        ChangeEvent event = new ChangeEvent(this);
+        for (ChangeListener listener : listeners.toArray(new ChangeListener[listeners.size()])) {
+            listener.stateChanged(event);
+        }
+    }
+
+    protected void fireChangeEvent() {
+        eventTimer.restart();
+    }
+
+    public void addChangeListener(ChangeListener listener) {
+        listeners.add(listener);
+    }
+
+    public void removeChangeListener(ChangeListener listener) {
+        listeners.remove(listener);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/core/selection/SelectionManager.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,56 @@
+package at.ssw.visualizer.core.selection;
+
+import javax.swing.event.ChangeListener;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class SelectionManager {
+    private static final SelectionManager SINGLETON = new SelectionManager();
+
+    public static SelectionManager getDefault() {
+        return SINGLETON;
+    }
+
+
+    /** Default selection returned when no TopComponent is active.
+     * It is also used to maintain listeners added to the selection manager. */
+    private final Selection emptySelection;
+    private Selection curSelection;
+
+    private SelectionManager() {
+        emptySelection = new Selection();
+        curSelection = emptySelection;
+    }
+
+    public Selection getCurSelection() {
+        return curSelection;
+    }
+
+    public void setSelection(Selection sel) {
+        if (curSelection != sel) {
+            curSelection = sel;
+            fireChangeEvent();
+        }
+    }
+
+    public void removeSelection(Selection sel) {
+        if (curSelection == sel) {
+            curSelection = emptySelection;
+            fireChangeEvent();
+        }
+    }
+
+    protected void fireChangeEvent() {
+        emptySelection.fireChangeEvent();
+    }
+
+    public void addChangeListener(ChangeListener listener) {
+        emptySelection.addChangeListener(listener);
+    }
+
+    public void removeChangeListener(ChangeListener listener) {
+        emptySelection.removeChangeListener(listener);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/core/selection/SelectionProvider.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,9 @@
+package at.ssw.visualizer.core.selection;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public interface SelectionProvider {
+    public Selection getSelection();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/Bundle.properties	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,1 @@
+OpenIDE-Module-Name=Text Editor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/Editor.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,127 @@
+package at.ssw.visualizer.texteditor;
+
+import at.ssw.visualizer.core.selection.Selection;
+import at.ssw.visualizer.core.selection.SelectionManager;
+import at.ssw.visualizer.core.selection.SelectionProvider;
+import at.ssw.visualizer.texteditor.model.BlockRegion;
+import at.ssw.visualizer.texteditor.model.Text;
+import com.sun.hotspot.igv.data.InputBlock;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import javax.swing.event.CaretEvent;
+import javax.swing.event.CaretListener;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import org.openide.text.CloneableEditor;
+import org.openide.windows.TopComponent;
+
+/**
+ * Abstract template class of a <code> Editor </code> class of the Visualizer.
+ * 
+ * Must be initialized with a custom <code> EditorSupport </code> class and the 
+ * method <code> creatClonedObject </code> must be overwritten by 
+ * the <code> Editor </code> implementation.
+ * 
+ * @author Alexander Reder
+ */
+public abstract class Editor extends CloneableEditor implements SelectionProvider {
+    
+    protected Selection selection;
+    private boolean selectionUpdating;
+    private InputBlock[] curBlocks;
+    private boolean initialized;
+    
+    protected Editor(EditorSupport support) {
+        super(support);
+        selection = new Selection();
+        selection.put(support.getControlFlowGraph());        
+        selection.addChangeListener(selectionListener);
+    }
+    
+    public Selection getSelection() {
+        return selection;
+    }
+
+    @Override
+    protected void componentShowing() {
+        super.componentShowing();
+        if (!initialized) {
+            getEditorPane().addCaretListener(caretListener);
+            initialized = true;
+        }
+    }
+    
+    @Override
+    protected void componentActivated() {
+        super.componentActivated();
+        SelectionManager.getDefault().setSelection(selection);
+    }
+    
+    @Override
+    protected void componentClosed() {
+        super.componentClosed();
+        SelectionManager.getDefault().removeSelection(selection);
+    }
+        
+    @Override
+    public int getPersistenceType() {
+        return TopComponent.PERSISTENCE_NEVER;
+    }
+    
+    private ChangeListener selectionListener = new ChangeListener() {
+        public void stateChanged(ChangeEvent event) {
+            if (selectionUpdating) {
+                return;
+            }
+            selectionUpdating = true;
+            
+            Text text = (Text) getEditorPane().getDocument().getProperty(Text.class);
+            InputBlock[] newBlocks = selection.get(InputBlock[].class);
+            
+            if (newBlocks != null && newBlocks.length > 0 && !Arrays.equals(curBlocks, newBlocks)) {
+                BlockRegion r = text.getBlocks().get(newBlocks[0]);
+                int startOffset = r.getNameStart();
+                int endOffset = r.getNameEnd();
+                
+                if (newBlocks.length > 1) {
+                    for (InputBlock b : newBlocks) {
+                        r = text.getBlocks().get(b);
+                        startOffset = Math.min(startOffset, r.getStart());
+                        endOffset = Math.max(endOffset, r.getEnd());
+                    }
+                }
+                
+                getEditorPane().select(startOffset, endOffset);
+            }
+            curBlocks = newBlocks;
+            selectionUpdating = false;
+        }
+    };
+    
+    
+    private CaretListener caretListener = new CaretListener() {
+        public void caretUpdate(CaretEvent event) {
+            if (selectionUpdating) {
+                return;
+            }
+            selectionUpdating = true;
+            
+            Text text = (Text) getEditorPane().getDocument().getProperty(Text.class);
+            List<InputBlock> newBlocks = new ArrayList<InputBlock>();
+            int startOffset = Math.min(event.getDot(), event.getMark());
+            int endOffset = Math.max(event.getDot(), event.getMark());
+            
+            for (BlockRegion region : text.getBlocks().values()) {
+                if (region.getStart() <= endOffset && region.getEnd() > startOffset) {
+                    newBlocks.add(region.getBlock());
+                }
+            }
+            
+            curBlocks = newBlocks.toArray(new InputBlock[newBlocks.size()]);
+            selection.put(curBlocks);
+            selectionUpdating = false;
+        }
+    };
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/EditorKit.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,31 @@
+package at.ssw.visualizer.texteditor;
+
+import at.ssw.visualizer.texteditor.tooltip.ToolTipAction;
+import javax.swing.Action;
+import javax.swing.text.TextAction;
+import org.netbeans.modules.editor.NbEditorKit;
+
+/**
+ * Abstract template class of a <code> EditorKit </code>class of the Visualizer.
+ * 
+ * The <code> scanner </code> field must be initialized with the
+ * custom <code> Scanner </code> implementation and the method <code> 
+ * getContentType </code> must be overwritten and return the mime type 
+ * for the editor.
+ * 
+ * @author Alexander Reder
+ */
+public abstract class EditorKit extends NbEditorKit {
+
+    @Override
+    protected Action[] getCustomActions() {
+        Action[] prev = super.getCustomActions();
+        Action[] added = new Action[]{new ToolTipAction()};
+        if (prev != null) {
+            return TextAction.augmentList(prev, added);
+        } else {
+           return added;
+        }
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/EditorSupport.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,149 @@
+package at.ssw.visualizer.texteditor;
+
+import at.ssw.visualizer.texteditor.model.Text;
+import com.sun.hotspot.igv.data.InputGraph;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.beans.VetoableChangeListener;
+import java.beans.VetoableChangeSupport;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Date;
+import javax.swing.text.EditorKit;
+import javax.swing.text.StyledDocument;
+import org.openide.cookies.EditorCookie;
+import org.openide.cookies.EditCookie;
+import org.openide.text.CloneableEditorSupport;
+import org.openide.windows.CloneableOpenSupport;
+
+/**
+ * Abstract template class of a <code> EditorSupport </code> class of the 
+ * Visulizer.
+ * 
+ * The <code> text </code> field must be initialized by the implementing class
+ * and the methods <code> createCloneableEditor </code> and <code> 
+ * initializeCloneableEditor </code> must be overwritten by the implenting class.
+ * <code> createCloneableEditor </code> must return a custom implementation
+ * of the <code> Editor </code> class.
+ * <code> initializeClonableEditor </code> is used to set the icon, e.g.
+ * <code> editor.setIcon(Utilities.loadImage(IconsImage)); </code>.
+ * 
+ * @author Bernhard Stiftner
+ * @author Christian Wimmer
+ * @author Alexander Reder
+ */
+public abstract class EditorSupport extends CloneableEditorSupport implements EditCookie, EditorCookie, EditorCookie.Observable {
+   
+    protected InputGraph cfg;
+    protected Text text;
+
+    protected EditorSupport(InputGraph cfg) {
+        super(new Env());
+        ((Env) this.env).editorSupport = this;
+        this.cfg = cfg;
+    }
+    
+    public InputGraph getControlFlowGraph() {
+        return cfg;
+    }
+    
+    @Override
+    protected StyledDocument createStyledDocument(EditorKit kit) {
+        StyledDocument doc = super.createStyledDocument(kit);
+
+        // Back-link from Document to our internal data model.
+        doc.putProperty(Text.class, text);
+        doc.putProperty(InputGraph.class, cfg);
+
+        return doc;
+    }
+    
+    public abstract String getMimeType();
+    
+    protected String messageOpening() {
+        return "Opening " + messageToolTip();
+    }
+
+    protected String messageOpened() {
+        return "Opened " + messageToolTip();
+    }
+    
+    protected String messageSave() {
+        throw new UnsupportedOperationException("Not supported yet.");
+    }
+
+    protected String messageName() {
+        return cfg.getName();
+    }
+
+    protected String messageToolTip() {
+        return cfg.getGroup().getName() + " - " + cfg.getName();
+    }
+
+    public static class Env implements CloneableEditorSupport.Env {
+
+        private PropertyChangeSupport prop = new PropertyChangeSupport(this);
+        private VetoableChangeSupport veto = new VetoableChangeSupport(this);
+
+        /**
+         * Back-link to outer class EditorSupport. Env must be a static class
+         * because it is passed to super constructor of EditorSupport.
+         */
+        private EditorSupport editorSupport;
+
+        public InputStream inputStream() throws IOException {
+            return new ByteArrayInputStream(editorSupport.text.getText().getBytes());
+        }
+
+        public OutputStream outputStream() throws IOException {
+            throw new IOException("Editor is readonly");
+        }
+
+        public Date getTime() {
+            throw new UnsupportedOperationException("Not supported yet.");
+        }
+
+        public String getMimeType() {
+            return editorSupport.getMimeType();
+        }
+
+        public boolean isValid() {
+            return true;
+        }
+
+        public boolean isModified() {
+            return false;
+        }
+
+        public void markModified() throws IOException {
+            throw new IOException("Editor is readonly");
+        }
+
+        public void unmarkModified() {
+            // Nothing to do.
+        }
+
+        public CloneableOpenSupport findCloneableOpenSupport() {
+            return editorSupport;
+        }
+
+        public void addPropertyChangeListener(PropertyChangeListener l) {
+            prop.addPropertyChangeListener(l);
+        }
+
+        public void removePropertyChangeListener(PropertyChangeListener l) {
+            prop.removePropertyChangeListener(l);
+        }
+
+        public void addVetoableChangeListener(VetoableChangeListener l) {
+            veto.addVetoableChangeListener(l);
+        }
+
+        public void removeVetoableChangeListener(VetoableChangeListener l) {
+            veto.removeVetoableChangeListener(l);
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/fold/FoldManager.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,81 @@
+package at.ssw.visualizer.texteditor.fold;
+
+import at.ssw.visualizer.texteditor.model.FoldingRegion;
+import at.ssw.visualizer.texteditor.model.Text;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.JComponent;
+import javax.swing.event.DocumentEvent;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import javax.swing.text.JTextComponent;
+import org.netbeans.api.editor.fold.Fold;
+import org.netbeans.editor.CodeFoldingSideBar;
+import org.netbeans.spi.editor.fold.FoldHierarchyTransaction;
+import org.netbeans.spi.editor.fold.FoldOperation;
+
+/**
+ *
+ * @author Alexander Reder
+ */
+public class FoldManager implements org.netbeans.spi.editor.fold.FoldManager {
+
+    protected FoldOperation operation;
+    
+    public void init(FoldOperation operation) {
+        this.operation = operation;
+    }
+
+    public void initFolds(FoldHierarchyTransaction transaction) {
+        Document document = operation.getHierarchy().getComponent().getDocument();
+        Text text = (Text) document.getProperty(Text.class);
+        if (document.getLength() == 0 || text == null) {
+            return;
+        }
+
+        try {
+            for (FoldingRegion fr : text.getFoldings()) {
+                operation.addToHierarchy(fr.getKind(), fr.getKind().toString(), fr.isInitiallyCollapsed(), fr.getStart(), fr.getEnd(), 0, 0, null, transaction);
+            }
+        } catch (BadLocationException ex) {
+            Logger logger = Logger.getLogger(FoldManager.class.getName());
+            logger.log(Level.SEVERE, ex.getMessage(), ex);
+        }
+    }
+
+    public void insertUpdate(DocumentEvent arg0, FoldHierarchyTransaction arg1) {
+    }
+
+    public void removeUpdate(DocumentEvent arg0, FoldHierarchyTransaction arg1) {
+    }
+
+    public void changedUpdate(DocumentEvent arg0, FoldHierarchyTransaction arg1) {
+    }
+
+    public void removeEmptyNotify(Fold arg0) {
+    }
+
+    public void removeDamagedNotify(Fold arg0) {
+    }
+
+    public void expandNotify(Fold arg0) {
+    }
+
+    public void release() {
+    }
+
+    public static class FoldManagerFactory implements org.netbeans.spi.editor.fold.FoldManagerFactory {
+
+        public FoldManager createFoldManager() {
+            return new FoldManager();
+        }
+    }
+
+    public static class SideBarFactory implements org.netbeans.editor.SideBarFactory {
+
+        public JComponent createSideBar(JTextComponent target) {
+            return new CodeFoldingSideBar(target);
+        }
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/highlight/HighlightsContainer.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,119 @@
+package at.ssw.visualizer.texteditor.highlight;
+
+import at.ssw.visualizer.texteditor.model.Scanner;
+import at.ssw.visualizer.texteditor.model.Text;
+import at.ssw.visualizer.texteditor.model.TextRegion;
+import javax.swing.event.CaretEvent;
+import javax.swing.event.CaretListener;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.Caret;
+import javax.swing.text.Document;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.SimpleAttributeSet;
+import org.netbeans.api.editor.mimelookup.MimeLookup;
+import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.api.editor.settings.FontColorSettings;
+import org.netbeans.editor.TokenID;
+import org.netbeans.spi.editor.highlighting.HighlightsSequence;
+import org.netbeans.spi.editor.highlighting.ZOrder;
+import org.netbeans.spi.editor.highlighting.support.AbstractHighlightsContainer;
+import org.openide.util.WeakListeners;
+
+/**
+ *
+ * @author Christian Wimmer
+ * @author Alexander Reder
+ */
+public class HighlightsContainer extends AbstractHighlightsContainer {
+
+    private static final String HIGHLIGHT_COLORING = "at-ssw-visualizer-highlight";
+    
+    protected final JTextComponent component;
+    protected final Document document;
+    protected final AttributeSet highlightColoring;
+    protected final Scanner scanner;
+
+    protected TextRegion[] curRegions = null;
+
+    private final CaretListener caretListener = new CaretListener() {
+
+        public void caretUpdate(CaretEvent event) {
+            TextRegion[] newRegions = findRegions();
+            if (newRegions != curRegions) {
+                curRegions = newRegions;
+                fireHighlightsChange(0, document.getLength());
+            }
+        }
+
+    };
+    
+    protected HighlightsContainer(JTextComponent component, Document document) {
+        this.document = document;
+        this.component = component;
+        component.addCaretListener(WeakListeners.create(CaretListener.class, caretListener, component));
+        
+        // Load the coloring.
+        Text t = (Text) document.getProperty(Text.class);
+        MimePath mimePath = MimePath.parse(t.getMimeType());
+        FontColorSettings fcs = MimeLookup.getLookup(mimePath).lookup(FontColorSettings.class);
+        AttributeSet highlight = fcs.getFontColors(HIGHLIGHT_COLORING);
+        highlightColoring = highlight != null ? highlight : SimpleAttributeSet.EMPTY;
+
+        scanner = t.getScanner();
+        scanner.setText(document);
+        curRegions = findRegions();
+    }
+
+    public HighlightsSequence getHighlights(int startOffset, int endOffset) {
+        return new RegionSequence();
+    }
+
+    protected TextRegion[] findRegions() {
+        Text text = (Text) document.getProperty(Text.class);
+        Caret caret = component.getCaret();
+        if (text == null || caret == null) {
+            return null;
+        }
+        scanner.findTokenBegin(caret.getDot());
+        TokenID token = scanner.nextToken();
+        if (token.getNumericID() < 0) {
+            return null;
+        }
+
+        return text.getHighlighting(scanner.getTokenString());
+    }
+
+    protected class RegionSequence implements HighlightsSequence {
+
+        private int idx = -1;
+
+        public boolean moveNext() {
+            idx++;
+            return curRegions != null && idx < curRegions.length;
+        }
+
+        public int getStartOffset() {
+            return curRegions[idx].getStart();
+        }
+
+        public int getEndOffset() {
+            return curRegions[idx].getEnd();
+        }
+
+        public AttributeSet getAttributes() {
+            return highlightColoring;
+        }
+    }
+
+    public static final class HighlightsLayerFactory implements org.netbeans.spi.editor.highlighting.HighlightsLayerFactory {
+
+        public org.netbeans.spi.editor.highlighting.HighlightsLayer[] createLayers(Context context) {
+            Text t = (Text) context.getDocument().getProperty(Text.class);
+            if(t == null) {
+                return new org.netbeans.spi.editor.highlighting.HighlightsLayer[0];
+            }
+            return new org.netbeans.spi.editor.highlighting.HighlightsLayer[]{org.netbeans.spi.editor.highlighting.HighlightsLayer.create("at-ssw-visualizer-highlighting", ZOrder.SHOW_OFF_RACK, true, new HighlightsContainer(context.getComponent(), context.getDocument()))};
+        }
+
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/hyperlink/HyperlinkProvider.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,57 @@
+package at.ssw.visualizer.texteditor.hyperlink;
+
+import at.ssw.visualizer.texteditor.model.Scanner;
+import at.ssw.visualizer.texteditor.model.Text;
+import at.ssw.visualizer.texteditor.model.TextRegion;
+import javax.swing.text.Document;
+import javax.swing.text.JTextComponent;
+import org.netbeans.editor.TokenID;
+import org.netbeans.editor.Utilities;
+
+/**
+ * 
+ * @author Bernhard Stiftner
+ * @author Christian Wimmer
+ * @author Alexander Reder
+ */
+public class HyperlinkProvider implements org.netbeans.lib.editor.hyperlink.spi.HyperlinkProvider {
+    
+    protected Scanner scanner = null;
+    
+    protected TextRegion findTarget(Document doc, int offset) {
+        Text text = (Text) doc.getProperty(Text.class);
+        if (text == null) {
+            return null;
+        }
+        
+        scanner = text.getScanner();
+        scanner.setText(doc);
+        scanner.findTokenBegin(offset);
+        TokenID token = scanner.nextToken();
+        if (token.getNumericID() < 0) {
+            return null;
+        }
+        
+        return text.getHyperlinkTarget(scanner.getTokenString());
+    }
+
+    public boolean isHyperlinkPoint(Document doc, int offset) {
+        return findTarget(doc, offset) != null;
+    }
+
+    public int[] getHyperlinkSpan(Document doc, int offset) {
+        if (findTarget(doc, offset) != null) {
+            return new int[]{scanner.getTokenOffset(), scanner.getTokenOffset() + scanner.getTokenLength()};
+        }
+        return null;
+    }
+
+    public void performClickAction(Document doc, int offset) {
+        TextRegion target = findTarget(doc, offset);
+        if (target != null) {
+            JTextComponent editor = Utilities.getFocusedComponent();
+            editor.select(target.getStart(), target.getEnd());
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/layer.xml	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,15 @@
+<?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="Editors\Preferences\Defaults\org-netbeans-modules-editor-preferences-mac.xml\position" intvalue="200"/>
+    <attr name="Editors\Preferences\Defaults\org-netbeans-modules-editor-preferences.xml\position" intvalue="100"/>
+    <folder name="Editors">
+        <folder name="Preferences">
+            <folder name="Defaults">
+                <file name="at-ssw-visualizer-texteditor-preferences.xml" url="preferences.xml">
+                    <attr name="position" intvalue="300"/>
+                </file>
+            </folder>
+        </folder>
+    </folder>
+</filesystem>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/BlockRegion.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,35 @@
+package at.ssw.visualizer.texteditor.model;
+
+import com.sun.hotspot.igv.data.InputBlock;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class BlockRegion extends TextRegion {
+
+    private InputBlock block;
+
+    private int nameStart;
+    private int nameEnd;
+
+    public BlockRegion(InputBlock block, int start, int end, int nameStart, int nameEnd) {
+        super(start, end);
+        this.block = block;
+        this.nameStart = nameStart;
+        this.nameEnd = nameEnd;
+    }
+
+
+    public InputBlock getBlock() {
+        return block;
+    }
+
+    public int getNameStart() {
+        return nameStart;
+    }
+
+    public int getNameEnd() {
+        return nameEnd;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/FoldingRegion.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,32 @@
+package at.ssw.visualizer.texteditor.model;
+
+import org.netbeans.api.editor.fold.FoldType;
+
+/**
+ *
+ * @author Christian Wimmer
+ * @author Alexander Reder
+ */
+public class FoldingRegion extends TextRegion {
+
+       
+    private FoldType kind;
+    private boolean initallyCollapsed;
+
+
+    public FoldingRegion(FoldType kind, int start, int end, boolean initiallyCollapsed) {
+        super(start, end);
+        this.kind = kind;
+        this.initallyCollapsed = initiallyCollapsed;
+    }
+
+    
+    public FoldType getKind() {
+        return kind;
+    }
+
+    public boolean isInitiallyCollapsed() {
+        return initallyCollapsed;
+    }
+        
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/HoverParser.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,117 @@
+package at.ssw.visualizer.texteditor.model;
+
+import java.util.Iterator;
+
+/**
+ *
+ * @author ChristianWimmer
+ */
+public class HoverParser implements Iterator<String> {
+
+    private static String HOVER_START = "<@";
+    private static String HOVER_SEP = "|@";
+    private static String HOVER_END = ">@";
+    private String text;
+    private int curPos;
+    private String curText;
+    private String curHover;
+    private boolean curNewLine;
+
+    public static String firstLine(String text) {
+        if (text == null) {
+            return "";
+        }
+        HoverParser p = new HoverParser(text);
+        StringBuilder result = new StringBuilder(text.length());
+        while (p.hasNext()) {
+            String part = p.next();
+            if (p.isNewLine()) {
+                break;
+            }
+            result.append(part);
+        }
+        return result.toString();
+    }
+
+    public HoverParser(String text) {
+        this.text = text;
+    }
+
+    private void advance() {
+        int lineStart = text.indexOf('\n', curPos);
+        int nextStart = text.indexOf(HOVER_START, curPos);
+
+        if (lineStart == curPos) {
+            curText = "\n";
+            curHover = null;
+            curPos = lineStart + 1;
+            curNewLine = true;
+            while (curPos < text.length() && text.charAt(curPos) <= ' ') {
+                curPos++;
+            }
+            return;
+        }
+        curNewLine = false;
+        if (lineStart != -1 && (nextStart == -1 || lineStart < nextStart)) {
+            curText = text.substring(curPos, lineStart);
+            curHover = null;
+            curPos = lineStart;
+            return;
+        }
+
+        if (nextStart == curPos) {
+            int nextSep = text.indexOf(HOVER_SEP, nextStart);
+            if (nextSep != -1) {
+                int nextEnd = text.indexOf(HOVER_END, nextSep);
+                if (nextEnd != -1) {
+                    curText = text.substring(nextStart + HOVER_START.length(), nextSep);
+                    curHover = text.substring(nextSep + HOVER_SEP.length(), nextEnd);
+                    while (curHover.endsWith("\n")) {
+                        curHover = curHover.substring(0, curHover.length() - 1);
+                    }
+                    curPos = nextEnd + HOVER_END.length();
+                    return;
+                }
+            }
+        }
+
+        if (nextStart == curPos) {
+            // Incomplete hover sequence. Make sure we make progress by just advancing to the next chararter.
+            nextStart++;
+        }
+
+        if (nextStart != -1) {
+            curText = text.substring(curPos, nextStart);
+            curHover = null;
+            curPos = nextStart;
+        } else if (curPos < text.length()) {
+            curText = text.substring(curPos);
+            curHover = null;
+            curPos = text.length();
+        } else {
+            curText = null;
+            curHover = null;
+        }
+    }
+
+    public boolean hasNext() {
+        return curPos < text.length();
+    }
+
+    public String next() {
+        advance();
+        return curText;
+    }
+
+    public String getHover() {
+        return curHover;
+    }
+
+    public boolean isNewLine() {
+        return curNewLine;
+    }
+
+    public void remove() {
+        throw new UnsupportedOperationException("Not supported.");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/Scanner.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,192 @@
+package at.ssw.visualizer.texteditor.model;
+
+import java.util.BitSet;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.swing.text.BadLocationException;
+import javax.swing.text.Document;
+import org.netbeans.editor.Syntax;
+import org.netbeans.editor.TokenContextPath;
+
+/**
+ * The implementing class must specify the used <code> TokenID</code>s and
+ * implement the scanner for the specified text.
+ * 
+ * @author Alexander Reder
+ * @author Christian Wimmer
+ */
+public abstract class Scanner extends Syntax {
+    protected static final int EOF = 0;
+    protected static final BitSet DIGIT = charsOf("0123456789");
+    protected static final BitSet HEX = charsOf("0123456789abcdefABCDEF");
+    protected static final BitSet LETTER = charsOf("_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+    protected static final BitSet LETTER_DIGIT = charsOf("0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ");
+    protected static final BitSet LC_LETTER = charsOf("_abcdefghijklmnopqrstuvwxyz");
+    protected static final BitSet LC_LETTER_DIGIT = charsOf("0123456789_abcdefghijklmnopqrstuvwxyz");
+
+    protected static BitSet charsOf(String s) {
+        BitSet result = new BitSet();
+        for (int i = 0; i < s.length(); i++) {
+            result.set(s.charAt(i));
+        }
+        return result;
+    }
+
+    protected BitSet whitespace;
+    protected char ch;
+
+    public Scanner(String whitespace, TokenContextPath tokenContextPath) {
+        this.whitespace = charsOf(whitespace);
+        this.whitespace.set(EOF);
+
+        this.tokenContextPath = tokenContextPath;
+    }
+
+    public void setText(Document document) {
+        try {
+            setText(document.getText(0, document.getLength()), 0, document.getLength());
+        } catch (BadLocationException ex) {
+            Logger logger = Logger.getLogger(Scanner.class.getName());
+            logger.log(Level.SEVERE, ex.getMessage(), ex);
+        }
+    }
+
+    public void setText(String s, int offset, int length) {
+        this.buffer = s.toCharArray();
+        this.offset = offset;
+        this.tokenOffset = offset;
+        this.stopOffset = Math.min(buffer.length, offset + length);
+    }
+
+    public String getTokenString() {
+        return new String(buffer, getTokenOffset(), getTokenLength());
+    }
+
+    public void findTokenBegin(int offset) {
+        this.offset = Math.max(offset, 0);
+        findTokenBegin();
+    }
+
+    /**
+     * If offset is in a token this method will read backwards until a
+     * whitespace character occurs.
+     */
+    protected void findTokenBegin() {
+        if (offset >= stopOffset) {
+            offset = stopOffset - 1;
+        }
+
+        if (!whitespace.get(buffer[offset])) {
+            while (offset > 0 && !whitespace.get(buffer[offset - 1])) {
+                offset--;
+            }
+        }
+        ch = buffer[offset];
+        tokenOffset = offset;
+    }
+
+    /**
+     * Reads the next character.
+     */
+    protected void readNext() {
+        offset++;
+        if (offset < stopOffset) {
+            ch = buffer[offset];
+        } else {
+            ch = EOF;
+        }
+    }
+
+    protected boolean isWhitespace() {
+        boolean result = false;
+        while (whitespace.get(ch) && ch != EOF) {
+            result = true;
+            readNext();
+        }
+        return result;
+    }
+
+    /**
+     * Read to the next whitespace
+     */
+    protected void readToWhitespace() {
+        do {
+            readNext();
+        } while (!whitespace.get(ch));
+    }
+
+    private boolean readNextOrRestart(boolean result, boolean readNext) {
+        if (result) {
+            if (readNext) {
+                readNext();
+            }
+        } else {
+            offset = tokenOffset;
+            ch = buffer[offset];
+        }
+        return result;
+    }
+
+    protected boolean isKeyword(Set<String> keywords) {
+        int beginOffset = offset;
+        int endOffset = offset;
+        while (endOffset < stopOffset && !whitespace.get(buffer[endOffset])) {
+            endOffset++;
+        }
+        String word = new String(buffer, beginOffset, endOffset - beginOffset);
+        if (!keywords.contains(word)) {
+            return false;
+        }
+
+        offset = endOffset - 1;
+        readNext();
+        return true;
+    }
+
+    protected boolean expectEnd() {
+        return readNextOrRestart(whitespace.get(ch), false);
+    }
+
+    protected boolean expectEnd(char expected) {
+        return readNextOrRestart(ch == expected, false) && offset + 1 < stopOffset && whitespace.get(buffer[offset + 1]);
+    }
+
+    protected boolean expectChar(char expected) {
+        return readNextOrRestart(ch == expected, true);
+    }
+
+    protected boolean expectChar(BitSet expected) {
+        return readNextOrRestart(expected.get(ch), true);
+    }
+
+    protected boolean expectChars(BitSet expected) {
+        while (expected.get(ch)) {
+            readNext();
+        }
+        return true;
+    }
+
+    protected boolean skipUntil(char expected) {
+        while (ch != expected && !whitespace.get(ch)) {
+            readNext();
+        }
+        return expectChar(expected);
+    }
+
+    protected boolean beforeChar(char before) {
+        int curOffset = offset - 1;
+        while (curOffset >= 0 && buffer[curOffset] != before && whitespace.get(buffer[curOffset])) {
+            curOffset--;
+        }
+        return curOffset >= 0 && buffer[curOffset] == before;
+    }
+
+    protected boolean beforeChars(BitSet before) {
+        int curOffset = offset - 1;
+        while (curOffset >= 0 && !before.get(buffer[curOffset]) && whitespace.get(buffer[curOffset])) {
+            curOffset--;
+        }
+        return curOffset >= 0 && before.get(buffer[curOffset]);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/Text.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,83 @@
+package at.ssw.visualizer.texteditor.model;
+
+import com.sun.hotspot.igv.data.InputBlock;
+import com.sun.hotspot.igv.data.InputGraph;
+import java.util.Map;
+
+/**
+ * @author Christian Wimmer
+ * @author Alexander Reder
+ */
+public class Text {
+
+    private InputGraph cfg;
+
+    private String text;
+    private FoldingRegion[] foldings;
+    private Map<String, TextRegion> hyperlinks;
+    private Map<String, String> stringHovers;
+    private Map<TextRegion, String> regionHovers;
+    private Map<String, TextRegion[]> highlighting;
+    private Map<InputBlock, BlockRegion> blocks;
+    private Scanner scanner;
+    private String mimeType;
+
+    
+    public Text(InputGraph cfg, String text, FoldingRegion[] foldings, Map<String, TextRegion> hyperlinks, Map<String, String> stringHovers, Map<TextRegion, String> regionHovers, Map<String, TextRegion[]> highlighting, Map<InputBlock, BlockRegion> blocks, Scanner scanner, String mimeType) {
+        this.cfg = cfg;
+        this.text = text;
+        this.foldings = foldings;
+        this.hyperlinks = hyperlinks;
+        this.stringHovers = stringHovers;
+        this.regionHovers = regionHovers;
+        this.highlighting = highlighting;
+        this.blocks = blocks;
+        this.scanner = scanner;
+        this.mimeType = mimeType;
+    }
+
+    public InputGraph getCfg() {
+        return cfg;
+    }
+
+    public String getText() {
+        return text;
+    }
+
+    public FoldingRegion[] getFoldings() {
+        return foldings;
+    }
+
+    public TextRegion getHyperlinkTarget(String key) {
+        return hyperlinks.get(key);
+    }
+
+    public String getStringHover(String key) {
+        return stringHovers.get(key);
+    }
+
+    public String getRegionHover(int position) {
+        for (TextRegion r : regionHovers.keySet()) {
+            if (r.getStart() <= position && r.getEnd() >= position) {
+                return regionHovers.get(r);
+            }
+        }
+        return null;
+    }
+
+    public TextRegion[] getHighlighting(String key) {
+        return highlighting.get(key);
+    }
+
+    public Map<InputBlock, BlockRegion> getBlocks() {
+        return blocks;
+    }
+    
+    public Scanner getScanner() {
+        return scanner;
+    }
+    
+    public String getMimeType() {
+        return mimeType;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/TextBuilder.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,102 @@
+package at.ssw.visualizer.texteditor.model;
+
+import com.sun.hotspot.igv.data.InputBlock;
+import com.sun.hotspot.igv.data.InputGraph;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ *
+ * @author Alexander Reder
+ */
+public abstract class TextBuilder {
+
+    protected StringBuilder text;
+    protected Scanner scanner;
+    protected List<FoldingRegion> foldingRegions;
+    protected Map<String, TextRegion> hyperlinks;
+    protected Map<String, String> stringHovers;
+    protected Map<TextRegion, String> regionHovers;
+    protected Map<String, TextRegion[]> highlighting;
+    protected Map<InputBlock, BlockRegion> blocks;
+    protected Set<String> hoverKeys;
+    protected Map<String, String> hoverDefinitions;
+    protected Map<String, List<String>> hoverReferences;
+    
+    public TextBuilder() {
+        text = new StringBuilder(4 * 1024);
+        foldingRegions = new ArrayList<FoldingRegion>();
+        hyperlinks = new HashMap<String, TextRegion>();
+        stringHovers = new HashMap<String, String>();
+        regionHovers = new HashMap<TextRegion, String>();
+        highlighting = new HashMap<String, TextRegion[]>();
+        blocks = new HashMap<InputBlock, BlockRegion>();
+        hoverKeys = new HashSet<String>();
+        hoverDefinitions = new HashMap<String, String>();
+        hoverReferences = new HashMap<String, List<String>>();
+    }
+    
+    public abstract Text buildDocument(InputGraph cfg);
+    
+    protected abstract void buildHighlighting();
+    
+    protected Text buildText(InputGraph cfg, String mimeType) {
+        buildHovers();
+        buildHighlighting();
+        return new Text(cfg, text.toString(), foldingRegions.toArray(new FoldingRegion[foldingRegions.size()]), hyperlinks, stringHovers, regionHovers, highlighting, blocks, scanner, mimeType);
+    }
+    
+    protected void appendBlockDetails(InputBlock block) {
+        text.append(blockDetails(block));
+    }
+        
+    protected String blockDetails(InputBlock block) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(block.getName());
+        hoverKeys.add(block.getName());
+        // TODO: predecessors, successors, BCI, ...
+        return sb.toString();
+    }
+    
+    protected void appendBlockList(StringBuilder sb, String prefix, List<InputBlock> blocks) {
+        for (InputBlock block : blocks) {
+            sb.append(prefix);
+            prefix = ",";
+            sb.append(block.getName());
+        }
+    }
+    
+    private void appendList(StringBuilder sb, String prefix, List<String> values) {
+        for (String value : values) {
+            sb.append(prefix).append(value);
+            prefix = ",";
+        }
+    }
+    
+    protected void buildHovers() {
+        StringBuilder sb;
+        for(String key : hoverKeys) {
+            sb = new StringBuilder();
+            if(hoverDefinitions.containsKey(key) && hoverReferences.containsKey(key)) {
+                sb.append("Definition;\n");
+                sb.append(hoverDefinitions.get(key));
+                sb.append("\n");
+            }
+            if(hoverReferences.containsKey(key)) {
+                sb.append("References:\n");
+                for(String ref : hoverReferences.get(key)) {
+                    sb.append(ref);
+                    sb.append("\n");
+                }
+            }
+            if(sb.length() > 0) {
+                stringHovers.put(key, sb.toString().substring(0, sb.length() - 1));
+            }            
+        }
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/TextRegion.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,27 @@
+package at.ssw.visualizer.texteditor.model;
+
+/**
+ *
+ * @author Christian Wimmer
+ * @author Alexander Reder
+ */
+public class TextRegion {
+    
+    private int start;
+    private int end;
+
+    public TextRegion(int start, int end) {
+        this.start = start;
+        this.end = end;
+    }
+
+    
+    public int getStart() {
+        return start;
+    }
+
+    public int getEnd() {
+        return end;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/preferences.xml	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE editor-preferences PUBLIC "-//NetBeans//DTD Editor Preferences 1.0//EN" "http://www.netbeans.org/dtds/EditorPreferences-1_0.dtd">
+
+<editor-preferences>
+    <entry name="code-folding-enable" value="true" javaType="java.lang.Boolean" />
+</editor-preferences>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/tooltip/StyledToolTip.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,57 @@
+package at.ssw.visualizer.texteditor.tooltip;
+
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import javax.swing.JEditorPane;
+import javax.swing.JPanel;
+import javax.swing.border.LineBorder;
+import javax.swing.text.EditorKit;
+
+/**
+ *
+ * @author Bernhard Stiftner
+ * @author Christian Wimmer
+ * @author Alexander Reder
+ */
+public class StyledToolTip extends JPanel {
+
+    public static final int BORDER = 2;
+
+    private final String text;
+    private final JEditorPane toolTipPane;
+
+    public StyledToolTip(String text, EditorKit editorKit) {
+        this.text = text;
+
+        setBackground(new Color(235, 235, 163));
+        setBorder(new LineBorder(Color.BLACK));
+        setOpaque(true);
+        setLayout(new BorderLayout());
+
+        toolTipPane = new JEditorPane();
+        toolTipPane.setEditable(false);
+        toolTipPane.setEditorKit(editorKit);
+        toolTipPane.setText(text);
+
+        add(toolTipPane, BorderLayout.CENTER);
+    }
+
+    @Override
+    public Dimension getPreferredSize() {
+        // Workaround: JEditorPane does not provide a proper width (only few pixels),
+        //             so make the tooltip as large as the editor it is shown in
+        Dimension prefSize = super.getPreferredSize();
+        prefSize.width = Integer.MAX_VALUE;
+        return prefSize;
+    }
+
+    @Override
+    protected void paintComponent(Graphics g) {
+        // Workaround: Add a new line at the end so that the caret is not in the visible area.
+        toolTipPane.setText(text + "\n");
+
+        super.paintComponent(g);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/tooltip/ToolTipAction.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,67 @@
+package at.ssw.visualizer.texteditor.tooltip;
+
+import at.ssw.visualizer.texteditor.model.Scanner;
+import at.ssw.visualizer.texteditor.model.Text;
+import java.awt.event.ActionEvent;
+import javax.swing.text.JTextComponent;
+import org.netbeans.api.editor.EditorActionRegistration;
+import org.netbeans.editor.BaseDocument;
+import org.netbeans.editor.EditorUI;
+import org.netbeans.editor.PopupManager;
+import org.netbeans.editor.TokenID;
+import org.netbeans.editor.Utilities;
+import org.netbeans.editor.ext.ExtKit;
+import org.netbeans.editor.ext.ToolTipSupport;
+import org.netbeans.modules.editor.NbEditorKit;
+
+/**
+ *
+ * @author Christian Wimmer
+ * @author Alexander Reder
+ */
+public class ToolTipAction extends NbEditorKit.NbBuildToolTipAction {
+    public ToolTipAction() {
+        putValue(NAME, ExtKit.buildToolTipAction);
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent evt, JTextComponent target) {
+        if (!showTooltip(target)) {
+            super.actionPerformed(evt, target);
+        }
+    }
+    
+    private boolean showTooltip(JTextComponent target) {
+        BaseDocument document = Utilities.getDocument(target);
+        Text text = (Text) document.getProperty(Text.class);
+        if (text == null) {
+            return false;
+        }
+
+        EditorUI ui = Utilities.getEditorUI(target);  
+        ToolTipSupport tts = ui.getToolTipSupport();
+        int offset = target.viewToModel(tts.getLastMouseEvent().getPoint());
+
+        String toolTipText = text.getRegionHover(offset);
+
+        if (toolTipText == null) {
+            Scanner scanner = text.getScanner();
+            scanner.setText(document);
+            scanner.findTokenBegin(offset);
+            TokenID token = scanner.nextToken();
+            if (token.getNumericID() < 0) {
+                return false;
+            }
+
+            toolTipText = text.getStringHover(scanner.getTokenString());
+            if (toolTipText == null) {
+                return false;
+            }
+        }
+
+        StyledToolTip tooltip = new StyledToolTip(toolTipText, target.getUI().getEditorKit(target));
+
+        tts.setToolTip(tooltip, PopupManager.ViewPortBounds, PopupManager.Largest, 0, 0);
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/view/AbstractTextViewTopComponent.java	Tue Jun 07 11:19:01 2011 +0200
@@ -0,0 +1,78 @@
+package at.ssw.visualizer.texteditor.view;
+
+import at.ssw.visualizer.core.selection.Selection;
+import at.ssw.visualizer.core.selection.SelectionManager;
+import at.ssw.visualizer.texteditor.EditorKit;
+import com.sun.hotspot.igv.data.InputBlock;
+import com.sun.hotspot.igv.data.InputGraph;
+import java.awt.BorderLayout;
+import java.util.Arrays;
+import javax.swing.BorderFactory;
+import javax.swing.JEditorPane;
+import javax.swing.JScrollPane;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import org.openide.windows.TopComponent;
+
+/**
+ *
+ * @author Alexander Reder
+ */
+public abstract class AbstractTextViewTopComponent extends TopComponent {
+    
+    protected InputGraph curCFG;
+    protected InputBlock[] curBlocks;
+
+    private JEditorPane editorPane;
+    
+    // EditorKit must be set in the imlementation class
+    public AbstractTextViewTopComponent(EditorKit kit) {
+        editorPane = new JEditorPane();
+        editorPane.setEditorKit(kit);
+        editorPane.setEditable(false);
+        JScrollPane scrollPane = new JScrollPane(editorPane);
+        scrollPane.setViewportBorder(BorderFactory.createEmptyBorder());
+        scrollPane.setBorder(BorderFactory.createEmptyBorder());
+        setLayout(new BorderLayout());
+        add(scrollPane);
+    }
+
+    @Override
+    protected void componentShowing() {
+        super.componentShowing();
+        SelectionManager.getDefault().addChangeListener(selectionChangeListener);
+        updateContent();
+    }
+
+    @Override
+    protected void componentHidden() {
+        super.componentHidden();
+        SelectionManager.getDefault().removeChangeListener(selectionChangeListener);
+        curCFG = null;
+        curBlocks = null;
+    }
+
+
+    private ChangeListener selectionChangeListener = new ChangeListener() {
+        public void stateChanged(ChangeEvent event) {
+            updateContent();
+        }
+    };
+
+    protected void updateContent() {
+        Selection selection = SelectionManager.getDefault().getCurSelection();
+        InputGraph newCFG = selection.get(InputGraph.class);
+        InputBlock[] newBlocks = selection.get(InputBlock[].class);
+
+        if (newCFG == null || newBlocks == null || newBlocks.length == 0) {
+            editorPane.setText("No block selected\n");
+        } else if (curCFG != newCFG || !Arrays.equals(curBlocks, newBlocks)) {
+            editorPane.setText(getContent(newCFG, newBlocks));
+        }
+        curCFG = newCFG;
+        curBlocks = newBlocks;
+    }
+
+    protected abstract String getContent(InputGraph cfg, InputBlock[] blocks);
+    
+}
--- a/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties	Tue Jun 07 11:18:18 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/nbproject/platform.properties	Tue Jun 07 11:19:01 2011 +0200
@@ -1,13 +1,173 @@
 cluster.path=\
+    ${nbplatform.active.dir}/ide:\
     ${nbplatform.active.dir}/platform
 disabled.modules=\
+    org.apache.xml.resolver,\
+    org.mozilla.rhino.patched,\
+    org.netbeans.api.debugger,\
+    org.netbeans.api.java.classpath,\
+    org.netbeans.api.xml,\
+    org.netbeans.core.browser,\
     org.netbeans.core.execution,\
+    org.netbeans.core.ide,\
     org.netbeans.core.multiview,\
+    org.netbeans.lib.cvsclient,\
+    org.netbeans.lib.terminalemulator,\
+    org.netbeans.libs.antlr3.runtime,\
+    org.netbeans.libs.bugtracking,\
+    org.netbeans.libs.bugzilla,\
+    org.netbeans.libs.bytelist,\
+    org.netbeans.libs.commons_codec,\
+    org.netbeans.libs.commons_logging,\
+    org.netbeans.libs.commons_net,\
+    org.netbeans.libs.freemarker,\
+    org.netbeans.libs.ini4j,\
+    org.netbeans.libs.jakarta_oro,\
+    org.netbeans.libs.jaxb,\
+    org.netbeans.libs.jsch,\
     org.netbeans.libs.jsr223,\
+    org.netbeans.libs.jvyamlb,\
+    org.netbeans.libs.jzlib,\
+    org.netbeans.libs.lucene,\
+    org.netbeans.libs.smack,\
+    org.netbeans.libs.svnClientAdapter,\
+    org.netbeans.libs.svnClientAdapter.javahl,\
+    org.netbeans.libs.svnClientAdapter.svnkit,\
+    org.netbeans.libs.swingx,\
+    org.netbeans.libs.xerces,\
     org.netbeans.modules.autoupdate.services,\
     org.netbeans.modules.autoupdate.ui,\
+    org.netbeans.modules.bugtracking,\
+    org.netbeans.modules.bugtracking.bridge,\
+    org.netbeans.modules.bugzilla,\
     org.netbeans.modules.core.kit,\
+    org.netbeans.modules.csl.api,\
+    org.netbeans.modules.css.editor,\
+    org.netbeans.modules.css.visual,\
+    org.netbeans.modules.db,\
+    org.netbeans.modules.db.core,\
+    org.netbeans.modules.db.dataview,\
+    org.netbeans.modules.db.drivers,\
+    org.netbeans.modules.db.kit,\
+    org.netbeans.modules.db.metadata.model,\
+    org.netbeans.modules.db.mysql,\
+    org.netbeans.modules.db.sql.editor,\
+    org.netbeans.modules.db.sql.visualeditor,\
+    org.netbeans.modules.dbapi,\
+    org.netbeans.modules.defaults,\
+    org.netbeans.modules.derby,\
+    org.netbeans.modules.diff,\
+    org.netbeans.modules.dlight.nativeexecution,\
+    org.netbeans.modules.dlight.terminal,\
+    org.netbeans.modules.editor.bookmarks,\
+    org.netbeans.modules.editor.bracesmatching,\
+    org.netbeans.modules.editor.codetemplates,\
+    org.netbeans.modules.editor.completion,\
+    org.netbeans.modules.editor.errorstripe,\
+    org.netbeans.modules.editor.errorstripe.api,\
+    org.netbeans.modules.editor.guards,\
+    org.netbeans.modules.editor.indent.project,\
+    org.netbeans.modules.editor.kit,\
+    org.netbeans.modules.editor.macros,\
+    org.netbeans.modules.editor.plain,\
+    org.netbeans.modules.editor.plain.lib,\
+    org.netbeans.modules.editor.structure,\
+    org.netbeans.modules.extbrowser,\
+    org.netbeans.modules.extexecution,\
+    org.netbeans.modules.extexecution.destroy,\
     org.netbeans.modules.favorites,\
+    org.netbeans.modules.glassfish.common,\
+    org.netbeans.modules.gototest,\
+    org.netbeans.modules.gsf.codecoverage,\
+    org.netbeans.modules.gsf.testrunner,\
+    org.netbeans.modules.html,\
+    org.netbeans.modules.html.editor,\
+    org.netbeans.modules.html.editor.lib,\
+    org.netbeans.modules.html.lexer,\
+    org.netbeans.modules.html.parser,\
+    org.netbeans.modules.html.validation,\
+    org.netbeans.modules.httpserver,\
+    org.netbeans.modules.hudson,\
+    org.netbeans.modules.hudson.mercurial,\
+    org.netbeans.modules.hudson.subversion,\
+    org.netbeans.modules.ide.kit,\
+    org.netbeans.modules.image,\
+    org.netbeans.modules.javascript.editing,\
+    org.netbeans.modules.javascript.hints,\
+    org.netbeans.modules.javascript.kit,\
+    org.netbeans.modules.javascript.refactoring,\
+    org.netbeans.modules.jellytools.ide,\
+    org.netbeans.modules.jumpto,\
+    org.netbeans.modules.languages,\
+    org.netbeans.modules.languages.diff,\
+    org.netbeans.modules.languages.manifest,\
+    org.netbeans.modules.languages.yaml,\
+    org.netbeans.modules.lexer.nbbridge,\
+    org.netbeans.modules.localhistory,\
+    org.netbeans.modules.mercurial,\
+    org.netbeans.modules.options.editor,\
+    org.netbeans.modules.parsing.api,\
+    org.netbeans.modules.parsing.lucene,\
+    org.netbeans.modules.print.editor,\
+    org.netbeans.modules.project.ant,\
+    org.netbeans.modules.project.libraries,\
+    org.netbeans.modules.projectapi,\
+    org.netbeans.modules.projectui,\
+    org.netbeans.modules.projectui.buildmenu,\
+    org.netbeans.modules.projectuiapi,\
+    org.netbeans.modules.properties,\
+    org.netbeans.modules.properties.syntax,\
+    org.netbeans.modules.refactoring.api,\
+    org.netbeans.modules.schema2beans,\
+    org.netbeans.modules.server,\
+    org.netbeans.modules.servletapi,\
+    org.netbeans.modules.spellchecker,\
+    org.netbeans.modules.spellchecker.apimodule,\
+    org.netbeans.modules.spellchecker.bindings.htmlxml,\
+    org.netbeans.modules.spellchecker.bindings.properties,\
+    org.netbeans.modules.spellchecker.dictionary_en,\
+    org.netbeans.modules.spellchecker.kit,\
+    org.netbeans.modules.subversion,\
+    org.netbeans.modules.swing.validation,\
+    org.netbeans.modules.target.iterator,\
+    org.netbeans.modules.tasklist.kit,\
+    org.netbeans.modules.tasklist.projectint,\
+    org.netbeans.modules.tasklist.todo,\
+    org.netbeans.modules.tasklist.ui,\
+    org.netbeans.modules.terminal,\
+    org.netbeans.modules.usersguide,\
+    org.netbeans.modules.utilities,\
+    org.netbeans.modules.utilities.project,\
+    org.netbeans.modules.versioning,\
+    org.netbeans.modules.versioning.indexingbridge,\
+    org.netbeans.modules.versioning.system.cvss,\
+    org.netbeans.modules.versioning.util,\
+    org.netbeans.modules.web.client.tools.api,\
+    org.netbeans.modules.web.common,\
+    org.netbeans.modules.xml,\
+    org.netbeans.modules.xml.axi,\
+    org.netbeans.modules.xml.catalog,\
+    org.netbeans.modules.xml.core,\
+    org.netbeans.modules.xml.jaxb.api,\
+    org.netbeans.modules.xml.lexer,\
+    org.netbeans.modules.xml.multiview,\
+    org.netbeans.modules.xml.retriever,\
+    org.netbeans.modules.xml.schema.completion,\
+    org.netbeans.modules.xml.schema.model,\
+    org.netbeans.modules.xml.tax,\
+    org.netbeans.modules.xml.text,\
+    org.netbeans.modules.xml.tools,\
+    org.netbeans.modules.xml.wsdl.model,\
+    org.netbeans.modules.xml.xam,\
+    org.netbeans.modules.xml.xdm,\
+    org.netbeans.modules.xsl,\
+    org.netbeans.spi.debugger.ui,\
+    org.netbeans.spi.editor.hints,\
+    org.netbeans.spi.navigator,\
+    org.netbeans.spi.palette,\
+    org.netbeans.spi.tasklist,\
+    org.netbeans.spi.viewmodel,\
+    org.netbeans.swing.dirchooser,\
     org.openide.compat,\
     org.openide.execution,\
     org.openide.options,\
--- a/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Tue Jun 07 11:18:18 2011 +0200
+++ b/src/share/tools/IdealGraphVisualizer/nbproject/project.properties	Tue Jun 07 11:19:01 2011 +0200
@@ -17,7 +17,9 @@
     ${project.com.sun.hotspot.igv.svg}:\
     ${project.com.sun.hotspot.connection}:\
     ${project.com.sun.hotspot.igv.servercompiler}:\
-    ${project.com.sun.hotspot.igv.filterwindow}
+    ${project.com.sun.hotspot.igv.filterwindow}:\
+    ${project.at.ssw.visualizer.texteditor}
+project.at.ssw.visualizer.texteditor=Text Editor
 project.com.sun.hotspot.connection=NetworkConnection
 project.com.sun.hotspot.igv.bytecodes=Bytecodes
 project.com.sun.hotspot.igv.controlflow=ControlFlow