changeset 2843:6960cc79f664

IdealGraphVisualizer: Import editor component from C1XVisualizer
author Peter Hofer <peter.hofer@jku.at>
date Wed, 01 Jun 2011 15:22:40 +0200
parents 7596ae867a7b
children fa6fd3974058
files src/share/tools/IdealGraphVisualizer/Text Editor/build.xml src/share/tools/IdealGraphVisualizer/Text Editor/manifest.mf src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/build-impl.xml src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/genfiles.properties src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/platform.properties src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/project.properties src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/project.xml src/share/tools/IdealGraphVisualizer/Text Editor/nbproject/suite.properties src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/Bundle.properties src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/Editor.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/EditorKit.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/EditorSupport.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/fold/FoldManager.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/highlight/HighlightsContainer.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/hyperlink/HyperlinkProvider.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/layer.xml src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/BlockRegion.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/FoldingRegion.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/HoverParser.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/Scanner.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/Text.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/TextBuilder.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/model/TextRegion.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/preferences.xml src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/tooltip/StyledToolTip.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/tooltip/ToolTipAction.java src/share/tools/IdealGraphVisualizer/Text Editor/src/at/ssw/visualizer/texteditor/view/AbstractTextViewTopComponent.java
diffstat 27 files changed, 1744 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/share/tools/IdealGraphVisualizer/Text Editor/build.xml	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 2011 +0200
@@ -0,0 +1,8 @@
+build.xml.data.CRC32=d16e475b
+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=d16e475b
+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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 2011 +0200
@@ -0,0 +1,152 @@
+<?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>at.ssw.visualizer</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <run-dependency/>
+                </dependency>
+                <dependency>
+                    <code-name-base>at.ssw.visualizer.model</code-name-base>
+                    <build-prerequisite/>
+                    <compile-dependency/>
+                    <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	Wed Jun 01 15:22:40 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/texteditor/Bundle.properties	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 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.model.cfg.BasicBlock;
+import at.ssw.visualizer.texteditor.model.BlockRegion;
+import at.ssw.visualizer.texteditor.model.Text;
+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 BasicBlock[] 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);
+            BasicBlock[] newBlocks = selection.get(BasicBlock[].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 (BasicBlock 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<BasicBlock> newBlocks = new ArrayList<BasicBlock>();
+            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 BasicBlock[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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 2011 +0200
@@ -0,0 +1,151 @@
+package at.ssw.visualizer.texteditor;
+
+import at.ssw.visualizer.model.Compilation;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.texteditor.model.Text;
+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 ControlFlowGraph cfg;
+    protected Text text;
+
+    protected EditorSupport(ControlFlowGraph cfg) {
+        super(new Env());
+        ((Env) this.env).editorSupport = this;
+        this.cfg = cfg;
+    }
+    
+    public ControlFlowGraph 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(Compilation.class, cfg.getCompilation());
+        doc.putProperty(ControlFlowGraph.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.getCompilation().getShortName();
+    }
+
+    protected String messageToolTip() {
+        return cfg.getCompilation().getMethod() + " - " + 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() {
+            return editorSupport.cfg.getCompilation().getDate();
+        }
+
+        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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 2011 +0200
@@ -0,0 +1,35 @@
+package at.ssw.visualizer.texteditor.model;
+
+import at.ssw.visualizer.model.cfg.BasicBlock;
+
+/**
+ *
+ * @author Christian Wimmer
+ */
+public class BlockRegion extends TextRegion {
+
+    private BasicBlock block;
+
+    private int nameStart;
+    private int nameEnd;
+
+    public BlockRegion(BasicBlock block, int start, int end, int nameStart, int nameEnd) {
+        super(start, end);
+        this.block = block;
+        this.nameStart = nameStart;
+        this.nameEnd = nameEnd;
+    }
+
+
+    public BasicBlock 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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 2011 +0200
@@ -0,0 +1,91 @@
+package at.ssw.visualizer.texteditor.model;
+
+import at.ssw.visualizer.model.Compilation;
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import java.util.Map;
+
+/**
+ * @author Christian Wimmer
+ * @author Alexander Reder
+ */
+public class Text {
+
+    private Compilation compilation;
+    private ControlFlowGraph 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<BasicBlock, BlockRegion> blocks;
+    private Scanner scanner;
+    private String mimeType;
+
+    
+    public Text(ControlFlowGraph cfg, String text, FoldingRegion[] foldings, Map<String, TextRegion> hyperlinks, Map<String, String> stringHovers, Map<TextRegion, String> regionHovers, Map<String, TextRegion[]> highlighting, Map<BasicBlock, BlockRegion> blocks, Scanner scanner, String mimeType) {
+        this.compilation = cfg.getCompilation();
+        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 Compilation getCompilation() {
+        return compilation;
+    }
+
+    public ControlFlowGraph 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<BasicBlock, 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	Wed Jun 01 15:22:40 2011 +0200
@@ -0,0 +1,113 @@
+package at.ssw.visualizer.texteditor.model;
+
+import at.ssw.visualizer.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+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<BasicBlock, 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<BasicBlock, BlockRegion>();
+        hoverKeys = new HashSet<String>();
+        hoverDefinitions = new HashMap<String, String>();
+        hoverReferences = new HashMap<String, List<String>>();
+    }
+    
+    public abstract Text buildDocument(ControlFlowGraph cfg);
+    
+    protected abstract void buildHighlighting();
+    
+    protected Text buildText(ControlFlowGraph 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(BasicBlock block) {
+        text.append(blockDetails(block));
+    }
+        
+    protected String blockDetails(BasicBlock block) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(block.getName());
+        hoverKeys.add(block.getName());
+        appendBlockList(sb, " <- ", block.getPredecessors());
+        appendBlockList(sb, " -> ", block.getSuccessors());
+        appendBlockList(sb, " xh ", block.getXhandlers());
+        if (block.getDominator() != null) {
+            sb.append(" dom ").append(block.getDominator().getName());
+        }
+        sb.append(" [").append(block.getFromBci()).append(", ").append(block.getToBci()).append("]");
+        appendList(sb, " ", block.getFlags());
+
+        if (block.getLoopDepth() > 0) {
+            sb.append(" (loop ").append(block.getLoopIndex()).append(" depth ").append(block.getLoopDepth()).append(")");
+        }
+        return sb.toString();
+    }
+    
+    protected void appendBlockList(StringBuilder sb, String prefix, List<BasicBlock> blocks) {
+        for (BasicBlock 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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 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	Wed Jun 01 15:22:40 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.model.cfg.BasicBlock;
+import at.ssw.visualizer.model.cfg.ControlFlowGraph;
+import at.ssw.visualizer.texteditor.EditorKit;
+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 ControlFlowGraph curCFG;
+    protected BasicBlock[] 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();
+        ControlFlowGraph newCFG = selection.get(ControlFlowGraph.class);
+        BasicBlock[] newBlocks = selection.get(BasicBlock[].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(ControlFlowGraph cfg, BasicBlock[] blocks);
+    
+}