changeset 166:71ec57b4c8f3

merge
author Frank Benoit <benoit@tionex.de>
date Mon, 08 Sep 2008 01:38:10 +0200
parents 20cdc983a411 (current diff) e5dd0081ccba (diff)
children 3b8f773f35e4
files dsss.conf dwtx/core/runtime/jobs/package.html
diffstat 481 files changed, 129604 insertions(+), 27 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/collectionimp.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,93 @@
+module packageimport;
+
+import tango.io.FilePath;
+import tango.io.File;
+import tango.io.Buffer;
+import tango.io.stream.FileStream;
+import tango.io.stream.TextFileStream;
+import tango.util.log.Trace;
+import tango.text.Regex;
+import tango.text.Util;
+import tango.text.stream.LineIterator;
+import tango.text.convert.Format;
+
+const char[][] javaimps = [
+"import java.util.ArrayList;", 
+"import java.util.Arrays;", 
+"import java.util.Collection;", 
+"import java.util.Collections;", 
+"import java.util.HashMap;", 
+"import java.util.HashSet;", 
+"import java.util.IdentityHashMap;", 
+"import java.util.Iterator;", 
+"import java.util.LinkedHashMap;", 
+"import java.util.LinkedList;", 
+"import java.util.List;", 
+"import java.util.ListIterator;", 
+"import java.util.Map;", 
+"import java.util.Map.Entry;", 
+"import java.util.Set;", 
+"import java.util.Comparator;", 
+"import java.util.Stack;"
+];
+void processDir( char[] dir ){
+    auto pack = dir.dup.replace( '/', '.' );
+    auto fp = FilePath(dir);
+    char[][] mods;
+    // read all module names
+    foreach( fileinfo; fp ){
+        if( fileinfo.folder ){
+            processDir( fileinfo.path ~ fileinfo.name );
+            continue;
+        }
+        if( fileinfo.name.length > 2 && fileinfo.name[ $-2 .. $ ] == ".d" ){
+            mods ~= fileinfo.name.dup;
+        }
+    }
+    // foreach module
+    foreach( mod; mods ){
+        auto filename = Format("{}/{}", dir, mod );
+        auto cont = cast(char[])File( filename ).read;
+        char[][] lines = cont.splitLines();
+        char[][] outlines = lines.dup;
+        bool found = true;
+        foreach( uint idx, char[] line; lines ){
+            foreach( javaimp; javaimps ){
+                if( line == javaimp ){
+                    outlines[idx] = found ? "import dwtx.dwtxhelper.Collection;" : "";
+                    found = false;
+                }
+            }
+        }
+        if( !found ){
+            Trace.formatln( "{} ", filename );
+            bool first = true;
+            auto output = new TextFileOutput( filename );
+            foreach( line; outlines ){
+                if( !first ){
+                    output.write( \n );
+                }
+                first = false;
+                output.write( line );
+            }
+            output.flush();
+            output.close();
+        }
+    }
+        // read content into buffer
+        // search module statement and print to outfile
+        // write package imports
+        // write all remaining lines
+}
+
+void main(){
+    processDir( "dwtx/text" );
+    processDir( "dwtx/jface/text" );
+    processDir( "dwtx/jface/internal/text" );
+}
+
+
+
+
+
+
--- a/dsss.conf	Mon Sep 08 01:37:00 2008 +0200
+++ b/dsss.conf	Mon Sep 08 01:38:10 2008 +0200
@@ -1,7 +1,17 @@
 
+
+[fixmodule.d]
+[collectionimp.d]
 [dwtx]
 type=library
 buildflags+=-Jres
+
+#exclude the incomplete JFace.Text
+exclude+=dwtx/text
+exclude+=dwtx/jface/contentassist
+exclude+=dwtx/jface/text
+exclude+=dwtx/jface/internal/text
+
 version(linux){
     buildflags+=-I../dwt-linux
 }
--- a/dwtx/core/internal/jobs/ThreadJob.d	Mon Sep 08 01:37:00 2008 +0200
+++ b/dwtx/core/internal/jobs/ThreadJob.d	Mon Sep 08 01:38:10 2008 +0200
@@ -119,7 +119,7 @@
         String msg = buf.toString();
         if (JobManager.DEBUG || JobManager.DEBUG_BEGIN_END) {
             Stdout.formatln("{}",msg);
-            Exception t = lastPush is null ? new IllegalArgumentException("") : lastPush;
+            Exception t = lastPush is null ? cast(Exception)new IllegalArgumentException("") : cast(Exception)lastPush;
             IStatus error = new Status(IStatus.ERROR, JobManager.PI_JOBS, 1, msg, t);
             RuntimeLog.log(error);
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/core/runtime/ILog.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.core.runtime.ILog;
+
+import dwt.dwthelper.utils;
+import dwtx.core.runtime.ILogListener;
+import dwtx.core.runtime.IStatus;
+
+import dwtx.org.osgi.framework.Bundle;
+
+/**
+ * A log to which status events can be written.  Logs appear on individual
+ * plug-ins and on the platform itself.  Clients can register log listeners which
+ * will receive notification of all log events as they come in.
+ * <p>
+ * XXX Need to create a new log interface on common plugin. That interface should be a super interface of this ILog.
+ * getBundle() would stay here. In the super interface we would have getName()
+ * </p>
+ *
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface ILog {
+    /**
+     * Adds the given log listener to this log.  Subsequently the log listener will
+     * receive notification of all log events passing through this log.
+     * This method has no affect if the identical listener is already registered on this log.
+     *
+     * @param listener the listener to add to this log
+     * @see Platform#addLogListener(ILogListener)
+     */
+    public void addLogListener(ILogListener listener);
+
+    /**
+     * Returns the plug-in with which this log is associated.
+     *
+     * @return the plug-in with which this log is associated
+     * @since 3.0
+     */
+    public Bundle getBundle();
+
+    /**
+     * Logs the given status.  The status is distributed to the log listeners
+     * installed on this log and then to the log listeners installed on the platform.
+     *
+     * @param status the status to log
+     */
+    public void log(IStatus status);
+
+    /**
+     * Removes the given log listener to this log.  Subsequently the log listener will
+     * no longer receive notification of log events passing through this log.
+     * This method has no affect if the identical listener is not registered on this log.
+     *
+     * @param listener the listener to remove
+     * @see Platform#removeLogListener(ILogListener)
+     */
+    public void removeLogListener(ILogListener listener);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/core/runtime/Platform.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1578 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.core.runtime.Platform;
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.IPath;
+import dwtx.core.runtime.ILog;
+// import java.io.IOException;
+// import java.lang.reflect.Method;
+// import java.net.URL;
+// import java.util.HashMap;
+// import java.util.Map;
+// import java.util.MissingResourceException;
+// import java.util.ResourceBundle;
+//
+import dwtx.org.osgi.framework.Bundle;
+// import org.osgi.service.packageadmin.PackageAdmin;
+//
+// import dwtx.core.internal.runtime.CompatibilityHelper;
+// import dwtx.core.internal.runtime.InternalPlatform;
+// import dwtx.core.internal.runtime.Messages;
+// import dwtx.core.internal.runtime.PlatformActivator;
+// import dwtx.core.internal.runtime.auth.AuthorizationHandler;
+// import dwtx.core.runtime.content.IContentTypeManager;
+// import dwtx.core.runtime.jobs.IJobManager;
+// import dwtx.core.runtime.jobs.Job;
+// import dwtx.core.runtime.preferences.IPreferencesService;
+// import dwtx.osgi.service.datalocation.Location;
+// import dwtx.osgi.service.debug.DebugOptions;
+// import dwtx.osgi.service.environment.EnvironmentInfo;
+// import dwtx.osgi.service.resolver.PlatformAdmin;
+
+/**
+ * The central class of the Eclipse Platform Runtime. This class cannot
+ * be instantiated or subclassed by clients; all functionality is provided
+ * by static methods.  Features include:
+ * <ul>
+ * <li>the platform registry of installed plug-ins</li>
+ * <li>the platform adapter manager</li>
+ * <li>the platform log</li>
+ * <li>the authorization info management</li>
+ * </ul>
+ * <p>
+ * Most users don't have to worry about Platform's lifecycle. However, if your
+ * code can call methods of this class when Platform is not running, it becomes
+ * necessary to check {@link #isRunning()} before making the call. A runtime
+ * exception might be thrown or incorrect result might be returned if a method
+ * from this class is called while Platform is not running.
+ * </p>
+ */
+public final class Platform {
+
+//     /**
+//      * The unique identifier constant (value "<code>dwtx.core.runtime</code>")
+//      * of the Core Runtime (pseudo-) plug-in.
+//      */
+//     public static final String PI_RUNTIME = "dwtx.core.runtime"; //$NON-NLS-1$
+//
+//     /**
+//      * The simple identifier constant (value "<code>applications</code>") of
+//      * the extension point of the Core Runtime plug-in where plug-ins declare
+//      * the existence of runnable applications. A plug-in may define any
+//      * number of applications; however, the platform is only capable
+//      * of running one application at a time.
+//      *
+//      */
+//     public static final String PT_APPLICATIONS = "applications"; //$NON-NLS-1$
+//
+//     /**
+//      * The simple identifier constant (value "<code>adapters</code>") of
+//      * the extension point of the Core Runtime plug-in where plug-ins declare
+//      * the existence of adapter factories. A plug-in may define any
+//      * number of adapters.
+//      *
+//      * @see IAdapterManager#hasAdapter(Object, String)
+//      * @since 3.0
+//      */
+//     public static final String PT_ADAPTERS = "adapters"; //$NON-NLS-1$
+//
+//     /**
+//      * The simple identifier constant (value "<code>preferences</code>") of
+//      * the extension point of the Core Runtime plug-in where plug-ins declare
+//      * extensions to the preference facility. A plug-in may define any number
+//      * of preference extensions.
+//      *
+//      * @see #getPreferencesService()
+//      * @since 3.0
+//      */
+//     public static final String PT_PREFERENCES = Preferences.PT_PREFERENCES;
+//
+//     /**
+//      * The simple identifier constant (value "<code>products</code>") of
+//      * the extension point of the Core Runtime plug-in where plug-ins declare
+//      * the existence of a product. A plug-in may define any
+//      * number of products; however, the platform is only capable
+//      * of running one product at a time.
+//      *
+//      * @see #getProduct()
+//      * @since 3.0
+//      */
+//     public static final String PT_PRODUCT = "products"; //$NON-NLS-1$
+//
+//     /**
+//      * Debug option value denoting the time at which the platform runtime
+//      * was started.  This constant can be used in conjunction with
+//      * <code>getDebugOption</code> to find the string value of
+//      * <code>System.currentTimeMillis()</code> when the platform was started.
+//      */
+//     public static final String OPTION_STARTTIME = PI_RUNTIME + "/starttime"; //$NON-NLS-1$
+//
+//     /**
+//      * Name of a preference for configuring the performance level for this system.
+//      *
+//      * <p>
+//      * This value can be used by all components to customize features to suit the
+//      * speed of the user's machine.  The platform job manager uses this value to make
+//      * scheduling decisions about background jobs.
+//      * </p>
+//      * <p>
+//      * The preference value must be an integer between the constant values
+//      * MIN_PERFORMANCE and MAX_PERFORMANCE
+//      * </p>
+//      * @see #MIN_PERFORMANCE
+//      * @see #MAX_PERFORMANCE
+//      * @since 3.0
+//      */
+//     public static final String PREF_PLATFORM_PERFORMANCE = "runtime.performance"; //$NON-NLS-1$
+//
+//     /**
+//      * Constant (value "line.separator") name of the preference used for storing
+//      * the line separator.
+//      *
+//      * @see #knownPlatformLineSeparators
+//      * @since 3.1
+//      */
+//     public static final String PREF_LINE_SEPARATOR = "line.separator"; //$NON-NLS-1$
+//
+//     /**
+//      * Constant (value 1) indicating the minimum allowed value for the
+//      * <code>PREF_PLATFORM_PERFORMANCE</code> preference setting.
+//      * @since 3.0
+//      */
+//     public static final int MIN_PERFORMANCE = 1;
+//
+//     /**
+//      * Constant (value 5) indicating the maximum allowed value for the
+//      * <code>PREF_PLATFORM_PERFORMANCE</code> preference setting.
+//      * @since 3.0
+//      */
+//     public static final int MAX_PERFORMANCE = 5;
+//
+//     /**
+//      * Status code constant (value 1) indicating a problem in a plug-in
+//      * manifest (<code>plugin.xml</code>) file.
+//      */
+//     public static final int PARSE_PROBLEM = 1;
+//
+//     /**
+//      * Status code constant (value 2) indicating an error occurred while running a plug-in.
+//      */
+//     public static final int PLUGIN_ERROR = 2;
+//
+//     /**
+//      * Status code constant (value 3) indicating an error internal to the
+//      * platform has occurred.
+//      */
+//     public static final int INTERNAL_ERROR = 3;
+//
+//     /**
+//      * Status code constant (value 4) indicating the platform could not read
+//      * some of its metadata.
+//      */
+//     public static final int FAILED_READ_METADATA = 4;
+//
+//     /**
+//      * Status code constant (value 5) indicating the platform could not write
+//      * some of its metadata.
+//      */
+//     public static final int FAILED_WRITE_METADATA = 5;
+//
+//     /**
+//      * Status code constant (value 6) indicating the platform could not delete
+//      * some of its metadata.
+//      */
+//     public static final int FAILED_DELETE_METADATA = 6;
+//
+//     /**
+//      * Constant string (value "win32") indicating the platform is running on a
+//      * Window 32-bit operating system (e.g., Windows 98, NT, 2000).
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String OS_WIN32 = "win32";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "linux") indicating the platform is running on a
+//      * Linux-based operating system.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String OS_LINUX = "linux";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "aix") indicating the platform is running on an
+//      * AIX-based operating system.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String OS_AIX = "aix";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "solaris") indicating the platform is running on a
+//      * Solaris-based operating system.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String OS_SOLARIS = "solaris";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "hpux") indicating the platform is running on an
+//      * HP/UX-based operating system.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String OS_HPUX = "hpux";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "qnx") indicating the platform is running on a
+//      * QNX-based operating system.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String OS_QNX = "qnx";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "macosx") indicating the platform is running on a
+//      * Mac OS X operating system.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String OS_MACOSX = "macosx";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "unknown") indicating the platform is running on a
+//      * machine running an unknown operating system.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String OS_UNKNOWN = "unknown";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "x86") indicating the platform is running on an
+//      * x86-based architecture.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String ARCH_X86 = "x86";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "PA_RISC") indicating the platform is running on an
+//      * PA_RISC-based architecture.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String ARCH_PA_RISC = "PA_RISC";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "ppc") indicating the platform is running on an
+//      * PowerPC-based architecture.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String ARCH_PPC = "ppc";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "sparc") indicating the platform is running on an
+//      * Sparc-based architecture.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String ARCH_SPARC = "sparc";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "x86_64") indicating the platform is running on an
+//      * x86 64bit-based architecture.
+//      *
+//      * @since 3.1
+//      */
+//     public static final String ARCH_X86_64 = "x86_64";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "amd64") indicating the platform is running on an
+//      * AMD64-based architecture.
+//      *
+//      * @since 3.0
+//      * @deprecated use <code>ARCH_X86_64</code> instead. Note the values
+//      * has been changed to be the value of the <code>ARCH_X86_64</code> constant.
+//      */
+//     public static final String ARCH_AMD64 = ARCH_X86_64;
+//
+//     /**
+//      * Constant string (value "ia64") indicating the platform is running on an
+//      * IA64-based architecture.
+//      *
+//      * @since 3.0
+//      */
+//     public static final String ARCH_IA64 = "ia64"; //$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "ia64_32") indicating the platform is running on an
+//      * IA64 32bit-based architecture.
+//      *
+//      * @since 3.1
+//      */
+//     public static final String ARCH_IA64_32 = "ia64_32";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "win32") indicating the platform is running on a
+//      * machine using the Windows windowing system.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String WS_WIN32 = "win32";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "motif") indicating the platform is running on a
+//      * machine using the Motif windowing system.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String WS_MOTIF = "motif";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "gtk") indicating the platform is running on a
+//      * machine using the GTK windowing system.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String WS_GTK = "gtk";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "photon") indicating the platform is running on a
+//      * machine using the Photon windowing system.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String WS_PHOTON = "photon";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "carbon") indicating the platform is running on a
+//      * machine using the Carbon windowing system (Mac OS X).
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String WS_CARBON = "carbon";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "wpf") indicating the platform is running on a
+//      * machine using the WPF windowing system.
+//      * @since 3.3
+//      */
+//     public static final String WS_WPF = "wpf";//$NON-NLS-1$
+//
+//     /**
+//      * Constant string (value "unknown") indicating the platform is running on a
+//      * machine running an unknown windowing system.
+//      * <p>
+//      * Note this constant has been moved from the deprecated
+//      * dwtx.core.boot.BootLoader class and its value has not changed.
+//      * </p>
+//      * @since 3.0
+//      */
+//     public static final String WS_UNKNOWN = "unknown";//$NON-NLS-1$
+//
+//     // private constants for platform line separators and their associated platform names
+//     private static final String LINE_SEPARATOR_KEY_MAC_OS_9 = Messages.line_separator_platform_mac_os_9;
+//     private static final String LINE_SEPARATOR_KEY_UNIX = Messages.line_separator_platform_unix;
+//     private static final String LINE_SEPARATOR_KEY_WINDOWS = Messages.line_separator_platform_windows;
+//
+//     private static final String LINE_SEPARATOR_VALUE_CR = "\r"; //$NON-NLS-1$
+//     private static final String LINE_SEPARATOR_VALUE_LF = "\n"; //$NON-NLS-1$
+//     private static final String LINE_SEPARATOR_VALUE_CRLF = "\r\n"; //$NON-NLS-1$
+//
+//     /**
+//      * Private constructor to block instance creation.
+//      */
+//     private Platform() {
+//         super();
+//     }
+//
+//     /**
+//      * Adds the given authorization information to the key ring. The
+//      * information is relevant for the specified protection space and the
+//      * given authorization scheme. The protection space is defined by the
+//      * combination of the given server URL and realm. The authorization
+//      * scheme determines what the authorization information contains and how
+//      * it should be used. The authorization information is a <code>Map</code>
+//      * of <code>String</code> to <code>String</code> and typically
+//      * contains information such as user names and passwords.
+//      *
+//      * @param serverUrl the URL identifying the server for this authorization
+//      *      information. For example, "http://www.example.com/".
+//      * @param realm the subsection of the given server to which this
+//      *      authorization information applies.  For example,
+//      *      "realm1@example.com" or "" for no realm.
+//      * @param authScheme the scheme for which this authorization information
+//      *      applies. For example, "Basic" or "" for no authorization scheme
+//      * @param info a <code>Map</code> containing authorization information
+//      *      such as user names and passwords (key type : <code>String</code>,
+//      *      value type : <code>String</code>)
+//      * @exception CoreException if there are problems setting the
+//      *      authorization information. Reasons include:
+//      * <ul>
+//      * <li>The keyring could not be saved.</li>
+//      * </ul>
+//      * @deprecated Authorization database is superseded by the Equinox secure storage.
+//      * Use <code>dwtx.equinox.security.storage.SecurePreferencesFactory</code>
+//      * to obtain secure preferences and <code>dwtx.equinox.security.storage.ISecurePreferences</code>
+//      * for data access and modifications.
+//      * Consider using <code>ISecurePreferences#put(String, String, bool)</code> as a replacement of this method.
+//      */
+//     public static void addAuthorizationInfo(URL serverUrl, String realm, String authScheme, Map info) throws CoreException {
+//         try {
+//             AuthorizationHandler.addAuthorizationInfo(serverUrl, realm, authScheme, info);
+//         } catch (NoClassDefFoundError e) {
+//             // The authorization code is not available so just log and continue
+//             logAuthNotAvailable(e);
+//         }
+//     }
+//
+//     /**
+//      * Adds the given log listener to the notification list of the platform.
+//      * <p>
+//      * Once registered, a listener starts receiving notification as entries
+//      * are added to plug-in logs via <code>ILog.log()</code>. The listener continues to
+//      * receive notifications until it is replaced or removed.
+//      * </p>
+//      *
+//      * @param listener the listener to register
+//      * @see ILog#addLogListener(ILogListener)
+//      * @see #removeLogListener(ILogListener)
+//      * XXX Use the LogMgr service.
+//      */
+//     public static void addLogListener(ILogListener listener) {
+//         InternalPlatform.getDefault().addLogListener(listener);
+//     }
+//
+//     /**
+//      * Adds the specified resource to the protection space specified by the
+//      * given realm. All targets at or deeper than the depth of the last
+//      * symbolic element in the path of the given resource URL are assumed to
+//      * be in the same protection space.
+//      *
+//      * @param resourceUrl the URL identifying the resources to be added to
+//      *      the specified protection space. For example,
+//      *      "http://www.example.com/folder/".
+//      * @param realm the name of the protection space. For example,
+//      *      "realm1@example.com"
+//      * @exception CoreException if there are problems setting the
+//      *      authorization information. Reasons include:
+//      * <ul>
+//      * <li>The key ring could not be saved.</li>
+//      * </ul>
+//      * @deprecated Authorization database is superseded by the Equinox secure storage.
+//      * Use <code>dwtx.equinox.security.storage.SecurePreferencesFactory</code>
+//      * to obtain secure preferences and <code>dwtx.equinox.security.storage.ISecurePreferences</code>
+//      * for data access and modifications.
+//      */
+//     public static void addProtectionSpace(URL resourceUrl, String realm) throws CoreException {
+//         try {
+//             AuthorizationHandler.addProtectionSpace(resourceUrl, realm);
+//         } catch (NoClassDefFoundError e) {
+//             // The authorization code is not available so just log and continue
+//             logAuthNotAvailable(e);
+//         }
+//     }
+//
+//     /**
+//      * Returns a URL that is the local equivalent of the
+//      * supplied URL. This method is expected to be used with the
+//      * plug-in-relative URLs returned by IPluginDescriptor, Bundle.getEntry()
+//      * and Platform.find().
+//      * If the specified URL is not a plug-in-relative URL, it
+//      * is returned as is. If the specified URL is a plug-in-relative
+//      * URL of a file (including .jar archive), it is returned as
+//      * a locally accessible URL using "file:" protocol
+//      * (extracting/caching the file locally, if required). If the specified URL
+//      * is a plug-in-relative URL of a directory, the directory and any files and directories
+//      * under it are made locally accessible likewise.
+//      *
+//      * @param url original plug-in-relative URL.
+//      * @return the resolved URL
+//      * @exception IOException if unable to resolve URL
+//      * @see #resolve(URL)
+//      * @see #find(Bundle, IPath)
+//      * @see Bundle#getEntry(String)
+//      * @deprecated use {@link FileLocator#toFileURL(URL)} instead
+//      */
+//     public static URL asLocalURL(URL url) throws IOException {
+//         return FileLocator.toFileURL(url);
+//     }
+//
+//     /**
+//      * Takes down the splash screen if one was put up.
+//      * XXX this is application life cycle. Need to have the appropriate method on IApplication.
+//      */
+//     public static void endSplash() {
+//         InternalPlatform.getDefault().endSplash();
+//     }
+//
+//     /**
+//      * Removes the authorization information for the specified protection
+//      * space and given authorization scheme. The protection space is defined
+//      * by the given server URL and realm.
+//      *
+//      * @param serverUrl the URL identifying the server to remove the
+//      *      authorization information for. For example,
+//      *      "http://www.example.com/".
+//      * @param realm the subsection of the given server to remove the
+//      *      authorization information for. For example,
+//      *      "realm1@example.com" or "" for no realm.
+//      * @param authScheme the scheme for which the authorization information
+//      *      to remove applies. For example, "Basic" or "" for no
+//      *      authorization scheme.
+//      * @exception CoreException if there are problems removing the
+//      *      authorization information. Reasons include:
+//      * <ul>
+//      * <li>The keyring could not be saved.</li>
+//      * </ul>
+//      * @deprecated Authorization database is superseded by the Equinox secure storage.
+//      * Use <code>dwtx.equinox.security.storage.SecurePreferencesFactory</code>
+//      * to obtain secure preferences and <code>dwtx.equinox.security.storage.ISecurePreferences</code>
+//      * for data access and modifications.
+//      * Consider using <code>ISecurePreferences#clear()</code> as a replacement of this method.
+//      */
+//     public static void flushAuthorizationInfo(URL serverUrl, String realm, String authScheme) throws CoreException {
+//         try {
+//             AuthorizationHandler.flushAuthorizationInfo(serverUrl, realm, authScheme);
+//         } catch (NoClassDefFoundError e) {
+//             // The authorization code is not available so just log and continue
+//             logAuthNotAvailable(e);
+//         }
+//     }
+//
+//     private static void logAuthNotAvailable(Throwable e) {
+//         InternalPlatform.getDefault().log(new Status(IStatus.WARNING, Platform.PI_RUNTIME, 0, Messages.auth_notAvailable, null));
+//     }
+//
+//     /**
+//      * Returns the adapter manager used for extending
+//      * <code>IAdaptable</code> objects.
+//      *
+//      * @return the adapter manager for this platform
+//      * @see IAdapterManager
+//      * XXX register as a service (same pattern than Jobs)
+//      * Do we want to make it available as a singleton?
+//      */
+//     public static IAdapterManager getAdapterManager() {
+//         return InternalPlatform.getDefault().getAdapterManager();
+//     }
+//
+//     /**
+//      * Returns the authorization information for the specified protection
+//      * space and given authorization scheme. The protection space is defined
+//      * by the given server URL and realm. Returns <code>null</code> if no
+//      * such information exists.
+//      *
+//      * @param serverUrl the URL identifying the server for the authorization
+//      *      information. For example, "http://www.example.com/".
+//      * @param realm the subsection of the given server to which the
+//      *      authorization information applies.  For example,
+//      *      "realm1@example.com" or "" for no realm.
+//      * @param authScheme the scheme for which the authorization information
+//      *      applies. For example, "Basic" or "" for no authorization scheme
+//      * @return the authorization information for the specified protection
+//      *      space and given authorization scheme, or <code>null</code> if no
+//      *      such information exists
+//      * @deprecated Authorization database is superseded by the Equinox secure storage.
+//      * Use <code>dwtx.equinox.security.storage.SecurePreferencesFactory</code>
+//      * to obtain secure preferences and <code>dwtx.equinox.security.storage.ISecurePreferences</code>
+//      * for data access and modifications.
+//      * Consider using <code>ISecurePreferences#get(String, String)</code> as a replacement of this method.
+//      */
+//     public static Map getAuthorizationInfo(URL serverUrl, String realm, String authScheme) {
+//         try {
+//             return AuthorizationHandler.getAuthorizationInfo(serverUrl, realm, authScheme);
+//         } catch (NoClassDefFoundError e) {
+//             // The authorization code is not available so just log and continue
+//             logAuthNotAvailable(e);
+//         }
+//         return null;
+//     }
+//
+//     /**
+//      * Returns the command line args provided to the Eclipse runtime layer when it was first run.
+//      * The returned value does not include arguments consumed by the lower levels of Eclipse
+//      * (e.g., OSGi or the launcher).
+//      * Note that individual platform runnables may be provided with different arguments
+//      * if they are being run individually rather than with <code>Platform.run()</code>.
+//      * <p>
+//      * Clients are also able to acquire the {@link EnvironmentInfo} service and query it for
+//      * the command-line arguments.
+//      * </p>
+//      * @return the command line used to start the platform
+//      */
+//     public static String[] getCommandLineArgs() {
+//         return InternalPlatform.getDefault().getCommandLineArgs();
+//     }
+//
+//     /**
+//      * Returns the content type manager.
+//      * <p>
+//      * Clients are also able to acquire the {@link IContentTypeManager} service.
+//      * </p>
+//      * @return the content type manager
+//      * @since 3.0
+//      */
+//     public static IContentTypeManager getContentTypeManager() {
+//         return InternalPlatform.getDefault().getContentTypeManager();
+//     }
+
+    /**
+     * Returns the identified option.  <code>null</code>
+     * is returned if no such option is found.   Options are specified
+     * in the general form <i>&lt;plug-in id&gt;/&lt;option-path&gt;</i>.
+     * For example, <code>dwtx.core.runtime/debug</code>
+     * <p>
+     * Clients are also able to acquire the {@link DebugOptions} service
+     * and query it for debug options.
+     * </p>
+     * @param option the name of the option to lookup
+     * @return the value of the requested debug option or <code>null</code>
+     */
+    public static String getDebugOption(String option) {
+        return null;
+// DWT FIXME:  impl
+//         return InternalPlatform.getDefault().getOption(option);
+    }
+
+//     /**
+//      * Returns the location of the platform working directory.
+//      * <p>
+//      * Callers of this method should consider using <code>getInstanceLocation</code>
+//      * instead.  In various, typically non IDE-related configurations of Eclipse, the platform
+//      * working directory may not be on the local file system.  As such, the more general
+//      * form of this location is as a URL.
+//      * </p><p>
+//      * Alternatively, instead of calling <code>getInstanceLocation</code> clients are
+//      * able to acquire the {@link Location} service (with the type {@link Location#INSTANCE_FILTER})
+//      * and then change the resulting URL to a path. See the javadoc for <code>getInstanceLocation</code>
+//      * for more details.
+//      * </p>
+//      * @return the location of the platform
+//      * @see #getInstanceLocation()
+//      */
+//     public static IPath getLocation() throws IllegalStateException {
+//         return InternalPlatform.getDefault().getLocation();
+//     }
+
+    /**
+     * Returns the location of the platform log file.  This file may contain information
+     * about errors that have previously occurred during this invocation of the Platform.
+     * <p>
+     * It is recommended not to keep this value, as the log location may vary when an instance
+     * location is being set.</p>
+     * <p>
+     * Note: it is very important that users of this method do not leave the log
+     * file open for extended periods of time.  Doing so may prevent others
+     * from writing to the log file, which could result in important error messages
+     * being lost.  It is strongly recommended that clients wanting to read the
+     * log file for extended periods should copy the log file contents elsewhere,
+     * and immediately close the original file.</p>
+     * @return the path of the log file on disk.
+     *
+     * XXX  consider making an ILogger interface that listeners can implements and it allows
+     * us to implement Platform.getLogLocation()
+     */
+    public static IPath getLogFileLocation() {
+        implMissing(__FILE__,__LINE__);
+        return null;
+        //return InternalPlatform.getDefault().getMetaArea().getLogLocation();
+    }
+
+//     /**
+//      * Returns the plug-in runtime object for the identified plug-in
+//      * or <code>null</code> if no such plug-in can be found.  If
+//      * the plug-in is defined but not yet activated, the plug-in will
+//      * be activated before being returned.
+//      * <p>
+//      * <b>Note</b>: This method is only able to find and return plug-in
+//      * objects for plug-ins described using plugin.xml according to the
+//      * traditional Eclipse conventions.  Eclipse 3.0 permits plug-ins to be
+//      * described in manifest.mf files and to define their own bundle
+//      * activators.  Such plug-ins cannot be discovered by this method.</p>
+//      *
+//      * @param id the unique identifier of the desired plug-in
+//      *      (e.g., <code>"com.example.acme"</code>).
+//      * @return the plug-in runtime object, or <code>null</code>
+//      * @deprecated
+//      * This method only works if the compatibility layer is installed and must not be used otherwise.
+//      * See the comments on {@link IPluginDescriptor#getPlugin()} for details.
+//      */
+//     public static Plugin getPlugin(String id) {
+//         try {
+//             IPluginRegistry registry = getPluginRegistry();
+//             if (registry is null)
+//                 throw new IllegalStateException();
+//             IPluginDescriptor pd = registry.getPluginDescriptor(id);
+//             if (pd is null)
+//                 return null;
+//             return pd.getPlugin();
+//         } catch (CoreException e) {
+//             // TODO log the exception
+//         }
+//         return null;
+//     }
+//
+//     /**
+//      * Returns the plug-in registry for this platform.
+//      *
+//      * @return the plug-in registry
+//      * @see IPluginRegistry
+//      * @deprecated <code>IPluginRegistry</code> was refactored in Eclipse 3.0.
+//      * This method only works if the compatibility layer is installed and must not be used otherwise.
+//      * See the comments on {@link IPluginRegistry} and its methods for details.
+//      */
+//     public static IPluginRegistry getPluginRegistry() {
+//         Bundle compatibility = InternalPlatform.getDefault().getBundle(CompatibilityHelper.PI_RUNTIME_COMPATIBILITY);
+//         if (compatibility is null)
+//             throw new IllegalStateException();
+//
+//         Class oldInternalPlatform = null;
+//         try {
+//             oldInternalPlatform = compatibility.loadClass("dwtx.core.internal.plugins.InternalPlatform"); //$NON-NLS-1$
+//             Method getPluginRegistry = oldInternalPlatform.getMethod("getPluginRegistry", null); //$NON-NLS-1$
+//             return (IPluginRegistry) getPluginRegistry.invoke(oldInternalPlatform, null);
+//         } catch (Exception e) {
+//             //Ignore the exceptions, return null
+//         }
+//         return null;
+//
+//     }
+//
+//     /**
+//      * Returns the location in the local file system of the plug-in
+//      * state area for the given plug-in.
+//      * The platform must be running.
+//      * <p>
+//      * The plug-in state area is a file directory within the
+//      * platform's metadata area where a plug-in is free to create files.
+//      * The content and structure of this area is defined by the plug-in,
+//      * and the particular plug-in is solely responsible for any files
+//      * it puts there. It is recommended for plug-in preference settings.
+//      * </p>
+//      *
+//      * @param plugin the plug-in whose state location is returned
+//      * @return a local file system path
+//      * @deprecated clients should call <code>getStateLocation</code> instead
+//      */
+//     public static IPath getPluginStateLocation(Plugin plugin) {
+//         return plugin.getStateLocation();
+//     }
+//
+//     /**
+//      * Returns the protection space (realm) for the specified resource, or
+//      * <code>null</code> if the realm is unknown.
+//      *
+//      * @param resourceUrl the URL of the resource whose protection space is
+//      *      returned. For example, "http://www.example.com/folder/".
+//      * @return the protection space (realm) for the specified resource, or
+//      *      <code>null</code> if the realm is unknown
+//      * @deprecated Authorization database is superseded by the Equinox secure storage.
+//      * Use <code>dwtx.equinox.security.storage.SecurePreferencesFactory</code>
+//      * to obtain secure preferences and <code>dwtx.equinox.security.storage.ISecurePreferences</code>
+//      * for data access and modifications.
+//      */
+//     public static String getProtectionSpace(URL resourceUrl) {
+//         try {
+//             return AuthorizationHandler.getProtectionSpace(resourceUrl);
+//         } catch (NoClassDefFoundError e) {
+//             // The authorization code is not available so just log and continue
+//             logAuthNotAvailable(e);
+//         }
+//         return null;
+//     }
+//
+//     /**
+//      * Removes the indicated (identical) log listener from the notification list
+//      * of the platform.  If no such listener exists, no action is taken.
+//      *
+//      * @param listener the listener to de-register
+//      * @see ILog#removeLogListener(ILogListener)
+//      * @see #addLogListener(ILogListener)
+//      * XXX Use the LogMgr service.
+//      */
+//     public static void removeLogListener(ILogListener listener) {
+//         InternalPlatform.getDefault().removeLogListener(listener);
+//     }
+//
+//     /**
+//      * Returns a URL which is the resolved equivalent of the
+//      * supplied URL. This method is expected to be used with the
+//      * plug-in-relative URLs returned by IPluginDescriptor, Bundle.getEntry()
+//      * and Platform.find().
+//      * <p>
+//      * If the specified URL is not a plug-in-relative URL, it is returned
+//      * as is. If the specified URL is a plug-in-relative URL, this method
+//      * attempts to reduce the given URL to one which is native to the Java
+//      * class library (eg. file, http, etc).
+//      * </p><p>
+//      * Note however that users of this API should not assume too much about the
+//      * results of this method.  While it may consistently return a file: URL in certain
+//      * installation configurations, others may result in jar: or http: URLs.
+//      * </p>
+//      * @param url original plug-in-relative URL.
+//      * @return the resolved URL
+//      * @exception IOException if unable to resolve URL
+//      * @see #asLocalURL(URL)
+//      * @see #find(Bundle, IPath)
+//      * @see Bundle#getEntry(String)
+//      * @deprecated use {@link FileLocator#resolve(URL)} instead
+//      */
+//     public static URL resolve(URL url) throws IOException {
+//         return FileLocator.resolve(url);
+//     }
+//
+//     /**
+//      * Runs the given runnable in a protected mode.   Exceptions
+//      * thrown in the runnable are logged and passed to the runnable's
+//      * exception handler.  Such exceptions are not rethrown by this method.
+//      *
+//      * @param runnable the runnable to run
+//      * @deprecated clients should use <code>SafeRunner#run</code> instead
+//      */
+//     public static void run(ISafeRunnable runnable) {
+//         SafeRunner.run(runnable);
+//     }
+//
+//     /**
+//      * Returns the platform job manager.
+//      *
+//      * @return the platform's job manager
+//      * @since 3.0
+//      * @deprecated The method {@link Job#getJobManager()} should be used instead.
+//      */
+//     public static IJobManager getJobManager() {
+//         return Job.getJobManager();
+//     }
+//
+//     /**
+//      * Returns the extension registry for this platform.
+//      *
+//      * @return the extension registry
+//      * @see IExtensionRegistry
+//      * @since 3.0
+//      */
+//     public static IExtensionRegistry getExtensionRegistry() {
+//         return InternalPlatform.getDefault().getRegistry();
+//     }
+//
+//     /**
+//      * Returns a URL for the given path in the given bundle.  Returns <code>null</code> if the URL
+//      * could not be computed or created.
+//      *
+//      * @param bundle the bundle in which to search
+//      * @param path path relative to plug-in installation location
+//      * @return a URL for the given path or <code>null</code>.  The actual form
+//      * of the returned URL is not specified.
+//      * @see #find(Bundle, IPath, Map)
+//      * @see #resolve(URL)
+//      * @see #asLocalURL(URL)
+//      * @since 3.0
+//      * @deprecated use {@link FileLocator#find(Bundle, IPath, Map)}
+//      */
+//     public static URL find(Bundle bundle, IPath path) {
+//         return FileLocator.find(bundle, path, null);
+//     }
+//
+//     /**
+//      * Returns a URL for the given path in the given bundle.  Returns <code>null</code> if the URL
+//      * could not be computed or created.
+//      * <p>
+//      * find looks for this path in given bundle and any attached fragments.
+//      * <code>null</code> is returned if no such entry is found.  Note that
+//      * there is no specific order to the fragments.
+//      * </p><p>
+//      * The following arguments may also be used
+//      * <pre>
+//      *     $nl$ - for language specific information
+//      *     $os$ - for operating system specific information
+//      *     $ws$ - for windowing system specific information
+//      * </pre>
+//      * </p><p>
+//      * A path of $nl$/about.properties in an environment with a default
+//      * locale of en_CA will return a URL corresponding to the first place
+//      * about.properties is found according to the following order:
+//      * <pre>
+//      *     plugin root/nl/en/CA/about.properties
+//      *     fragment1 root/nl/en/CA/about.properties
+//      *     fragment2 root/nl/en/CA/about.properties
+//      *     ...
+//      *     plugin root/nl/en/about.properties
+//      *     fragment1 root/nl/en/about.properties
+//      *     fragment2 root/nl/en/about.properties
+//      *     ...
+//      *     plugin root/about.properties
+//      *     fragment1 root/about.properties
+//      *     fragment2 root/about.properties
+//      *     ...
+//      * </pre>
+//      * </p><p>
+//      * The current environment variable values can be overridden using
+//      * the override map argument.
+//      * </p>
+//      *
+//      * @param bundle the bundle in which to search
+//      * @param path file path relative to plug-in installation location
+//      * @param override map of override substitution arguments to be used for
+//      * any $arg$ path elements. The map keys correspond to the substitution
+//      * arguments (eg. "$nl$" or "$os$"). The resulting
+//      * values must be of type java.lang.String. If the map is <code>null</code>,
+//      * or does not contain the required substitution argument, the default
+//      * is used.
+//      * @return a URL for the given path or <code>null</code>.  The actual form
+//      * of the returned URL is not specified.
+//      * @see #resolve(URL)
+//      * @see #asLocalURL(URL)
+//      * @since 3.0
+//      * @deprecated use {@link FileLocator#find(Bundle, IPath, Map)} instead
+//      */
+//     public static URL find(Bundle bundle, IPath path, Map override) {
+//         return FileLocator.find(bundle, path, override);
+//     }
+//
+//     /**
+//      * Returns the location in the local file system of the
+//      * plug-in state area for the given bundle.
+//      * If the plug-in state area did not exist prior to this call,
+//      * it is created.
+//      * <p>
+//      * The plug-in state area is a file directory within the
+//      * platform's metadata area where a plug-in is free to create files.
+//      * The content and structure of this area is defined by the plug-in,
+//      * and the particular plug-in is solely responsible for any files
+//      * it puts there. It is recommended for plug-in preference settings and
+//      * other configuration parameters.
+//      * </p>
+//      *
+//      * @param bundle the bundle whose state location if returned
+//      * @return a local file system path
+//      * @since 3.0
+//      * XXX Investigate the usage of a service factory
+//      */
+//     public static IPath getStateLocation(Bundle bundle) {
+//         return InternalPlatform.getDefault().getStateLocation(bundle);
+//     }
+//
+//     /**
+//      * Returns a number that changes whenever the set of installed plug-ins
+//      * changes. This can be used for invalidating caches that are based on
+//      * the set of currently installed plug-ins. (e.g. extensions)
+//      * <p>
+//      * Clients are also able to acquire the {@link PlatformAdmin} service
+//      * and get the timestamp from its state object.
+//      * </p>
+//      * @return a number related to the set of installed plug-ins
+//      * @since 3.1
+//      */
+//     public static long getStateStamp() {
+//         return InternalPlatform.getDefault().getStateTimeStamp();
+//     }
+
+    /**
+     * Returns the log for the given bundle.  If no such log exists, one is created.
+     *
+     * @param bundle the bundle whose log is returned
+     * @return the log for the given bundle
+     * @since 3.0
+     * XXX change this into a LogMgr service that would keep track of the map. See if it can be a service factory.
+     * It would contain all the methods that are here.
+     * Relate to RuntimeLog if appropriate.
+     * The system log listener needs to be optional: turned on or off. What about a system property? :-)
+     */
+    public static ILog getLog(Bundle bundle) {
+        implMissing(__FILE__,__LINE__);
+        return null;
+        //return InternalPlatform.getDefault().getLog(bundle);
+    }
+
+//     /**
+//      * Returns the given bundle's resource bundle for the current locale.
+//      * <p>
+//      * This resource bundle is typically stored as the plugin.properties file
+//      * in the plug-in itself, and contains any translatable strings used in the
+//      * plug-in manifest file (plugin.xml).
+//      * </p>
+//      * <p>
+//      *  This mechanism is intended only for
+//      * externalizing strings found in the plug-in manifest file. Using this
+//      * method for externalizing strings in your code may result in degraded
+//      * memory performance.
+//      * </p>
+//      *
+//      * @param bundle the bundle whose resource bundle is being queried
+//      * @return the resource bundle
+//      * @exception MissingResourceException if the resource bundle was not found
+//      * @since 3.0
+//      * XXX this is deprecated. use NLS or BundleFinder.find()
+//      */
+//     public static ResourceBundle getResourceBundle(Bundle bundle) throws MissingResourceException {
+//         return InternalPlatform.getDefault().getResourceBundle(bundle);
+//     }
+//
+//     /**
+//      * Returns a resource string corresponding to the given argument value.
+//      * If the argument value specifies a resource key, the string
+//      * is looked up in the default resource bundle for the given runtime bundle. If the argument does not
+//      * specify a valid key, the argument itself is returned as the
+//      * resource string. The key lookup is performed in the
+//      * file referenced in the Bundle-Localization header of the bundle manifest. If a resource string
+//      * corresponding to the key is not found in the resource bundle
+//      * the key value, or any default text following the key in the
+//      * argument value is returned as the resource string.
+//      * A key is identified as a string beginning with the "%" character.
+//      * Note, that the "%" character is stripped off prior to lookup
+//      * in the resource bundle.
+//      * <p>
+//      * Equivalent to <code>getResourceString(bundle, value, getResourceBundle())</code>
+//      * </p>
+//      *
+//      * @param bundle the bundle whose resource bundle is being queried
+//      * @param value the value to look for
+//      * @return the resource string
+//      * @see #getResourceBundle(Bundle)
+//      * @since 3.0
+//      * XXX this is deprecated. use NLS or  BundleFinder.find()
+//      */
+//     public static String getResourceString(Bundle bundle, String value) {
+//         return InternalPlatform.getDefault().getResourceString(bundle, value);
+//     }
+//
+//     /**
+//      * Returns a resource string corresponding to the given argument
+//      * value and resource bundle in the given runtime bundle.
+//      * If the argument value specifies a resource key, the string
+//      * is looked up in the given resource bundle. If the argument does not
+//      * specify a valid key, the argument itself is returned as the
+//      * resource string. The key lookup is performed against the
+//      * specified resource bundle. If a resource string
+//      * corresponding to the key is not found in the resource bundle
+//      * the key value, or any default text following the key in the
+//      * argument value is returned as the resource string.
+//      * A key is identified as a string beginning with the "%" character.
+//      * Note that the "%" character is stripped off prior to lookup
+//      * in the resource bundle.
+//      * <p>
+//      * For example, assume resource bundle plugin.properties contains
+//      * name = Project Name
+//      * <pre>
+//      *     getResourceString("Hello World") returns "Hello World"</li>
+//      *     getResourceString("%name") returns "Project Name"</li>
+//      *     getResourceString("%name Hello World") returns "Project Name"</li>
+//      *     getResourceString("%abcd Hello World") returns "Hello World"</li>
+//      *     getResourceString("%abcd") returns "%abcd"</li>
+//      *     getResourceString("%%name") returns "%name"</li>
+//      * </pre>
+//      * </p>
+//      *
+//      * @param bundle the bundle whose resource bundle is being queried
+//      * @param value the value
+//      * @param resourceBundle the resource bundle to query
+//      * @return the resource string
+//      * @see #getResourceBundle(Bundle)
+//      * @since 3.0
+//      * XXX this is deprecated. use NLS or  BundleFinder.find()
+//      */
+//     public static String getResourceString(Bundle bundle, String value, ResourceBundle resourceBundle) {
+//         return InternalPlatform.getDefault().getResourceString(bundle, value, resourceBundle);
+//     }
+//
+//     /**
+//      * Returns the string name of the current system architecture.
+//      * The value is a user-defined string if the architecture is
+//      * specified on the command line, otherwise it is the value
+//      * returned by <code>java.lang.System.getProperty("os.arch")</code>.
+//      * <p>
+//      * Clients are also able to acquire the {@link EnvironmentInfo} service and query it for
+//      * the operating-system architecture.
+//      * </p>
+//      * @return the string name of the current system architecture
+//      * @since 3.0
+//      */
+//     public static String getOSArch() {
+//         return InternalPlatform.getDefault().getOSArch();
+//     }
+//
+//     /**
+//      * Returns the string name of the current locale for use in finding files
+//      * whose path starts with <code>$nl$</code>.
+//      * <p>
+//      * Clients are also able to acquire the {@link EnvironmentInfo} service and query it for
+//      * the NL.
+//      * </p>
+//      * @return the string name of the current locale
+//      * @since 3.0
+//      */
+//     public static String getNL() {
+//         return InternalPlatform.getDefault().getNL();
+//     }
+//
+//     /**
+//      * Returns the string name of the current operating system for use in finding
+//      * files whose path starts with <code>$os$</code>.  <code>OS_UNKNOWN</code> is
+//      * returned if the operating system cannot be determined.
+//      * The value may indicate one of the operating systems known to the platform
+//      * (as specified in <code>knownOSValues</code>) or a user-defined string if
+//      * the operating system name is specified on the command line.
+//      * <p>
+//      * Clients are also able to acquire the {@link EnvironmentInfo} service and query it for
+//      * the operating-system.
+//      * </p>
+//      * @return the string name of the current operating system
+//      * @since 3.0
+//      */
+//     public static String getOS() {
+//         return InternalPlatform.getDefault().getOS();
+//     }
+//
+//     /**
+//      * Returns the string name of the current window system for use in finding files
+//      * whose path starts with <code>$ws$</code>.  <code>null</code> is returned
+//      * if the window system cannot be determined.
+//      * <p>
+//      * Clients are also able to acquire the {@link EnvironmentInfo} service and query it for
+//      * the windowing system.
+//      * </p>
+//      * @return the string name of the current window system or <code>null</code>
+//      * @since 3.0
+//      */
+//     public static String getWS() {
+//         return InternalPlatform.getDefault().getWS();
+//     }
+//
+//     /**
+//      * Returns the arguments not consumed by the framework implementation itself.  Which
+//      * arguments are consumed is implementation specific. These arguments are available
+//      * for use by the application.
+//      *
+//      * @return the array of command line arguments not consumed by the framework.
+//      * @since 3.0
+//      * XXX Use the Environment info service. Need to see how to set the value of the app args.
+//      */
+//     public static String[] getApplicationArgs() {
+//         return InternalPlatform.getDefault().getApplicationArgs();
+//     }
+//
+//     /**
+//      * Returns the platform administrator for this running Eclipse.
+//      * <p>
+//      * Note: This is an internal method and <em>must not</em>
+//      * be used by clients which are not part of the Eclipse Platform.
+//      * This method allows access to classes which are not Eclipse
+//      * Platform API but are part of the OSGi runtime that the Eclipse
+//      * Platform is built on. Even as the Eclipse Platform evolves
+//      * in compatible ways from release to release, the details of
+//      * the OSGi implementation might not.
+//      * </p><p>
+//      * Clients can also acquire the {@link PlatformAdmin} service
+//      * to retrieve this object.
+//      * </p>
+//      * @return the platform admin for this instance of Eclipse
+//      * @since 3.0
+//      */
+//     public static PlatformAdmin getPlatformAdmin() {
+//         return InternalPlatform.getDefault().getPlatformAdmin();
+//     }
+//
+//     /**
+//      * Returns the location of the platform's working directory (also known as the instance data area).
+//      * <code>null</code> is returned if the platform is running without an instance location.
+//      * <p>
+//      * This method is equivalent to acquiring the <code>dwtx.osgi.service.datalocation.Location</code>
+//      * service with the property "type" equal to {@link Location#INSTANCE_FILTER}.
+//      *</p>
+//      * @return the location of the platform's instance data area or <code>null</code> if none
+//      * @since 3.0
+//      * @see Location#INSTANCE_FILTER
+//      */
+//     public static Location getInstanceLocation() {
+//         return InternalPlatform.getDefault().getInstanceLocation();
+//     }
+//
+//     /**
+//      * Returns the currently registered bundle group providers.
+//      * <p>
+//      * Clients are also able to acquire the {@link IBundleGroupProvider} service and query it for
+//      * the registered bundle group providers.
+//      * </p>
+//      * @return the currently registered bundle group providers
+//      * @since 3.0
+//      */
+//     public static IBundleGroupProvider[] getBundleGroupProviders() {
+//         return InternalPlatform.getDefault().getBundleGroupProviders();
+//     }
+//
+//     /**
+//      * Return the interface into the preference mechanism. The returned
+//      * object can be used for such operations as searching for preference
+//      * values across multiple scopes and preference import/export.
+//      * <p>
+//      * Clients are also able to acquire the {@link IPreferencesService} service via
+//      * OSGi mechanisms and use it for preference functions.
+//      * </p>
+//      * @return an object to interface into the preference mechanism
+//      * @since 3.0
+//      */
+//     public static IPreferencesService getPreferencesService() {
+//         return InternalPlatform.getDefault().getPreferencesService();
+//     }
+//
+//     /**
+//      * Returns the product which was selected when running this Eclipse instance
+//      * or <code>null</code> if none
+//      * @return the current product or <code>null</code> if none
+//      * @since 3.0
+//      * XXX move this into the app model.
+//      */
+//     public static IProduct getProduct() {
+//         return InternalPlatform.getDefault().getProduct();
+//     }
+//
+//     /**
+//      * Registers the given bundle group provider with the platform.
+//      * <p>
+//      * Clients are also able to use the {@link IBundleGroupProvider} service to
+//      * register themselves as a bundle group provider.
+//      * </p>
+//      * @param provider a provider to register
+//      * @since 3.0
+//      */
+//     public static void registerBundleGroupProvider(IBundleGroupProvider provider) {
+//         InternalPlatform.getDefault().registerBundleGroupProvider(provider);
+//     }
+//
+//     /**
+//      * De-registers the given bundle group provider with the platform.
+//      * <p>
+//      * Clients are also able to use the {@link IBundleGroupProvider} service mechanism
+//      * for unregistering themselves.
+//      * </p>
+//      * @param provider a provider to de-register
+//      * @since 3.0
+//      * @see #registerBundleGroupProvider(IBundleGroupProvider)
+//      */
+//     public static void unregisterBundleGroupProvider(IBundleGroupProvider provider) {
+//         InternalPlatform.getDefault().unregisterBundleGroupProvider(provider);
+//     }
+//
+//     /**
+//      * Returns the location of the configuration information
+//      * used to run this instance of Eclipse.  The configuration area typically
+//      * contains the list of plug-ins available for use, various settings
+//      * (those shared across different instances of the same configuration)
+//      * and any other such data needed by plug-ins.
+//      * <code>null</code> is returned if the platform is running without a configuration location.
+//      * <p>
+//      * This method is equivalent to acquiring the <code>dwtx.osgi.service.datalocation.Location</code>
+//      * service with the property "type" equal to {@link Location#CONFIGURATION_FILTER}.
+//      *</p>
+//      * @return the location of the platform's configuration data area or <code>null</code> if none
+//      * @since 3.0
+//      * @see Location#CONFIGURATION_FILTER
+//      */
+//     public static Location getConfigurationLocation() {
+//         return InternalPlatform.getDefault().getConfigurationLocation();
+//     }
+//
+//     /**
+//      * Returns the location of the platform's user data area.  The user data area is a location on the system
+//      * which is specific to the system's current user.  By default it is located relative to the
+//      * location given by the System property "user.home".
+//      * <code>null</code> is returned if the platform is running without an user location.
+//      * <p>
+//      * This method is equivalent to acquiring the <code>dwtx.osgi.service.datalocation.Location</code>
+//      * service with the property "type" equal to {@link Location#USER_FILTER}.
+//      *</p>
+//      * @return the location of the platform's user data area or <code>null</code> if none
+//      * @since 3.0
+//      * @see Location#USER_FILTER
+//      */
+//     public static Location getUserLocation() {
+//         return InternalPlatform.getDefault().getUserLocation();
+//     }
+//
+//     /**
+//      * Returns the location of the base installation for the running platform
+//      * <code>null</code> is returned if the platform is running without a configuration location.
+//      * <p>
+//      * This method is equivalent to acquiring the <code>dwtx.osgi.service.datalocation.Location</code>
+//      * service with the property "type" equal to {@link Location#INSTALL_FILTER}.
+//      *</p>
+//      * @return the location of the platform's installation area or <code>null</code> if none
+//      * @since 3.0
+//      * @see Location#INSTALL_FILTER
+//      */
+//     public static Location getInstallLocation() {
+//         return InternalPlatform.getDefault().getInstallLocation();
+//     }
+//
+//     /**
+//      * Checks if the specified bundle is a fragment bundle.
+//      * <p>
+//      * Clients are also able to acquire the {@link PackageAdmin} service
+//      * to query if the given bundle is a fragment by asking for the bundle type
+//      * and checking against constants on the service interface.
+//      * </p>
+//      * @param bundle the bundle to query
+//      * @return true if the specified bundle is a fragment bundle; otherwise false is returned.
+//      * @since 3.0
+//      */
+//     public static bool isFragment(Bundle bundle) {
+//         return InternalPlatform.getDefault().isFragment(bundle);
+//     }
+//
+//     /**
+//      * Returns an array of attached fragment bundles for the specified bundle.  If the
+//      * specified bundle is a fragment then <tt>null</tt> is returned.  If no fragments are
+//      * attached to the specified bundle then <tt>null</tt> is returned.
+//      * <p>
+//      * Clients are also able to acquire the {@link PackageAdmin} service and query
+//      * it for the fragments of the given bundle.
+//      * </p>
+//      * @param bundle the bundle to get the attached fragment bundles for.
+//      * @return an array of fragment bundles or <tt>null</tt> if the bundle does not
+//      * have any attached fragment bundles.
+//      * @since 3.0
+//      */
+//     public static Bundle[] getFragments(Bundle bundle) {
+//         return InternalPlatform.getDefault().getFragments(bundle);
+//     }
+//
+    /**
+     * Returns the resolved bundle with the specified symbolic name that has the
+     * highest version.  If no resolved bundles are installed that have the
+     * specified symbolic name then null is returned.
+     * <p>
+     * Clients are also able to acquire the {@link PackageAdmin} service and query
+     * it for the bundle with the specified symbolic name. Clients can ask the
+     * service for all bundles with that particular name and then determine the
+     * one with the highest version. Note that clients may want to filter
+     * the results based on the state of the bundles.
+     * </p>
+     * @param symbolicName the symbolic name of the bundle to be returned.
+     * @return the bundle that has the specified symbolic name with the
+     * highest version, or <tt>null</tt> if no bundle is found.
+     * @since 3.0
+     */
+    public static Bundle getBundle(String symbolicName) {
+        implMissing(__FILE__, __LINE__ );
+        return null;
+        //return InternalPlatform.getDefault().getBundle(symbolicName);
+    }
+
+//     /**
+//      * Returns all bundles with the specified symbolic name.  If no resolved bundles
+//      * with the specified symbolic name can be found, <tt>null</tt> is returned.
+//      * If the version argument is not null then only the Bundles that have
+//      * the specified symbolic name and a version greater than or equal to the
+//      * specified version are returned. The returned bundles are ordered in
+//      * descending bundle version order.
+//      * <p>
+//      * Clients are also able to acquire the {@link PackageAdmin} service and query
+//      * it for all bundle versions with the given symbolic name, after turning the
+//      * specific version into a version range. Note that clients may want to filter
+//      * the results based on the state of the bundles.
+//      * </p>
+//      * @param symbolicName the symbolic name of the bundles that are to be returned.
+//      * @param version the version that the return bundle versions must match,
+//      * or <tt>null</tt> if no version matching is to be done.
+//      * @return the array of Bundles with the specified name that match the
+//      * specified version and match rule, or <tt>null</tt> if no bundles are found.
+//      */
+//     public static Bundle[] getBundles(String symbolicName, String version) {
+//         return InternalPlatform.getDefault().getBundles(symbolicName, version);
+//     }
+//
+//     /**
+//      * Returns an array of host bundles that the specified fragment bundle is
+//      * attached to or <tt>null</tt> if the specified bundle is not attached to a host.
+//      * If the bundle is not a fragment bundle then <tt>null</tt> is returned.
+//      * <p>
+//      * Clients are also able to acquire the {@link PackageAdmin} service and query
+//      * it for the hosts for the given bundle.
+//      * </p>
+//      * @param bundle the bundle to get the host bundles for.
+//      * @return an array of host bundles or null if the bundle does not have any
+//      * host bundles.
+//      * @since 3.0
+//      */
+//     public static Bundle[] getHosts(Bundle bundle) {
+//         return InternalPlatform.getDefault().getHosts(bundle);
+//     }
+//
+//     /**
+//      * Returns whether the platform is running.
+//      *
+//      * @return <code>true</code> if the platform is running,
+//      *      and <code>false</code> otherwise
+//      *@since 3.0
+//      *XXX do what you want to do. track osgi, track runtime, or whatever.
+//      */
+//     public static bool isRunning() {
+//         return InternalPlatform.getDefault().isRunning();
+//     }
+//
+//     /**
+//      * Returns a list of known system architectures.
+//      * <p>
+//      * Note that this list is not authoritative; there may be legal values
+//      * not included in this list. Indeed, the value returned by
+//      * <code>getOSArch</code> may not be in this list. Also, this list may
+//      * change over time as Eclipse comes to run on more operating environments.
+//      * </p>
+//      *
+//      * @return the list of system architectures known to the system
+//      * @see #getOSArch()
+//      * @since 3.0
+//      * XXX This is useless
+//      */
+//     public static String[] knownOSArchValues() {
+//         return InternalPlatform.getDefault().knownOSArchValues();
+//     }
+//
+//     /**
+//      * Returns a list of known operating system names.
+//      * <p>
+//      * Note that this list is not authoritative; there may be legal values
+//      * not included in this list. Indeed, the value returned by
+//      * <code>getOS</code> may not be in this list. Also, this list may
+//      * change over time as Eclipse comes to run on more operating environments.
+//      * </p>
+//      *
+//      * @return the list of operating systems known to the system
+//      * @see #getOS()
+//      * @since 3.0
+//      * XXX This is useless
+//      */
+//     public static String[] knownOSValues() {
+//         return InternalPlatform.getDefault().knownOSValues();
+//     }
+//
+//     /**
+//      * Returns a map of known platform line separators. The keys are
+//      * translated names of platforms and the values are their associated
+//      * line separator strings.
+//      *
+//      * @return a map of platform to their line separator string
+//      * @since 3.1
+//      */
+//     public static Map knownPlatformLineSeparators() {
+//         Map result = new HashMap();
+//         result.put(LINE_SEPARATOR_KEY_MAC_OS_9, LINE_SEPARATOR_VALUE_CR);
+//         result.put(LINE_SEPARATOR_KEY_UNIX, LINE_SEPARATOR_VALUE_LF);
+//         result.put(LINE_SEPARATOR_KEY_WINDOWS, LINE_SEPARATOR_VALUE_CRLF);
+//         return result;
+//     }
+//
+//     /**
+//      * Returns a list of known windowing system names.
+//      * <p>
+//      * Note that this list is not authoritative; there may be legal values
+//      * not included in this list. Indeed, the value returned by
+//      * <code>getWS</code> may not be in this list. Also, this list may
+//      * change over time as Eclipse comes to run on more operating environments.
+//      * </p>
+//      *
+//      * @return the list of window systems known to the system
+//      * @see #getWS()
+//      * @since 3.0
+//      * XXX This is useless
+//      */
+//     public static String[] knownWSValues() {
+//         return InternalPlatform.getDefault().knownWSValues();
+//     }
+//
+//     /**
+//      * Returns <code>true</code> if the platform is currently running in
+//      * debug mode.  The platform is typically put in debug mode using the
+//      * "-debug" command line argument.
+//      * <p>
+//      * Clients are also able to acquire the {@link EnvironmentInfo} service and query it
+//      * to see if they are in debug mode.
+//      * </p>
+//      * @return whether or not the platform is running in debug mode
+//      * @since 3.0
+//      */
+//     public static bool inDebugMode() {
+//         return PlatformActivator.getContext().getProperty("osgi.debug") !is null; //$NON-NLS-1$
+//     }
+//
+//     /**
+//      * Returns <code>true</code> if the platform is currently running in
+//      * development mode.  That is, if special procedures are to be
+//      * taken when defining plug-in class paths.  The platform is typically put in
+//      * development mode using the "-dev" command line argument.
+//      * <p>
+//      * Clients are also able to acquire the {@link EnvironmentInfo} service and query it
+//      * to see if they are in development mode.
+//      * </p>
+//      * @return whether or not the platform is running in development mode
+//      * @since 3.0
+//      */
+//     public static bool inDevelopmentMode() {
+//         return PlatformActivator.getContext().getProperty("osgi.dev") !is null; //$NON-NLS-1$
+//     }
+}
--- a/dwtx/core/runtime/jobs/package.html	Mon Sep 08 01:37:00 2008 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
-<html>
-<head>
-   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
-   <title>Package-level Javadoc</title>
-</head>
-<body>
-Provides core support for scheduling and interacting with background activity.
-<h2>
-Package Specification</h2>
-<p>
-This package specifies API for scheduling background tasks, or jobs.  Jobs can be
-scheduled for immediate execution, or for execution after a specified delay.  Once
-scheduled, jobs can be queried, canceled, or suspended.  Rules can be attached to
-jobs to indicate when they can run, and whether they can run simultaneously with other
-jobs.  This package also includes a generic locking facility that includes support for 
-detecting and responding to deadlock.
-<p>
-@since 3.0
-<p>
-</body>
-</html>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/dwtxhelper/BufferedReader.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,23 @@
+module dwtx.dwtxhelper.BufferedReader;
+
+import dwt.dwthelper.utils;
+
+class BufferedReader : Reader {
+    this(Reader reader){
+        implMissing(__FILE__,__LINE__);
+    }
+    public override int read(char[] cbuf, int off, int len){
+        implMissing(__FILE__,__LINE__);
+        return 0;
+    }
+    public override void  close(){
+        implMissing(__FILE__,__LINE__);
+    }
+    public String  readLine() {
+        implMissing(__FILE__,__LINE__);
+        return null;
+    }
+}
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/dwtxhelper/CharacterIterator.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,17 @@
+module dwtx.dwtxhelper.CharacterIterator;
+
+interface CharacterIterator {
+    static const char DONE = '\u00FF';
+    Object clone();
+    char   current();
+    char   first();
+    int    getBeginIndex();
+    int    getEndIndex();
+    int    getIndex();
+    char   last();
+    char   next();
+    char   previous();
+    char   setIndex(int position);
+}
+
+
--- a/dwtx/dwtxhelper/Collection.d	Mon Sep 08 01:37:00 2008 +0200
+++ b/dwtx/dwtxhelper/Collection.d	Mon Sep 08 01:38:10 2008 +0200
@@ -119,6 +119,7 @@
     public bool     addAll(int index, Collection c);
     public void     clear();
     public bool     contains(Object o);
+    public bool     contains(String o);
     public bool     containsAll(Collection c);
     public int      opEquals(Object o);
     public Object   get(int index);
@@ -362,6 +363,137 @@
 
 }
 
+class IdentityHashMap : Map {
+    alias tango.util.container.HashMap.HashMap!(Object,Object) MapType;
+    private MapType map;
+
+    public this(){
+        implMissing(__FILE__, __LINE__ );
+        map = new MapType();
+    }
+    public this(int initialCapacity){
+        implMissing(__FILE__, __LINE__ );
+        this();
+    }
+    public this(int initialCapacity, float loadFactor){
+        implMissing(__FILE__, __LINE__ );
+        map = new MapType(loadFactor);
+    }
+    public this(Map m){
+        implMissing(__FILE__, __LINE__ );
+        this();
+        putAll(m);
+    }
+    public void clear(){
+        map.clear();
+    }
+    public bool containsKey(Object key){
+        Object v;
+        return map.get(key, v );
+    }
+    public bool containsKey(String key){
+        return containsKey(stringcast(key));
+    }
+    public bool containsValue(Object value){
+        return map.contains(value);
+    }
+    public Set  entrySet(){
+        HashSet res = new HashSet();
+        foreach( k, v; map ){
+            res.add( new MapEntry(this,k));
+        }
+        return res;
+    }
+    public override int opEquals(Object o){
+        if( auto other = cast(HashMap) o ){
+            if( other.size() !is size() ){
+                return false;
+            }
+            foreach( k, v; map ){
+                Object vo = other.get(k);
+                if( v != vo ){
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+    public Object get(Object key){
+        if( auto v = key in map ){
+            return *v;
+        }
+        return null;
+    }
+    public Object get(String key){
+        return get(stringcast(key));
+    }
+    public override hash_t toHash(){
+        return super.toHash();
+    }
+    public bool isEmpty(){
+        return map.isEmpty();
+    }
+    public Set    keySet(){
+        HashSet res = new HashSet();
+        foreach( k, v; map ){
+            res.add(k);
+        }
+        return res;
+    }
+    public Object put(Object key, Object value){
+        Object res = null;
+        if( auto vold = key in map ){
+            res = *vold;
+        }
+        map[ key ] = value;
+        return res;
+    }
+    public Object put(String key, Object value){
+        return put( stringcast(key), value );
+    }
+    public Object put(Object key, String value){
+        return put( key, stringcast(value) );
+    }
+    public Object put(String key, String value){
+        return put( stringcast(key), stringcast(value) );
+    }
+    public void   putAll(Map t){
+        foreach( k, v; t ){
+            map[k] = v;
+        }
+    }
+    public Object remove(Object key){
+        if( auto v = key in map ){
+            Object res = *v;
+            map.remove(key);
+            return res;
+        }
+        map.remove(key);
+        return null;
+    }
+    public Object remove(String key){
+        return remove(stringcast(key));
+    }
+    public int    size(){
+        return map.size();
+    }
+    public Collection values(){
+        ArrayList res = new ArrayList( size() );
+        foreach( k, v; map ){
+            res.add( v );
+        }
+        return res;
+    }
+
+    public int opApply (int delegate(ref Object value) dg){
+        return map.opApply( dg );
+    }
+    public int opApply (int delegate(ref Object key, ref Object value) dg){
+        return map.opApply( dg );
+    }
+}
+
 class Dictionary {
     public this(){
     }
@@ -984,6 +1116,9 @@
     public abstract bool        addAll(int index, Collection c);
     public abstract void   clear();
     public abstract bool     contains(Object o);
+    public bool contains(String str){
+        return contains(stringcast(str));
+    }
     public abstract bool     containsAll(Collection c);
     public abstract int  opEquals(Object o);
     public abstract  Object        get(int index);
@@ -1200,6 +1335,9 @@
         implMissing( __FILE__, __LINE__ );
         return false;
     }
+    public bool    contains(String str){
+        return contains(stringcast(str));
+    }
     public bool    containsAll(Collection c){
         implMissing( __FILE__, __LINE__ );
         return false;
@@ -1610,6 +1748,9 @@
     bool    contains(Object elem){
         return list.contains(elem);
     }
+    bool    contains(String elem){
+        return contains(stringcast(elem));
+    }
     bool    containsAll(Collection c){
         foreach(o; c){
             if( !list.contains(o)) return false;
@@ -1640,6 +1781,12 @@
     Object     get(int index){
         return list.get(index);
     }
+    Object     getFirst(){
+        return list.get(0);
+    }
+    Object     getLast(){
+        return list.get(list.size()-1);
+    }
     hash_t    toHash(){
         implMissing( __FILE__, __LINE__ );
         return 0;
@@ -1818,6 +1965,9 @@
         }
         return false;
     }
+    bool    contains(String o){
+        return contains(stringcast(o));
+    }
     bool    containsAll(Collection c){
         implMissing( __FILE__, __LINE__ );
         return false;
@@ -1969,7 +2119,7 @@
 }
 
 class Arrays {
-    public static bool equals(Object[] a, Object[] b){
+    public static bool equals(T)(T[] a, T[] b){
         if( a.length !is b.length ){
             return false;
         }
@@ -1984,6 +2134,34 @@
         }
         return true;
     }
+/+    public static bool equals(Object[] a, Object[] b){
+        if( a.length !is b.length ){
+            return false;
+        }
+        for( int i = 0; i < a.length; i++ ){
+            if( a[i] is null && b[i] is null ){
+                continue;
+            }
+            if( a[i] !is null && b[i] !is null && a[i] == b[i] ){
+                continue;
+            }
+            return false;
+        }
+        return true;
+    }
++/
+    static void sort( T )( T[] a, Comparator c ){
+        bool isLess( T o1, T o2 ){
+            return c.compare( cast(Object)o1, cast(Object)o2 ) < 0;
+        }
+        tango.core.Array.sort( a, &isLess );
+    }
+    static void sort( T : char[] )( T[] a, Comparator c ){
+        bool isLess( T o1, T o2 ){
+            return c.compare( stringcast(o1), stringcast(o2) ) < 0;
+        }
+        tango.core.Array.sort( a, &isLess );
+    }
     static List    asList(Object[] a) {
         if( a.length is 0 ) return Collections.EMPTY_LIST;
         ArrayList res = new ArrayList( a.length );
@@ -1992,6 +2170,9 @@
         }
         return res;
     }
+    public static void fill( String str, char c ){
+        str[] = c;
+    }
 }
 
 class Collections {
@@ -2029,7 +2210,14 @@
         }
         return EMPTY_SET_;
     }
-
+    static int binarySearch(List list, Object key){
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+    static int binarySearch(List list, Object key, Comparator c){
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
     public static List unmodifiableList( List list ){
         implMissing( __FILE__, __LINE__ );
         return null;
@@ -2090,4 +2278,8 @@
     }
 }
 
-
+class LinkedHashMap : HashMap {
+    static this(){
+        implMissing( __FILE__, __LINE__ );
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/dwtxhelper/Date.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,12 @@
+module dwtx.dwtxhelper.Date;
+
+import dwt.dwthelper.utils;
+
+class Date {
+    long getTime(){
+        implMissing(__FILE__,__LINE__);
+        return 0;
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/dwtxhelper/MalformedURLException.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,4 @@
+module dwtx.dwtxhelper.MalformedURLException;
+
+class MalformedURLException {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/dwtxhelper/MessageFormat.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,20 @@
+module dwtx.dwtxhelper.MessageFormat;
+
+import dwt.dwthelper.utils;
+import tango.text.convert.Format;
+
+class MessageFormat {
+    public static String format( String frmt, Object[] args... ){
+        switch( args.length ){
+        case 0: return Format(frmt);
+        case 1: return Format(frmt, args[0]);
+        case 2: return Format(frmt, args[0], args[1]);
+        case 3: return Format(frmt, args[0], args[1], args[2]);
+        case 4: return Format(frmt, args[0], args[1], args[2], args[3]);
+        case 5: return Format(frmt, args[0], args[1], args[2], args[3], args[4]);
+        default:
+            implMissing(__FILE__, __LINE__ );
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/dwtxhelper/PushbackReader.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,11 @@
+module dwtx.dwtxhelper.PushbackReader;
+
+import dwt.dwthelper.utils;
+
+class PushbackReader : Reader {
+    this( Reader reader ){
+    }
+    void unread( char c ){
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/dwtxhelper/StringReader.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,19 @@
+module dwtx.dwtxhelper.StringReader;
+
+import dwt.dwthelper.utils;
+
+class StringReader : Reader {
+    String str;
+    this( String str ){
+        implMissing(__FILE__,__LINE__);
+        this.str = str;
+    }
+    public override int read(char[] cbuf, int off, int len){
+        cbuf[ off .. off+len ] = str[ 0 .. len ];
+        str = str[ len .. $ ];
+        return len;
+    }
+    public override void  close(){
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/dwtxhelper/StringTokenizer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,48 @@
+module dwtx.dwtxhelper.StringTokenizer;
+
+import dwt.dwthelper.utils;
+
+class StringTokenizer {
+
+    this(String){
+        implMissing(__FILE__,__LINE__);
+    }
+
+    this(String,String){
+        implMissing(__FILE__,__LINE__);
+    }
+
+    this(String,String,bool){
+        implMissing(__FILE__,__LINE__);
+    }
+
+    bool hasMoreTokens(){
+        implMissing(__FILE__,__LINE__);
+        return false;
+    }
+
+    String nextToken(){
+        implMissing(__FILE__,__LINE__);
+        return null;
+    }
+
+    String nextToken(String delim){
+        implMissing(__FILE__,__LINE__);
+        return null;
+    }
+
+    bool hasMoreElements(){
+        implMissing(__FILE__,__LINE__);
+        return false;
+    }
+
+    Object nextElement(){
+        implMissing(__FILE__,__LINE__);
+        return null;
+    }
+
+    int countTokens(){
+        implMissing(__FILE__,__LINE__);
+        return 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/dwtxhelper/URL.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,10 @@
+module dwtx.dwtxhelper.URL;
+
+import dwt.dwthelper.utils;
+
+class URL {
+    this(String){
+        implMissing(__FILE__,__LINE__);
+    }
+}
+
--- a/dwtx/dwtxhelper/mangoicu/UBreakIterator.d	Mon Sep 08 01:37:00 2008 +0200
+++ b/dwtx/dwtxhelper/mangoicu/UBreakIterator.d	Mon Sep 08 01:38:10 2008 +0200
@@ -312,6 +312,7 @@
 
         // this is returned by next(), previous() etc ...
         const uint Done = uint.max;
+        alias Done DONE;
 
         /***********************************************************************
 
@@ -454,7 +455,7 @@
                     return ubrk_next (handle);
                 return ubrk_following (handle, offset);
         }
-
+        alias next following;
         /***********************************************************************
 
                 Determine the text boundary preceding the current text
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/dwtxhelper/regex.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,76 @@
+module dwtx.dwtxhelper.regex;
+
+import dwt.dwthelper.utils;
+
+class Matcher {
+    public Pattern pattern(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+    public String    group(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+    public String    group(int n){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+    public  String replaceFirst(String replacement) {
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+    public int start(){
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+    public int end(){
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+    public bool find(){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+    public bool find(int start){
+        implMissing( __FILE__, __LINE__ );
+        return false;
+    }
+}
+
+class Pattern {
+    public static const int MULTILINE;
+    public static const int CASE_INSENSITIVE ;
+    public static const int UNICODE_CASE ;
+
+    public String pattern(){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+    public int flags(){
+        implMissing( __FILE__, __LINE__ );
+        return 0;
+    }
+    public static Pattern compile(String regex){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+    public static Pattern compile(String regex, int flags){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+    public Matcher matcher(CharSequence input){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+    public Matcher matcher(String input){
+        implMissing( __FILE__, __LINE__ );
+        return null;
+    }
+}
+
+class PatternSyntaxException : IllegalArgumentException {
+    this(String desc, String regex, int index) {
+        super(desc);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/contentassist/IContentAssistSubjectControl.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,271 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.contentassist.IContentAssistSubjectControl;
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.custom.VerifyKeyListener;
+import dwt.events.KeyListener;
+import dwt.events.SelectionListener;
+import dwt.graphics.Point;
+import dwt.widgets.Control;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IEventConsumer;
+
+
+/**
+ * A content assist subject control can request assistance provided by a
+ * {@linkplain dwtx.jface.contentassist.ISubjectControlContentAssistant subject control content assistant}.
+ *
+ * @since 3.0
+ */
+public interface IContentAssistSubjectControl {
+
+    /**
+     * Returns the control of this content assist subject control.
+     *
+     * @return the control of this content assist subject control
+     */
+    Control getControl();
+
+    /**
+     * Returns the line height.
+     *
+     * @return line height in pixel
+     * @exception dwt.DWTException
+     *               <ul>
+     *                  <li>{@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been
+     *                      disposed</li>
+     *                  <li>{@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the
+     *                       thread that created the receiver</li>
+     *               </ul>
+     */
+    int getLineHeight();
+
+    /**
+     * Returns the caret position relative to the start of the text in widget
+     * coordinates.
+     *
+     * @return the caret position relative to the start of the text in widget
+     *         coordinates
+     * @exception dwt.DWTException
+     *               <ul>
+     *                  <li>{@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been
+     *                      disposed</li>
+     *                  <li>{@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the
+     *                      thread that created the receiver</li>
+     *               </ul>
+     */
+    int getCaretOffset();
+
+    /**
+     * Returns the x, y location of the upper left corner of the character
+     * bounding box at the specified offset in the text. The point is relative
+     * to the upper left corner of the widget client area.
+     *
+     * @param offset widget offset relative to the start of the content 0
+     *           <= offset <= getCharCount()
+     * @return x, y location of the upper left corner of the character bounding
+     *         box at the specified offset in the text
+     * @exception dwt.DWTException
+     *          <ul>
+     *              <li>{@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed</li>
+     *              <li>{@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver</li>
+     *          </ul>
+     * @exception IllegalArgumentException when the offset is outside the valid range
+     */
+    Point getLocationAtOffset(int offset);
+
+    /**
+     * Returns the line delimiter used for entering new lines by key down or
+     * paste operation.
+     *
+     * @return line delimiter used for entering new lines by key down or paste
+     *         operation
+     * @exception dwt.DWTException
+     *          <ul>
+     *              <li>{@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed</li>
+     *              <li>{@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver</li>
+     *          </ul>
+     */
+    String getLineDelimiter();
+
+    /**
+     * Returns the selected range in the subject's widget.
+     *
+     * @return start and length of the selection, x is the offset of the
+     * @exception dwt.DWTException
+     *          <ul>
+     *              <li>{@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed</li>
+     *              <li>{@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver</li>
+     *          </ul>
+     */
+    Point getWidgetSelectionRange();
+
+    /**
+     * Returns the selected range.
+     *
+     * @return start and length of the selection, x is the offset and y the
+     *         length based on the subject's model (e.g. document)
+     */
+    Point getSelectedRange();
+
+    /**
+     * Sets the selected range. Offset and length based on the subject's
+     * model (e.g. document).
+     *
+     * @param offset the offset of the selection based on the subject's model e.g. document
+     * @param length the length of the selection based on the subject's model e.g. document
+     */
+    void setSelectedRange(int offset, int length);
+
+    /**
+     * Reveals the given region. Offset and length based on the subject's
+     * model (e.g. document).
+     *
+     * @param offset the offset of the selection based on the subject's model e.g. document
+     * @param length the length of the selection based on the subject's model e.g. document
+     */
+    void revealRange(int offset, int length);
+
+    /**
+     * Returns this content assist subject control's document.
+     *
+     * @return the viewer's input document
+     */
+    IDocument getDocument();
+
+    /**
+     * If supported, appends a verify key listener to the viewer's list of verify key
+     * listeners. If the listener is already registered with the viewer this
+     * call moves the listener to the end of the list.
+     * <p>
+     * Note: This content assist subject control may not support appending a verify
+     * listener, in which case <code>false</code> will be returned. If this
+     * content assist subject control only supports <code>addVerifyKeyListener</code>
+     * then this method can be used but <code>prependVerifyKeyListener</code>
+     * must return <code>false</code>.
+     * </p>
+     *
+     * @param verifyKeyListener the listener to be added
+     * @return <code>true</code> if the listener was added
+     */
+    bool appendVerifyKeyListener(VerifyKeyListener verifyKeyListener);
+
+    /**
+     * If supported, inserts the verify key listener at the beginning of this content assist
+     * subject's list of verify key listeners. If the listener is already
+     * registered with the viewer this call moves the listener to the beginning
+     * of the list.
+     * <p>
+     * Note: This content assist subject control may not support prepending a verify
+     * listener, in which case <code>false</code> will be returned. However,
+     * {@link #appendVerifyKeyListener(VerifyKeyListener)} might work.
+     * </p>
+     *
+     * @param verifyKeyListener the listener to be inserted
+     * @return <code>true</code> if the listener was added
+     */
+    bool prependVerifyKeyListener(VerifyKeyListener verifyKeyListener);
+
+    /**
+     * Removes the verify key listener from this content assist subject control's
+     * list of verify key listeners. If the listener is not registered, this
+     * call has no effect.
+     *
+     * @param verifyKeyListener the listener to be removed
+     */
+    void removeVerifyKeyListener(VerifyKeyListener verifyKeyListener);
+
+    /**
+     * Tests whether a verify key listener can be added either using <code>prependVerifyKeyListener</code>
+     * or {@link #appendVerifyKeyListener(VerifyKeyListener)}.
+     *
+     * @return <code>true</code> if adding verify key listeners is supported
+     */
+    bool supportsVerifyKeyListener();
+
+    /**
+     * Adds the listener to the collection of listeners who will be notified
+     * when keys are pressed and released on the system keyboard, by sending it
+     * one of the messages defined in the {@link KeyListener} interface.
+     *
+     * @param keyListener the listener which should be notified
+     * @exception IllegalArgumentException if the listener is <code>null</code>
+     * @exception dwt.DWTException
+     *          <ul>
+     *              <li>{@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed</li>
+     *              <li>{@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver</li>
+     *          </ul>
+     *
+     * @see KeyListener
+     * @see #removeKeyListener(KeyListener)
+     */
+    void addKeyListener(KeyListener keyListener);
+
+    /**
+     * Removes the listener from the collection of listeners who will be
+     * notified when keys are pressed and released on the system keyboard.
+     *
+     * @param keyListener the listener which should be notified
+     * @exception IllegalArgumentException if the listener is null</li>
+     * @exception dwt.DWTException
+     *          <ul>
+     *              <li>{@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed</li>
+     *              <li>{@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver</li>
+     *          </ul>
+     * @see KeyListener
+     * @see #addKeyListener(KeyListener)
+     */
+    void removeKeyListener(KeyListener keyListener);
+
+    /**
+     * If supported, registers an event consumer with this content assist
+     * subject.
+     *
+     * @param eventConsumer the content assist subject control's event consumer. <code>null</code>
+     *           is a valid argument.
+     */
+    void setEventConsumer(IEventConsumer eventConsumer);
+
+    /**
+     * Removes the specified selection listener.
+     * <p>
+     *
+     * @param selectionListener the listener
+     * @exception dwt.DWTException <ul>
+     *          <ul>
+     *              <li>{@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed</li>
+     *              <li>{@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver</li>
+     *          </ul>
+     * @exception IllegalArgumentException if listener is <code>null</code>
+     */
+    void removeSelectionListener(SelectionListener selectionListener);
+
+    /**
+     * If supported, adds a selection listener. A Selection event is sent by the widget when the
+     * selection has changed.
+     * <p>
+     *
+     * @param selectionListener the listener
+     * @return <code>true</code> if adding a selection listener is supported
+     *          <ul>
+     *              <li>{@link dwt.DWT#ERROR_WIDGET_DISPOSED} - if the receiver has been disposed</li>
+     *              <li>{@link dwt.DWT#ERROR_THREAD_INVALID_ACCESS} - if not called from the thread that created the receiver</li>
+     *          </ul>
+     * @exception IllegalArgumentException if listener is <code>null</code>
+     */
+    bool addSelectionListener(SelectionListener selectionListener);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/contentassist/ISubjectControlContentAssistProcessor.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.contentassist.ISubjectControlContentAssistProcessor;
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.contentassist.ICompletionProposal;
+import dwtx.jface.text.contentassist.IContentAssistProcessor;
+import dwtx.jface.text.contentassist.IContextInformation;
+import dwtx.jface.contentassist.IContentAssistSubjectControl;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.contentassist.IContentAssistProcessor}
+ * which provides the context for the
+ * {@linkplain dwtx.jface.contentassist.ISubjectControlContentAssistant subject control content assistant}.
+ *
+ * @since 3.0
+ * @deprecated As of 3.2, replaced by Platform UI's field assist support
+ */
+public interface ISubjectControlContentAssistProcessor : IContentAssistProcessor {
+
+    /**
+     * Returns a list of completion proposals based on the specified location
+     * within the document that corresponds to the current cursor position
+     * within the text viewer.
+     *
+     * @param contentAssistSubjectControl the content assist subject control whose
+     *           document is used to compute the proposals
+     * @param documentOffset an offset within the document for which
+     *           completions should be computed
+     * @return an array of completion proposals or <code>null</code> if no
+     *         proposals are possible
+     */
+    ICompletionProposal[] computeCompletionProposals(IContentAssistSubjectControl contentAssistSubjectControl, int documentOffset);
+
+    /**
+     * Returns information about possible contexts based on the specified
+     * location within the document that corresponds to the current cursor
+     * position within the content assist subject control.
+     *
+     * @param contentAssistSubjectControl the content assist subject control whose
+     *           document is used to compute the possible contexts
+     * @param documentOffset an offset within the document for which context
+     *           information should be computed
+     * @return an array of context information objects or <code>null</code>
+     *         if no context could be found
+     */
+    IContextInformation[] computeContextInformation(IContentAssistSubjectControl contentAssistSubjectControl, int documentOffset);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/contentassist/ISubjectControlContentAssistant.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.contentassist.ISubjectControlContentAssistant;
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.contentassist.IContentAssistant;
+
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.IContentAssistant} to
+ * allow to install a content assistant on the given
+ * {@linkplain dwtx.jface.contentassist.IContentAssistSubjectControl content assist subject control}.
+ *
+ * @since 3.0
+ * @deprecated As of 3.2, replaced by Platform UI's field assist support
+ */
+public interface ISubjectControlContentAssistant : IContentAssistant {
+
+    /**
+     * Installs content assist support on the given subject.
+     *
+     * @param contentAssistSubjectControl the one who requests content assist
+     */
+    void install(IContentAssistSubjectControl contentAssistSubjectControl);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/contentassist/ISubjectControlContextInformationPresenter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.contentassist.ISubjectControlContextInformationPresenter;
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.contentassist.IContextInformation;
+import dwtx.jface.text.contentassist.IContextInformationPresenter;
+import dwtx.jface.contentassist.IContentAssistSubjectControl;
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.IContextInformationPresenter} to
+ * allow to install a content assistant on the given
+ * {@linkplain dwtx.jface.contentassist.IContentAssistSubjectControl content assist subject control}.
+ *
+ * @since 3.0
+ * @deprecated As of 3.2, replaced by Platform UI's field assist support
+ */
+public interface ISubjectControlContextInformationPresenter : IContextInformationPresenter {
+
+    /**
+     * Installs this presenter for the given context information.
+     *
+     * @param info the context information which this presenter should style
+     * @param contentAssistSubjectControl the content assist subject control
+     * @param offset the document offset for which the information has been computed
+     */
+    void install(IContextInformation info, IContentAssistSubjectControl contentAssistSubjectControl, int offset);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/contentassist/ISubjectControlContextInformationValidator.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.contentassist.ISubjectControlContextInformationValidator;
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.contentassist.IContextInformation;
+import dwtx.jface.text.contentassist.IContextInformationValidator;
+import dwtx.jface.contentassist.IContentAssistSubjectControl;
+
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.IContextInformationValidator} to
+ * allow to install a content assistant on the given
+ * {@linkplain dwtx.jface.contentassist.IContentAssistSubjectControl content assist subject control}.
+ *
+ * @since 3.0
+ * @deprecated As of 3.2, replaced by Platform UI's field assist support
+ */
+public interface ISubjectControlContextInformationValidator : IContextInformationValidator {
+
+    /**
+     * Installs this validator for the given context information.
+     *
+     * @param info the context information which this validator should check
+     * @param contentAssistSubjectControl the content assist subject control
+     * @param offset the document offset for which the information
+     *           has been computed
+     */
+    void install(IContextInformation info, IContentAssistSubjectControl contentAssistSubjectControl, int offset);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/DelayedInputChangeListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.DelayedInputChangeListener;
+
+import dwtx.jface.internal.text.NonDeletingPositionUpdater; // packageimport
+import dwtx.jface.internal.text.InternalAccessor; // packageimport
+import dwtx.jface.internal.text.StickyHoverManager; // packageimport
+import dwtx.jface.internal.text.InformationControlReplacer; // packageimport
+import dwtx.jface.internal.text.TableOwnerDrawSupport; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.IDelayedInputChangeProvider;
+import dwtx.jface.text.IInputChangedListener;
+
+
+/**
+ * A delayed input change listener that forwards delayed input changes to an information control replacer.
+ * 
+ * @since 3.4
+ */
+public final class DelayedInputChangeListener : IInputChangedListener {
+    
+    private const IDelayedInputChangeProvider fChangeProvider;
+    private const InformationControlReplacer fInformationControlReplacer;
+
+    /**
+     * Creates a new listener.
+     * 
+     * @param changeProvider the information control with delayed input changes
+     * @param informationControlReplacer the information control replacer, whose information control should get the new input
+     */
+    public this(IDelayedInputChangeProvider changeProvider, InformationControlReplacer informationControlReplacer) {
+        fChangeProvider= changeProvider;
+        fInformationControlReplacer= informationControlReplacer;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDelayedInputChangeListener#inputChanged(java.lang.Object)
+     */
+    public void inputChanged(Object newInput) {
+        fChangeProvider.setDelayedInputChangeListener(null);
+        fInformationControlReplacer.setDelayedInput(newInput);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/InformationControlReplacer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,218 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.InformationControlReplacer;
+
+import dwtx.jface.internal.text.NonDeletingPositionUpdater; // packageimport
+import dwtx.jface.internal.text.InternalAccessor; // packageimport
+import dwtx.jface.internal.text.StickyHoverManager; // packageimport
+import dwtx.jface.internal.text.TableOwnerDrawSupport; // packageimport
+import dwtx.jface.internal.text.DelayedInputChangeListener; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Shell;
+import dwtx.jface.text.AbstractInformationControlManager;
+import dwtx.jface.text.AbstractReusableInformationControlCreator;
+import dwtx.jface.text.DefaultInformationControl;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.IInformationControlExtension2;
+import dwtx.jface.text.IInformationControlExtension3;
+import dwtx.jface.util.Geometry;
+
+
+/**
+ * An information control replacer can replace an
+ * {@link AbstractInformationControlManager}'s control.
+ *
+ * @see AbstractInformationControlManager#setInformationControlReplacer(InformationControlReplacer)
+ * @since 3.4
+ */
+public class InformationControlReplacer : AbstractInformationControlManager {
+    alias AbstractInformationControlManager.showInformationControl showInformationControl;
+    /**
+     * Minimal width in pixels.
+     */
+    private static const int MIN_WIDTH= 80;
+    /**
+     * Minimal height in pixels.
+     */
+    private static const int MIN_HEIGHT= 50;
+
+    /**
+     * Default control creator.
+     */
+    protected static class DefaultInformationControlCreator : AbstractReusableInformationControlCreator {
+        public IInformationControl doCreateInformationControl(Shell shell) {
+            return new DefaultInformationControl(shell, true);
+        }
+    }
+
+    private bool fIsReplacing;
+    private Object fReplacableInformation;
+    private bool fDelayedInformationSet;
+    private Rectangle fReplaceableArea;
+    private Rectangle fContentBounds;
+
+
+    /**
+     * Creates a new information control replacer.
+     *
+     * @param creator the default information control creator
+     */
+    public this(IInformationControlCreator creator) {
+        super(creator);
+        takesFocusWhenVisible(false);
+    }
+
+    /**
+     * Replace the information control.
+     *
+     * @param informationPresenterControlCreator the information presenter control creator
+     * @param contentBounds the bounds of the content area of the information control
+     * @param information the information to show
+     * @param subjectArea the subject area
+     * @param takeFocus <code>true</code> iff the replacing information control should take focus
+     */
+    public void replaceInformationControl(IInformationControlCreator informationPresenterControlCreator, Rectangle contentBounds, Object information, Rectangle subjectArea, bool takeFocus) {
+
+        try {
+            fIsReplacing= true;
+            if (! fDelayedInformationSet)
+                fReplacableInformation= information;
+            else
+                takeFocus= true; // delayed input has been set, so the original info control must have been focused
+            fContentBounds= contentBounds;
+            fReplaceableArea= subjectArea;
+
+            setCustomInformationControlCreator(informationPresenterControlCreator);
+
+            takesFocusWhenVisible(takeFocus);
+
+            showInformation();
+        } finally {
+            fIsReplacing= false;
+            fReplacableInformation= null;
+            fDelayedInformationSet= false;
+            fReplaceableArea= null;
+            setCustomInformationControlCreator(null);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#computeInformation()
+     */
+    protected void computeInformation() {
+        if (fIsReplacing && fReplacableInformation !is null) {
+            setInformation(fReplacableInformation, fReplaceableArea);
+            return;
+        }
+
+        if (DEBUG)
+            System.out_.println("InformationControlReplacer: no active replaceable"); //$NON-NLS-1$
+    }
+
+    /**
+     * Opens the information control with the given information and the specified
+     * subject area. It also activates the information control closer.
+     *
+     * @param subjectArea the information area
+     * @param information the information
+     */
+    public void showInformationControl(Rectangle subjectArea, Object information) {
+        IInformationControl informationControl= getInformationControl();
+
+        Rectangle controlBounds= fContentBounds;
+        if ( cast(IInformationControlExtension3)informationControl ) {
+            IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) informationControl;
+            Rectangle trim= iControl3.computeTrim();
+            controlBounds= Geometry.add(controlBounds, trim);
+
+            /*
+             * Ensure minimal size. Interacting with a tiny information control
+             * (resizing, selecting text) would be a pain.
+             */
+            controlBounds.width= Math.max(controlBounds.width, MIN_WIDTH);
+            controlBounds.height= Math.max(controlBounds.height, MIN_HEIGHT);
+
+            getInternalAccessor().cropToClosestMonitor(controlBounds);
+        }
+
+        Point location= Geometry.getLocation(controlBounds);
+        Point size= Geometry.getSize(controlBounds);
+
+        // Caveat: some IInformationControls fail unless setSizeConstraints(..) is called with concrete values
+        informationControl.setSizeConstraints(size.x, size.y);
+
+        if ( cast(IInformationControlExtension2)informationControl )
+            (cast(IInformationControlExtension2) informationControl).setInput(information);
+        else
+            informationControl.setInformation(information.toString());
+
+        informationControl.setLocation(location);
+        informationControl.setSize(size.x, size.y);
+
+        showInformationControl(subjectArea);
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl()
+     */
+    public void hideInformationControl() {
+        super.hideInformationControl();
+    }
+
+    /**
+     * @param input the delayed input, or <code>null</code> to request cancellation
+     */
+    public void setDelayedInput(Object input) {
+        fReplacableInformation= input;
+        if (! isReplacing()) {
+            fDelayedInformationSet= true;
+        } else if (cast(IInformationControlExtension2)getCurrentInformationControl2() ) {
+            (cast(IInformationControlExtension2) getCurrentInformationControl2()).setInput(input);
+        } else if (getCurrentInformationControl2() !is null) {
+            getCurrentInformationControl2().setInformation(input.toString());
+        }
+    }
+
+    /**
+     * Tells whether the replacer is currently replacing another information control.
+     *
+     * @return <code>true</code> while code from {@link #replaceInformationControl(IInformationControlCreator, Rectangle, Object, Rectangle, bool)} is run
+     */
+    public bool isReplacing() {
+        return fIsReplacing;
+    }
+
+    /**
+     * @return the current information control, or <code>null</code> if none available
+     */
+    public IInformationControl getCurrentInformationControl2() {
+        return getInternalAccessor().getCurrentInformationControl();
+    }
+
+    /**
+     * The number of pixels to blow up the keep-up zone.
+     *
+     * @return the margin in pixels
+     */
+    public int getKeepUpMargin() {
+        return 15;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/InternalAccessor.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.InternalAccessor;
+
+import dwtx.jface.internal.text.NonDeletingPositionUpdater; // packageimport
+import dwtx.jface.internal.text.StickyHoverManager; // packageimport
+import dwtx.jface.internal.text.InformationControlReplacer; // packageimport
+import dwtx.jface.internal.text.TableOwnerDrawSupport; // packageimport
+import dwtx.jface.internal.text.DelayedInputChangeListener; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.graphics.Rectangle;
+import dwtx.jface.text.AbstractInformationControlManager;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlExtension3;
+import dwtx.jface.text.ITextViewerExtension8;
+import dwtx.jface.text.ITextViewerExtension8;
+
+
+/**
+ * An internal class that gives access to internal methods of {@link
+ * AbstractInformationControlManager} and subclasses.
+ *
+ * @since 3.4
+ */
+public abstract class InternalAccessor {
+
+    /**
+     * Returns the current information control, or <code>null</code> if none.
+     *
+     * @return the current information control, or <code>null</code> if none
+     */
+    public abstract IInformationControl getCurrentInformationControl();
+
+    /**
+     * Sets the information control replacer for this manager and disposes the
+     * old one if set.
+     *
+     * @param replacer the information control replacer for this manager, or
+     *            <code>null</code> if no information control replacing should
+     *            take place
+     */
+    public abstract void setInformationControlReplacer(InformationControlReplacer replacer);
+
+    /**
+     * Returns the current information control replacer or <code>null</code> if none has been installed.
+     *
+     * @return the current information control replacer or <code>null</code> if none has been installed
+     */
+    public abstract InformationControlReplacer getInformationControlReplacer();
+
+    /**
+     * Tests whether the given information control is replaceable.
+     *
+     * @param iControl information control or <code>null</code> if none
+     * @return <code>true</code> if information control is replaceable, <code>false</code> otherwise
+     */
+    public abstract bool canReplace(IInformationControl iControl);
+
+    /**
+     * Tells whether this manager's information control is currently being replaced.
+     *
+     * @return <code>true</code> if a replace is in progress
+     */
+    public abstract bool isReplaceInProgress();
+
+    /**
+     * Crops the given bounds such that they lie completely on the closest monitor.
+     *
+     * @param bounds shell bounds to crop
+     */
+    public abstract void cropToClosestMonitor(Rectangle bounds);
+
+    /**
+     * Sets the hover enrich mode. Only applicable when an information
+     * control replacer has been set with
+     * {@link #setInformationControlReplacer(InformationControlReplacer)} .
+     *
+     * @param mode the enrich mode
+     * @see ITextViewerExtension8#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode)
+     */
+    public abstract void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode);
+
+    /**
+     * Indicates whether the mouse cursor is allowed to leave the subject area without closing the hover.
+     *
+     * @return whether the mouse cursor is allowed to leave the subject area without closing the hover
+     */
+    public abstract bool getAllowMouseExit();
+
+    /**
+     * Replaces this manager's information control as defined by
+     * the information control replacer.
+     * <strong>Must only be called when the information control is instanceof {@link IInformationControlExtension3}!</strong>
+     *
+     * @param takeFocus <code>true</code> iff the replacing information control should take focus
+     */
+    public abstract void replaceInformationControl(bool takeFocus);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/NonDeletingPositionUpdater.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.NonDeletingPositionUpdater;
+
+import dwtx.jface.internal.text.InternalAccessor; // packageimport
+import dwtx.jface.internal.text.StickyHoverManager; // packageimport
+import dwtx.jface.internal.text.InformationControlReplacer; // packageimport
+import dwtx.jface.internal.text.TableOwnerDrawSupport; // packageimport
+import dwtx.jface.internal.text.DelayedInputChangeListener; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IPositionUpdater;
+import dwtx.jface.text.Position;
+
+
+/**
+ * A position updater that never deletes a position. If the region containing
+ * the position is deleted, the position is moved to the beginning/end (falling
+ * together) of the change. If the region containing the position is replaced,
+ * the position is placed at the same location inside the replacement text, but
+ * always inside the replacement text.
+ *
+ * @since 3.1
+ */
+public final class NonDeletingPositionUpdater : IPositionUpdater {
+    /** The position category. */
+    private const String fCategory;
+
+    /**
+     * Creates a new updater for the given <code>category</code>.
+     *
+     * @param category the new category.
+     */
+    public this(String category) {
+        fCategory= category;
+    }
+
+    /*
+     * @see dwtx.jface.text.IPositionUpdater#update(dwtx.jface.text.DocumentEvent)
+     */
+    public void update(DocumentEvent event) {
+
+        int eventOffset= event.getOffset();
+        int eventOldEndOffset= eventOffset + event.getLength();
+        int eventNewLength= event.getText() is null ? 0 : event.getText().length();
+        int eventNewEndOffset= eventOffset + eventNewLength;
+        int deltaLength= eventNewLength - event.getLength();
+
+        try {
+            Position[] positions= event.getDocument().getPositions(fCategory);
+
+            for (int i= 0; i !is positions.length; i++) {
+
+                Position position= positions[i];
+
+                if (position.isDeleted())
+                    continue;
+
+                int offset= position.getOffset();
+                int length= position.getLength();
+                int end= offset + length;
+
+                if (offset > eventOldEndOffset) {
+                    // position comes way after change - shift
+                    position.setOffset(offset + deltaLength);
+                } else if (end < eventOffset) {
+                    // position comes way before change - leave alone
+                } else if (offset <= eventOffset && end >= eventOldEndOffset) {
+                    // event completely internal to the position - adjust length
+                    position.setLength(length + deltaLength);
+                } else if (offset < eventOffset) {
+                    // event extends over end of position - include the
+                    // replacement text into the position
+                    position.setLength(eventNewEndOffset - offset);
+                } else if (end > eventOldEndOffset) {
+                    // event extends from before position into it - adjust
+                    // offset and length, including the replacement text into
+                    // the position
+                    position.setOffset(eventOffset);
+                    int deleted= eventOldEndOffset - offset;
+                    position.setLength(length - deleted + eventNewLength);
+                } else {
+                    // event comprises the position - keep it at the same
+                    // position, but always inside the replacement text
+                    int newOffset= Math.min(offset, eventNewEndOffset);
+                    int newEndOffset= Math.min(end, eventNewEndOffset);
+                    position.setOffset(newOffset);
+                    position.setLength(newEndOffset - newOffset);
+                }
+            }
+        } catch (BadPositionCategoryException e) {
+            // ignore and return
+        }
+    }
+
+    /**
+     * Returns the position category.
+     *
+     * @return the position category
+     */
+    public String getCategory() {
+        return fCategory;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/StickyHoverManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,385 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.StickyHoverManager;
+
+import dwtx.jface.internal.text.NonDeletingPositionUpdater; // packageimport
+import dwtx.jface.internal.text.InternalAccessor; // packageimport
+import dwtx.jface.internal.text.InformationControlReplacer; // packageimport
+import dwtx.jface.internal.text.TableOwnerDrawSupport; // packageimport
+import dwtx.jface.internal.text.DelayedInputChangeListener; // packageimport
+
+import dwt.dwthelper.utils;
+import tango.text.convert.Format;
+
+import dwt.DWT;
+import dwt.events.ControlEvent;
+import dwt.events.ControlListener;
+import dwt.events.FocusEvent;
+import dwt.events.FocusListener;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlExtension3;
+import dwtx.jface.text.IInformationControlExtension5;
+import dwtx.jface.text.IViewportListener;
+import dwtx.jface.text.IWidgetTokenKeeper;
+import dwtx.jface.text.IWidgetTokenKeeperExtension;
+import dwtx.jface.text.IWidgetTokenOwner;
+import dwtx.jface.text.TextViewer;
+import dwtx.jface.util.Geometry;
+
+/**
+ * Implements a sticky hover control, i.e. a control that replaces a hover
+ * with an enriched and focusable control.
+ * <p>
+ * The information control is made visible on request by calling
+ * {@link #showInformationControl(Rectangle)}.
+ * </p>
+ * <p>
+ * Clients usually instantiate and configure this class before using it. The configuration
+ * must be consistent: This means the used {@link dwtx.jface.text.IInformationControlCreator}
+ * must create an information control expecting information in the same format the configured
+ * {@link dwtx.jface.text.information.IInformationProvider}s use to encode the information they provide.
+ * </p>
+ *
+ * @since 3.4
+ */
+public class StickyHoverManager : InformationControlReplacer , IWidgetTokenKeeper, IWidgetTokenKeeperExtension {
+
+    /**
+     * Priority of the info controls managed by this sticky hover manager.
+     * <p>
+     * Note: Only applicable when info control does not have focus.
+     * -5 as value has been chosen in order to be beaten by the hovers of TextViewerHoverManager.
+     * </p>
+     */
+    private static const int WIDGET_PRIORITY= -5;
+
+
+    /**
+     * Internal information control closer. Listens to several events issued by its subject control
+     * and closes the information control when necessary.
+     */
+    class Closer : IInformationControlCloser, ControlListener, MouseListener, IViewportListener, KeyListener, FocusListener, Listener {
+        //TODO: Catch 'Esc' key in fInformationControlToClose: Don't dispose, just hideInformationControl().
+        // This would allow to reuse the information control also when the user explicitly closes it.
+
+        //TODO: if subject control is a Scrollable, should add selection listeners to both scroll bars
+        // (and remove the ViewPortListener, which only listens to vertical scrolling)
+
+        /** The subject control. */
+        private Control fSubjectControl;
+        /** Indicates whether this closer is active. */
+        private bool fIsActive= false;
+        /** The display. */
+        private Display fDisplay;
+
+        /*
+         * @see IInformationControlCloser#setSubjectControl(Control)
+         */
+        public void setSubjectControl(Control control) {
+            fSubjectControl= control;
+        }
+
+        /*
+         * @see IInformationControlCloser#setInformationControl(IInformationControl)
+         */
+        public void setInformationControl(IInformationControl control) {
+            // NOTE: we use getCurrentInformationControl2() from the outer class
+        }
+
+        /*
+         * @see IInformationControlCloser#start(Rectangle)
+         */
+        public void start(Rectangle informationArea) {
+
+            if (fIsActive)
+                return;
+            fIsActive= true;
+
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
+                fSubjectControl.addControlListener(this);
+                fSubjectControl.addMouseListener(this);
+                fSubjectControl.addKeyListener(this);
+            }
+
+            fTextViewer.addViewportListener(this);
+
+            IInformationControl fInformationControlToClose= getCurrentInformationControl2();
+            if (fInformationControlToClose !is null)
+                fInformationControlToClose.addFocusListener(this);
+
+            fDisplay= fSubjectControl.getDisplay();
+            if (!fDisplay.isDisposed()) {
+                fDisplay.addFilter(DWT.MouseMove, this);
+                fDisplay.addFilter(DWT.FocusOut, this);
+            }
+        }
+
+        /*
+         * @see IInformationControlCloser#stop()
+         */
+        public void stop() {
+
+            if (!fIsActive)
+                return;
+            fIsActive= false;
+
+            fTextViewer.removeViewportListener(this);
+
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
+                fSubjectControl.removeControlListener(this);
+                fSubjectControl.removeMouseListener(this);
+                fSubjectControl.removeKeyListener(this);
+            }
+
+            IInformationControl fInformationControlToClose= getCurrentInformationControl2();
+            if (fInformationControlToClose !is null)
+                fInformationControlToClose.removeFocusListener(this);
+
+            if (fDisplay !is null && !fDisplay.isDisposed()) {
+                fDisplay.removeFilter(DWT.MouseMove, this);
+                fDisplay.removeFilter(DWT.FocusOut, this);
+            }
+
+            fDisplay= null;
+        }
+
+        /*
+         * @see ControlListener#controlResized(ControlEvent)
+         */
+         public void controlResized(ControlEvent e) {
+             hideInformationControl();
+        }
+
+        /*
+         * @see ControlListener#controlMoved(ControlEvent)
+         */
+         public void controlMoved(ControlEvent e) {
+             hideInformationControl();
+        }
+
+        /*
+         * @see MouseListener#mouseDown(MouseEvent)
+         */
+         public void mouseDown(MouseEvent e) {
+             hideInformationControl();
+        }
+
+        /*
+         * @see MouseListener#mouseUp(MouseEvent)
+         */
+        public void mouseUp(MouseEvent e) {
+        }
+
+        /*
+         * @see MouseListener#mouseDoubleClick(MouseEvent)
+         */
+        public void mouseDoubleClick(MouseEvent e) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see IViewportListenerListener#viewportChanged(int)
+         */
+        public void viewportChanged(int topIndex) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see KeyListener#keyPressed(KeyEvent)
+         */
+        public void keyPressed(KeyEvent e) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see KeyListener#keyReleased(KeyEvent)
+         */
+        public void keyReleased(KeyEvent e) {
+        }
+
+        /*
+         * @see dwt.events.FocusListener#focusGained(dwt.events.FocusEvent)
+         */
+        public void focusGained(FocusEvent e) {
+        }
+
+        /*
+         * @see dwt.events.FocusListener#focusLost(dwt.events.FocusEvent)
+         */
+        public void focusLost(FocusEvent e) {
+            if (DEBUG) System.out_.println(Format("StickyHoverManager.Closer.focusLost(): {}", e)); //$NON-NLS-1$
+            Display d= fSubjectControl.getDisplay();
+            d.asyncExec(new class()  Runnable {
+                // Without the asyncExec, mouse clicks to the workbench window are swallowed.
+                public void run() {
+                    hideInformationControl();
+                }
+            });
+        }
+
+        /*
+         * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event)
+         */
+        public void handleEvent(Event event) {
+            if (event.type is DWT.MouseMove) {
+                if (!( cast(Control)event.widget ) || event.widget.isDisposed())
+                    return;
+
+                IInformationControl infoControl= getCurrentInformationControl2();
+                if (infoControl !is null && !infoControl.isFocusControl() && cast(IInformationControlExtension3)infoControl ) {
+//                  if (DEBUG) System.out_.println("StickyHoverManager.Closer.handleEvent(): activeShell= " + fDisplay.getActiveShell()); //$NON-NLS-1$
+                    IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) infoControl;
+                    Rectangle controlBounds= iControl3.getBounds();
+                    if (controlBounds !is null) {
+                        Point mouseLoc= event.display.map(cast(Control) event.widget, null, event.x, event.y);
+                        int margin= getKeepUpMargin();
+                        Geometry.expand(controlBounds, margin, margin, margin, margin);
+                        if (!controlBounds.contains(mouseLoc)) {
+                            hideInformationControl();
+                        }
+                    }
+
+                } else {
+                    /*
+                     * TODO: need better understanding of why/if this is needed.
+                     * Looks like the same panic code we have in dwtx.jface.text.AbstractHoverInformationControlManager.Closer.handleMouseMove(Event)
+                     */
+                    if (fDisplay !is null && !fDisplay.isDisposed())
+                        fDisplay.removeFilter(DWT.MouseMove, this);
+                }
+
+            } else if (event.type is DWT.FocusOut) {
+                if (DEBUG) System.out_.println(Format("StickyHoverManager.Closer.handleEvent(): focusOut: {}", event)); //$NON-NLS-1$
+                IInformationControl iControl= getCurrentInformationControl2();
+                if (iControl !is null && ! iControl.isFocusControl())
+                    hideInformationControl();
+            }
+        }
+    }
+
+
+    private const TextViewer fTextViewer;
+
+
+    /**
+     * Creates a new sticky hover manager.
+     *
+     * @param textViewer the text viewer
+     */
+    public this(TextViewer textViewer) {
+        super(new DefaultInformationControlCreator());
+
+        fTextViewer= textViewer;
+        setCloser(new Closer());
+
+        install(fTextViewer.getTextWidget());
+    }
+
+    /*
+     * @see AbstractInformationControlManager#showInformationControl(Rectangle)
+     */
+    protected void showInformationControl(Rectangle subjectArea) {
+        if (fTextViewer !is null && fTextViewer.requestWidgetToken(this, WIDGET_PRIORITY))
+            super.showInformationControl(subjectArea);
+        else
+            if (DEBUG)
+                System.out_.println("cancelled StickyHoverManager.showInformationControl(..): did not get widget token (with prio)"); //$NON-NLS-1$
+    }
+
+    /*
+     * @see AbstractInformationControlManager#hideInformationControl()
+     */
+    public void hideInformationControl() {
+        try {
+            super.hideInformationControl();
+        } finally {
+            if (fTextViewer !is null)
+                fTextViewer.releaseWidgetToken(this);
+        }
+    }
+
+    /*
+     * @see AbstractInformationControlManager#handleInformationControlDisposed()
+     */
+    protected void handleInformationControlDisposed() {
+        try {
+            super.handleInformationControlDisposed();
+        } finally {
+            if (fTextViewer !is null)
+                fTextViewer.releaseWidgetToken(this);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeper#requestWidgetToken(IWidgetTokenOwner)
+     */
+    public bool requestWidgetToken(IWidgetTokenOwner owner) {
+        hideInformationControl();
+        if (DEBUG)
+            System.out_.println("StickyHoverManager gave up widget token (no prio)"); //$NON-NLS-1$
+        return true;
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeperExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner, int)
+     */
+    public bool requestWidgetToken(IWidgetTokenOwner owner, int priority) {
+        if (getCurrentInformationControl2() !is null) {
+            if (getCurrentInformationControl2().isFocusControl()) {
+                if (DEBUG)
+                    System.out_.println("StickyHoverManager kept widget token (focused)"); //$NON-NLS-1$
+                return false;
+            } else if (priority > WIDGET_PRIORITY) {
+                hideInformationControl();
+                if (DEBUG)
+                    System.out_.println("StickyHoverManager gave up widget token (prio)"); //$NON-NLS-1$
+                return true;
+            } else {
+                if (DEBUG)
+                    System.out_.println("StickyHoverManager kept widget token (prio)"); //$NON-NLS-1$
+                return false;
+            }
+        }
+        if (DEBUG)
+            System.out_.println("StickyHoverManager gave up widget token (no iControl)"); //$NON-NLS-1$
+        return true;
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeperExtension#setFocus(dwtx.jface.text.IWidgetTokenOwner)
+     */
+    public bool setFocus(IWidgetTokenOwner owner) {
+        IInformationControl iControl= getCurrentInformationControl2();
+        if ( cast(IInformationControlExtension5)iControl ) {
+            IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) iControl;
+            if (iControl5.isVisible()) {
+                iControl.setFocus();
+                return iControl.isFocusControl();
+            }
+            return false;
+        }
+        iControl.setFocus();
+        return iControl.isFocusControl();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/TableOwnerDrawSupport.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.TableOwnerDrawSupport;
+
+import dwtx.jface.internal.text.NonDeletingPositionUpdater; // packageimport
+import dwtx.jface.internal.text.InternalAccessor; // packageimport
+import dwtx.jface.internal.text.StickyHoverManager; // packageimport
+import dwtx.jface.internal.text.InformationControlReplacer; // packageimport
+import dwtx.jface.internal.text.DelayedInputChangeListener; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.DWT;
+import dwt.custom.StyleRange;
+import dwt.graphics.Color;
+import dwt.graphics.GC;
+import dwt.graphics.Image;
+import dwt.graphics.Rectangle;
+import dwt.graphics.TextLayout;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwt.widgets.Table;
+import dwt.widgets.TableItem;
+
+
+/**
+ * Adds owner draw support for tables.
+ *
+ * @since 3.4
+ */
+public class TableOwnerDrawSupport : Listener {
+
+    private static const String STYLED_RANGES_KEY= "styled_ranges"; //$NON-NLS-1$
+
+    private TextLayout fLayout;
+
+    public static void install(Table table) {
+        TableOwnerDrawSupport listener= new TableOwnerDrawSupport(table);
+        table.addListener(DWT.Dispose, listener);
+        table.addListener(DWT.MeasureItem, listener);
+        table.addListener(DWT.EraseItem, listener);
+        table.addListener(DWT.PaintItem, listener);
+    }
+
+    /**
+     * Stores the styled ranges in the given table item.
+     *
+     * @param item table item
+     * @param column the column index
+     * @param ranges the styled ranges or <code>null</code> to remove them
+     */
+    public static void storeStyleRanges(TableItem item, int column, StyleRange[] ranges) {
+        item.setData(STYLED_RANGES_KEY ~ Integer.toString(column), new ArrayWrapperObject(arraycast!(Object)(ranges)));
+    }
+
+    /**
+     * Returns the styled ranges which are stored in the given table item.
+     *
+     * @param item table item
+     * @param column the column index
+     * @return the styled ranges
+     */
+    private static StyleRange[] getStyledRanges(TableItem item, int column) {
+        return arrayFromObject!(StyleRange)(item.getData(STYLED_RANGES_KEY ~ Integer.toString(column)));
+    }
+
+    private this(Table table) {
+        int orientation= table.getStyle() & (DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT);
+        fLayout= new TextLayout(table.getDisplay());
+        fLayout.setOrientation(orientation);
+    }
+
+    /*
+     * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event)
+     */
+    public void handleEvent(Event event) {
+        switch (event.type) {
+            case DWT.MeasureItem:
+                break;
+            case DWT.EraseItem:
+                event.detail &= ~DWT.FOREGROUND;
+                break;
+            case DWT.PaintItem:
+                performPaint(event);
+                break;
+            case DWT.Dispose:
+                widgetDisposed();
+                break;
+            }
+    }
+
+    /**
+     * Performs the paint operation.
+     *
+     * @param event the event
+     */
+    private void performPaint(Event event) {
+        TableItem item= cast(TableItem) event.item;
+        GC gc= event.gc;
+        int index= event.index;
+
+        bool isSelected= (event.detail & DWT.SELECTED) !is 0;
+
+        // Remember colors to restore the GC later
+        Color oldForeground= gc.getForeground();
+        Color oldBackground= gc.getBackground();
+
+        if (!isSelected) {
+            Color foreground= item.getForeground(index);
+            gc.setForeground(foreground);
+
+            Color background= item.getBackground(index);
+            gc.setBackground(background);
+        }
+
+        Image image=item.getImage(index);
+        if (image !is null) {
+            Rectangle imageBounds=item.getImageBounds(index);
+            Rectangle bounds=image.getBounds();
+            int x=imageBounds.x + Math.max(0, (imageBounds.width - bounds.width) / 2);
+            int y=imageBounds.y + Math.max(0, (imageBounds.height - bounds.height) / 2);
+            gc.drawImage(image, x, y);
+        }
+
+        fLayout.setFont(item.getFont(index));
+
+        // XXX: needed to clear the style info, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=226090
+        fLayout.setText(""); //$NON-NLS-1$
+
+        fLayout.setText(item.getText(index));
+
+        StyleRange[] ranges= getStyledRanges(item, index);
+        if (ranges !is null) {
+            for (int i= 0; i < ranges.length; i++) {
+                StyleRange curr= ranges[i];
+                if (isSelected) {
+                    curr= cast(StyleRange) curr.clone();
+                    curr.foreground= null;
+                    curr.background= null;
+                }
+                fLayout.setStyle(curr, curr.start, curr.start + curr.length - 1);
+            }
+        }
+
+        Rectangle textBounds=item.getTextBounds(index);
+        if (textBounds !is null) {
+            Rectangle layoutBounds=fLayout.getBounds();
+            int x=textBounds.x;
+            int y=textBounds.y + Math.max(0, (textBounds.height - layoutBounds.height) / 2);
+            fLayout.draw(gc, x, y);
+        }
+
+        if ((event.detail & DWT.FOCUSED) !is 0) {
+            Rectangle focusBounds=item.getBounds();
+            gc.drawFocus(focusBounds.x, focusBounds.y, focusBounds.width, focusBounds.height);
+        }
+
+        if (!isSelected) {
+            gc.setForeground(oldForeground);
+            gc.setBackground(oldBackground);
+        }
+    }
+
+    private void widgetDisposed() {
+        fLayout.dispose();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/html/BrowserInformationControl.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,663 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.html.BrowserInformationControl;
+
+import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport
+import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInput; // packageimport
+import dwtx.jface.internal.text.html.SingleCharReader; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport
+import dwtx.jface.internal.text.html.HTMLMessages; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwt.widgets.Shell;
+import dwt.widgets.Composite;
+import dwtx.jface.text.AbstractInformationControl;
+import dwtx.jface.text.IInformationControlExtension2;
+import dwtx.jface.text.IDelayedInputChangeProvider;
+import dwtx.jface.text.IInputChangedListener;
+
+pragma( msg, "dwtx.jface.internal.text.html.BrowserInformationControl: SWT browser control missing" );
+class BrowserInformationControl : AbstractInformationControl , IInformationControlExtension2, IDelayedInputChangeProvider {
+    public this(Shell parent, String symbolicFontName, bool resizable){}
+    public static bool isAvailable(Composite parent){}
+    public void setInformation(String content) {}
+    protected void createContent(Composite parent) {
+    }
+    public void setInput(Object input) {}
+    public void setDelayedInputChangeListener(IInputChangedListener inputChangeListener) {}
+    public bool hasContents() {
+        return false;
+    }
+}
+
+// FIXME needs Browser :/
+/++
+
+import dwtx.dwtxhelper.StringReader;
+import dwtx.dwtxhelper.Collection;
+
+import dwt.DWT;
+import dwt.DWTError;
+import dwt.browser.Browser;
+import dwt.browser.LocationListener;
+import dwt.browser.ProgressAdapter;
+import dwt.browser.ProgressEvent;
+import dwt.custom.StyleRange;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.graphics.Color;
+import dwt.graphics.Font;
+import dwt.graphics.FontData;
+import dwt.graphics.GC;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.graphics.TextLayout;
+import dwt.graphics.TextStyle;
+import dwt.widgets.Composite;
+import dwt.widgets.Display;
+import dwt.widgets.Menu;
+import dwt.widgets.Shell;
+import dwt.widgets.Slider;
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.ListenerList;
+import dwtx.jface.action.ToolBarManager;
+import dwtx.jface.resource.JFaceResources;
+import dwtx.jface.text.AbstractInformationControl;
+import dwtx.jface.text.IDelayedInputChangeProvider;
+import dwtx.jface.text.IInformationControlExtension2;
+import dwtx.jface.text.IInputChangedListener;
+import dwtx.jface.text.TextPresentation;
+
+
+/**
+ * Displays HTML information in a {@link dwt.browser.Browser} widget.
+ * <p>
+ * This {@link IInformationControlExtension2} expects {@link #setInput(Object)} to be
+ * called with an argument of type {@link BrowserInformationControlInput}.
+ * </p>
+ * <p>
+ * Moved into this package from <code>dwtx.jface.internal.text.revisions</code>.</p>
+ * <p>
+ * This class may be instantiated; it is not intended to be subclassed.</p>
+ * <p>
+ * Current problems:
+ * <ul>
+ *  <li>the size computation is too small</li>
+ *  <li>focusLost event is not sent - see https://bugs.eclipse.org/bugs/show_bug.cgi?id=84532</li>
+ * </ul>
+ * </p>
+ *
+ * @since 3.2
+ */
+public class BrowserInformationControl : AbstractInformationControl , IInformationControlExtension2, IDelayedInputChangeProvider {
+
+
+    /**
+     * Tells whether the DWT Browser widget and hence this information
+     * control is available.
+     *
+     * @param parent the parent component used for checking or <code>null</code> if none
+     * @return <code>true</code> if this control is available
+     */
+    public static bool isAvailable(Composite parent) {
+        if (!fgAvailabilityChecked) {
+            try {
+                Browser browser= new Browser(parent, DWT.NONE);
+                browser.dispose();
+                fgIsAvailable= true;
+
+                Slider sliderV= new Slider(parent, DWT.VERTICAL);
+                Slider sliderH= new Slider(parent, DWT.HORIZONTAL);
+                int width= sliderV.computeSize(DWT.DEFAULT, DWT.DEFAULT).x;
+                int height= sliderH.computeSize(DWT.DEFAULT, DWT.DEFAULT).y;
+                fgScrollBarSize= new Point(width, height);
+                sliderV.dispose();
+                sliderH.dispose();
+            } catch (DWTError er) {
+                fgIsAvailable= false;
+            } finally {
+                fgAvailabilityChecked= true;
+            }
+        }
+
+        return fgIsAvailable;
+    }
+
+
+    /**
+     * Minimal size constraints.
+     * @since 3.2
+     */
+    private static const int MIN_WIDTH= 80;
+    private static const int MIN_HEIGHT= 50;
+
+
+    /**
+     * Availability checking cache.
+     */
+    private static bool fgIsAvailable= false;
+    private static bool fgAvailabilityChecked= false;
+
+    /**
+     * Cached scroll bar width and height
+     * @since 3.4
+     */
+    private static Point fgScrollBarSize;
+
+    /** The control's browser widget */
+    private Browser fBrowser;
+    /** Tells whether the browser has content */
+    private bool fBrowserHasContent;
+    /** Text layout used to approximate size of content when rendered in browser */
+    private TextLayout fTextLayout;
+    /** Bold text style */
+    private TextStyle fBoldStyle;
+
+    private BrowserInformationControlInput fInput;
+
+    /**
+     * <code>true</code> iff the browser has completed loading of the last
+     * input set via {@link #setInformation(String)}.
+     * @since 3.4
+     */
+    private bool fCompleted= false;
+
+    /**
+     * The listener to be notified when a delayed location changing event happened.
+     * @since 3.4
+     */
+    private IInputChangedListener fDelayedInputChangeListener;
+
+    /**
+     * The listeners to be notified when the input changed.
+     * @since 3.4
+     */
+    private ListenerList/*<IInputChangedListener>*/ fInputChangeListeners= new ListenerList(ListenerList.IDENTITY);
+
+    /**
+     * The symbolic name of the font used for size computations, or <code>null</code> to use dialog font.
+     * @since 3.4
+     */
+    private const String fSymbolicFontName;
+
+
+    /**
+     * Creates a browser information control with the given shell as parent.
+     *
+     * @param parent the parent shell
+     * @param symbolicFontName the symbolic name of the font used for size computations
+     * @param resizable <code>true</code> if the control should be resizable
+     * @since 3.4
+     */
+    public this(Shell parent, String symbolicFontName, bool resizable) {
+        super(parent, resizable);
+        fSymbolicFontName= symbolicFontName;
+        create();
+    }
+
+    /**
+     * Creates a browser information control with the given shell as parent.
+     *
+     * @param parent the parent shell
+     * @param symbolicFontName the symbolic name of the font used for size computations
+     * @param statusFieldText the text to be used in the optional status field
+     *            or <code>null</code> if the status field should be hidden
+     * @since 3.4
+     */
+    public this(Shell parent, String symbolicFontName, String statusFieldText) {
+        super(parent, statusFieldText);
+        fSymbolicFontName= symbolicFontName;
+        create();
+    }
+
+    /**
+     * Creates a browser information control with the given shell as parent.
+     *
+     * @param parent the parent shell
+     * @param symbolicFontName the symbolic name of the font used for size computations
+     * @param toolBarManager the manager or <code>null</code> if toolbar is not desired
+     * @since 3.4
+     */
+    public this(Shell parent, String symbolicFontName, ToolBarManager toolBarManager) {
+        super(parent, toolBarManager);
+        fSymbolicFontName= symbolicFontName;
+        create();
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControl#createContent(dwt.widgets.Composite)
+     */
+    protected void createContent(Composite parent) {
+        fBrowser= new Browser(parent, DWT.NONE);
+
+        Display display= getShell().getDisplay();
+        fBrowser.setForeground(display.getSystemColor(DWT.COLOR_INFO_FOREGROUND));
+        fBrowser.setBackground(display.getSystemColor(DWT.COLOR_INFO_BACKGROUND));
+        fBrowser.addKeyListener(new class()  KeyListener {
+
+            public void keyPressed(KeyEvent e)  {
+                if (e.character is 0x1B) // ESC
+                    getShell().dispose(); // XXX: Just hide? Would avoid constant recreations.
+            }
+
+            public void keyReleased(KeyEvent e) {}
+        });
+
+        fBrowser.addProgressListener(new class()  ProgressAdapter {
+            public void completed(ProgressEvent event) {
+                fCompleted= true;
+            }
+        });
+
+        // Replace browser's built-in context menu with none
+        fBrowser.setMenu(new Menu(getShell(), DWT.NONE));
+
+        createTextLayout();
+    }
+
+    /**
+     * {@inheritDoc}
+     * @deprecated use {@link #setInput(Object)}
+     */
+    public void setInformation(String content) {
+        setInput(new class(null,content)  BrowserInformationControlInput {
+            String content_;
+            this(BrowserInformationControlInput input, String a){
+                super(input);
+                content_=a;
+            }
+            public String getHtml() {
+                return content_;
+            }
+
+            public String getInputName() {
+                return ""; //$NON-NLS-1$
+            }
+
+            public Object getInputElement() {
+                return stringcast(content_);
+            }
+        });
+    }
+
+    /**
+     * {@inheritDoc} This control can handle {@link String} and
+     * {@link BrowserInformationControlInput}.
+     */
+    public void setInput(Object input) {
+        Assert.isLegal(input is null || cast(String)input  || cast(BrowserInformationControlInput)input );
+
+        if ( cast(String)input ) {
+            setInformation(cast(String)input);
+            return;
+        }
+
+        fInput= cast(BrowserInformationControlInput)input;
+
+        String content= null;
+        if (fInput !is null)
+            content= fInput.getHtml();
+
+        fBrowserHasContent= content !is null && content.length() > 0;
+
+        if (!fBrowserHasContent)
+            content= "<html><body ></html>"; //$NON-NLS-1$
+
+        bool RTL= (getShell().getStyle() & DWT.RIGHT_TO_LEFT) !is 0;
+        bool resizable= isResizable();
+
+        // The default "overflow:auto" would not result in a predictable width for the client area
+        // and the re-wrapping would cause visual noise
+        String[] styles= null;
+        if (RTL && resizable)
+            styles= [ "direction:rtl;", "overflow:scroll;", "word-wrap:break-word;" ]; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        else if (RTL && !resizable)
+            styles= [ "direction:rtl;", "overflow:hidden;", "word-wrap:break-word;" ]; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        else if (!resizable)
+            //XXX: In IE, "word-wrap: break-word;" causes bogus wrapping even in non-broken words :-(see e.g. Javadoc of String).
+            // Re-check whether we really still need this now that the Javadoc Hover header already sets this style.
+            styles= [ "overflow:hidden;"/*, "word-wrap: break-word;"*/ ]; //$NON-NLS-1$
+        else
+            styles= [ "overflow:scroll;" ]; //$NON-NLS-1$
+
+        StringBuffer buffer= new StringBuffer(content);
+        HTMLPrinter.insertStyles(buffer, styles);
+        content= buffer.toString();
+
+        /*
+         * XXX: Should add some JavaScript here that shows something like
+         * "(continued...)" or "..." at the end of the visible area when the page overflowed
+         * with "overflow:hidden;".
+         */
+
+        fCompleted= false;
+        fBrowser.setText(content);
+
+        Object[] listeners= fInputChangeListeners.getListeners();
+        for (int i= 0; i < listeners.length; i++)
+            (cast(IInputChangedListener)listeners[i]).inputChanged(fInput);
+    }
+
+    /*
+     * @see IInformationControl#setVisible(bool)
+     */
+    public void setVisible(bool visible) {
+        Shell shell= getShell();
+        if (shell.isVisible() is visible)
+            return;
+
+        if (!visible) {
+            super.setVisible(false);
+            setInput(null);
+            return;
+        }
+
+        /*
+         * The Browser widget flickers when made visible while it is not completely loaded.
+         * The fix is to delay the call to setVisible until either loading is completed
+         * (see ProgressListener in constructor), or a timeout has been reached.
+         */
+        final Display display= shell.getDisplay();
+
+        // Make sure the display wakes from sleep after timeout:
+        display.timerExec(100, new class()  Runnable {
+            public void run() {
+                fCompleted= true;
+            }
+        });
+
+        while (!fCompleted) {
+            // Drive the event loop to process the events required to load the browser widget's contents:
+            if (!display.readAndDispatch()) {
+                display.sleep();
+            }
+        }
+
+        shell= getShell();
+        if (shell is null || shell.isDisposed())
+            return;
+
+        /*
+         * Avoids flickering when replacing hovers, especially on Vista in ON_CLICK mode.
+         * Causes flickering on GTK. Carbon does not care.
+         */
+        if ("win32".equals(DWT.getPlatform())) //$NON-NLS-1$
+            shell.moveAbove(null);
+
+        super.setVisible(true);
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControl#setSize(int, int)
+     */
+    public void setSize(int width, int height) {
+        fBrowser.setRedraw(false); // avoid flickering
+        try {
+            super.setSize(width, height);
+        } finally {
+            fBrowser.setRedraw(true);
+        }
+    }
+
+    /**
+     * Creates and initializes the text layout used
+     * to compute the size hint.
+     *
+     * @since 3.2
+     */
+    private void createTextLayout() {
+        fTextLayout= new TextLayout(fBrowser.getDisplay());
+
+        // Initialize fonts
+        Font font= fSymbolicFontName is null ? JFaceResources.getDialogFont() : JFaceResources.getFont(fSymbolicFontName);
+        fTextLayout.setFont(font);
+        fTextLayout.setWidth(-1);
+        FontData[] fontData= font.getFontData();
+        for (int i= 0; i < fontData.length; i++)
+            fontData[i].setStyle(DWT.BOLD);
+        font= new Font(getShell().getDisplay(), fontData);
+        fBoldStyle= new TextStyle(font, null, null);
+
+        // Compute and set tab width
+        fTextLayout.setText("    "); //$NON-NLS-1$
+        int tabWidth = fTextLayout.getBounds().width;
+        fTextLayout.setTabs([tabWidth]);
+
+        fTextLayout.setText(""); //$NON-NLS-1$
+    }
+
+    /*
+     * @see IInformationControl#dispose()
+     */
+    public void dispose() {
+        if (fTextLayout !is null) {
+            fTextLayout.dispose();
+            fTextLayout= null;
+        }
+        if (fBoldStyle !is null) {
+            fBoldStyle.font.dispose();
+            fBoldStyle= null;
+        }
+        fBrowser= null;
+
+        super.dispose();
+    }
+
+    /*
+     * @see IInformationControl#computeSizeHint()
+     */
+    public Point computeSizeHint() {
+        Point sizeConstraints= getSizeConstraints();
+        Rectangle trim= computeTrim();
+        int height= trim.height;
+
+        //FIXME: The HTML2TextReader does not render <p> like a browser.
+        // Instead of inserting an empty line, it just adds a single line break.
+        // Furthermore, the indentation of <dl><dd> elements is too small (e.g with a long @see line)
+        TextPresentation presentation= new TextPresentation();
+        HTML2TextReader reader= new HTML2TextReader(new StringReader(fInput.getHtml()), presentation);
+        String text;
+        try {
+            text= reader.getString();
+        } catch (IOException e) {
+            text= ""; //$NON-NLS-1$
+        }
+
+        fTextLayout.setText(text);
+        fTextLayout.setWidth(sizeConstraints is null ? DWT.DEFAULT : sizeConstraints.x - trim.width);
+        Iterator iter= presentation.getAllStyleRangeIterator();
+        while (iter.hasNext()) {
+            StyleRange sr= cast(StyleRange)iter.next();
+            if (sr.fontStyle is DWT.BOLD)
+                fTextLayout.setStyle(fBoldStyle, sr.start, sr.start + sr.length - 1);
+        }
+
+        Rectangle bounds= fTextLayout.getBounds(); // does not return minimum width, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=217446
+        int lineCount= fTextLayout.getLineCount();
+        int textWidth= 0;
+        for (int i= 0; i < lineCount; i++) {
+            Rectangle rect= fTextLayout.getLineBounds(i);
+            int lineWidth= rect.x + rect.width;
+            if (i is 0)
+                lineWidth += fInput.getLeadingImageWidth();
+            textWidth= Math.max(textWidth, lineWidth);
+        }
+        bounds.width= textWidth;
+        fTextLayout.setText(""); //$NON-NLS-1$
+
+        int minWidth= bounds.width;
+        height= height + bounds.height;
+
+        // Add some air to accommodate for different browser renderings
+        minWidth+= 15;
+        height+= 15;
+
+
+        // Apply max size constraints
+        if (sizeConstraints !is null) {
+            if (sizeConstraints.x !is DWT.DEFAULT)
+                minWidth= Math.min(sizeConstraints.x, minWidth + trim.width);
+            if (sizeConstraints.y !is DWT.DEFAULT)
+                height= Math.min(sizeConstraints.y, height);
+        }
+
+        // Ensure minimal size
+        int width= Math.max(MIN_WIDTH, minWidth);
+        height= Math.max(MIN_HEIGHT, height);
+
+        return new Point(width, height);
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension3#computeTrim()
+     */
+    public Rectangle computeTrim() {
+        Rectangle trim= super.computeTrim();
+        if (isResizable()) {
+            bool RTL= (getShell().getStyle() & DWT.RIGHT_TO_LEFT) !is 0;
+            if (RTL) {
+                trim.x-= fgScrollBarSize.x;
+            }
+            trim.width+= fgScrollBarSize.x;
+            trim.height+= fgScrollBarSize.y;
+        }
+        return trim;
+    }
+
+    /**
+     * Adds the listener to the collection of listeners who will be
+     * notified when the current location has changed or is about to change.
+     *
+     * @param listener the location listener
+     * @since 3.4
+     */
+    public void addLocationListener(LocationListener listener) {
+        fBrowser.addLocationListener(listener);
+    }
+
+    /*
+     * @see IInformationControl#setForegroundColor(Color)
+     */
+    public void setForegroundColor(Color foreground) {
+        super.setForegroundColor(foreground);
+        fBrowser.setForeground(foreground);
+    }
+
+    /*
+     * @see IInformationControl#setBackgroundColor(Color)
+     */
+    public void setBackgroundColor(Color background) {
+        super.setBackgroundColor(background);
+        fBrowser.setBackground(background);
+    }
+
+    /*
+     * @see IInformationControlExtension#hasContents()
+     */
+    public bool hasContents() {
+        return fBrowserHasContent;
+    }
+
+    /**
+     * Adds a listener for input changes to this input change provider.
+     * Has no effect if an identical listener is already registered.
+     *
+     * @param inputChangeListener the listener to add
+     * @since 3.4
+     */
+    public void addInputChangeListener(IInputChangedListener inputChangeListener) {
+        Assert.isNotNull(inputChangeListener);
+        fInputChangeListeners.add(inputChangeListener);
+    }
+
+    /**
+     * Removes the given input change listener from this input change provider.
+     * Has no effect if an identical listener is not registered.
+     *
+     * @param inputChangeListener the listener to remove
+     * @since 3.4
+     */
+    public void removeInputChangeListener(IInputChangedListener inputChangeListener) {
+        fInputChangeListeners.remove(inputChangeListener);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDelayedInputChangeProvider#setDelayedInputChangeListener(dwtx.jface.text.IInputChangedListener)
+     * @since 3.4
+     */
+    public void setDelayedInputChangeListener(IInputChangedListener inputChangeListener) {
+        fDelayedInputChangeListener= inputChangeListener;
+    }
+
+    /**
+     * Tells whether a delayed input change listener is registered.
+     *
+     * @return <code>true</code> iff a delayed input change
+     *         listener is currently registered
+     * @since 3.4
+     */
+    public bool hasDelayedInputChangeListener() {
+        return fDelayedInputChangeListener !is null;
+    }
+
+    /**
+     * Notifies listeners of a delayed input change.
+     *
+     * @param newInput the new input, or <code>null</code> to request cancellation
+     * @since 3.4
+     */
+    public void notifyDelayedInputChange(Object newInput) {
+        if (fDelayedInputChangeListener !is null)
+            fDelayedInputChangeListener.inputChanged(newInput);
+    }
+
+    /*
+     * @see java.lang.Object#toString()
+     * @since 3.4
+     */
+    public override String toString() {
+        String style= (getShell().getStyle() & DWT.RESIZE) is 0 ? "fixed" : "resizeable"; //$NON-NLS-1$ //$NON-NLS-2$
+        return super.toString() + " -  style: " + style; //$NON-NLS-1$
+    }
+
+    /**
+     * @return the current browser input or <code>null</code>
+     */
+    public BrowserInformationControlInput getInput() {
+        return fInput;
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension5#computeSizeConstraints(int, int)
+     */
+    public Point computeSizeConstraints(int widthInChars, int heightInChars) {
+        if (fSymbolicFontName is null)
+            return null;
+
+        GC gc= new GC(fBrowser);
+        Font font= fSymbolicFontName is null ? JFaceResources.getDialogFont() : JFaceResources.getFont(fSymbolicFontName);
+        gc.setFont(font);
+        int width= gc.getFontMetrics().getAverageCharWidth();
+        int height= gc.getFontMetrics().getHeight();
+        gc.dispose();
+
+        return new Point(widthInChars * width, heightInChars * height);
+    }
+
+}
+
+++/
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/html/BrowserInformationControlInput.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.html.BrowserInformationControlInput;
+
+import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport
+import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInput; // packageimport
+import dwtx.jface.internal.text.html.SingleCharReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.DefaultInformationControl;
+
+
+/**
+ * Provides input for a {@link BrowserInformationControl}.
+ *
+ * @since 3.4
+ */
+public abstract class BrowserInformationControlInput : BrowserInput {
+    
+    /**
+     * Returns the leading image width.
+     * 
+     * @return the size of the leading image, by default <code>0</code> is returned
+     * @since 3.4
+     */
+    public int getLeadingImageWidth() {
+        return 0;
+    }
+
+    /**
+     * Creates the next browser input with the given input as previous one.
+     * 
+     * @param previous the previous input or <code>null</code> if none
+     */
+    public this(BrowserInformationControlInput previous) {
+        super(previous);
+    }
+
+    /**
+     * @return the HTML contents
+     */
+    public abstract String getHtml();
+    
+    /**
+     * Returns the HTML from {@link #getHtml()}.
+     * This is a fallback mode for platforms where the {@link BrowserInformationControl}
+     * is not available and this input is passed to a {@link DefaultInformationControl}.
+     * 
+     * @return {@link #getHtml()}
+     */
+    public override String toString() {
+        return getHtml();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/html/BrowserInput.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.html.BrowserInput;
+
+import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport
+import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport
+import dwtx.jface.internal.text.html.SingleCharReader; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport
+import dwtx.jface.internal.text.html.HTMLMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A browser input contains an input element and
+ * a previous and a next input, if available.
+ * 
+ * The browser input also provides a human readable
+ * name of its input element.
+ * 
+ * @since 3.4
+ */
+public abstract class BrowserInput {
+
+    private const BrowserInput fPrevious;
+    private BrowserInput fNext;
+
+    /**
+     * Create a new Browser input.
+     * 
+     * @param previous the input previous to this or <code>null</code> if this is the first
+     */
+    public this(BrowserInput previous) {
+        fPrevious= previous;
+        if (previous !is null)
+            previous.fNext= this;
+    }
+
+    /**
+     * The previous input or <code>null</code> if this
+     * is the first.
+     * 
+     * @return the previous input or <code>null</code>
+     */
+    public BrowserInput getPrevious() {
+        return fPrevious;
+    }
+
+    /**
+     * The next input or <code>null</code> if this
+     * is the last.
+     * 
+     * @return the next input or <code>null</code>
+     */
+    public BrowserInput getNext() {
+        return fNext;
+    }
+
+    /**
+     * The element to use to set the browsers input.
+     * 
+     * @return the input element
+     */
+    public abstract Object getInputElement();
+
+    /**
+     * A human readable name for the input.
+     * 
+     * @return the input name
+     */
+    public abstract String getInputName();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/html/HTML2TextReader.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,344 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.html.HTML2TextReader;
+
+import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport
+import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInput; // packageimport
+import dwtx.jface.internal.text.html.SingleCharReader; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport
+import dwtx.jface.internal.text.html.HTMLMessages; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.PushbackReader;
+import dwtx.dwtxhelper.Collection;
+static import tango.text.convert.Utf;
+
+import dwt.DWT;
+import dwt.custom.StyleRange;
+import dwtx.jface.text.TextPresentation;
+
+
+/**
+ * Reads the text contents from a reader of HTML contents and translates
+ * the tags or cut them out.
+ * <p>
+ * Moved into this package from <code>dwtx.jface.internal.text.revisions</code>.</p>
+ */
+public class HTML2TextReader : SubstitutionTextReader {
+
+    private static const String EMPTY_STRING= ""; //$NON-NLS-1$
+    private static const Map fgEntityLookup;
+    private static const Set fgTags;
+
+    static this() {
+
+        fgTags= new HashSet();
+        fgTags.add("b"); //$NON-NLS-1$
+        fgTags.add("br"); //$NON-NLS-1$
+        fgTags.add("br/"); //$NON-NLS-1$
+        fgTags.add("div"); //$NON-NLS-1$
+        fgTags.add("h1"); //$NON-NLS-1$
+        fgTags.add("h2"); //$NON-NLS-1$
+        fgTags.add("h3"); //$NON-NLS-1$
+        fgTags.add("h4"); //$NON-NLS-1$
+        fgTags.add("h5"); //$NON-NLS-1$
+        fgTags.add("p"); //$NON-NLS-1$
+        fgTags.add("dl"); //$NON-NLS-1$
+        fgTags.add("dt"); //$NON-NLS-1$
+        fgTags.add("dd"); //$NON-NLS-1$
+        fgTags.add("li"); //$NON-NLS-1$
+        fgTags.add("ul"); //$NON-NLS-1$
+        fgTags.add("pre"); //$NON-NLS-1$
+        fgTags.add("head"); //$NON-NLS-1$
+
+        fgEntityLookup= new HashMap(7);
+        fgEntityLookup.put("lt", "<"); //$NON-NLS-1$ //$NON-NLS-2$
+        fgEntityLookup.put("gt", ">"); //$NON-NLS-1$ //$NON-NLS-2$
+        fgEntityLookup.put("nbsp", " "); //$NON-NLS-1$ //$NON-NLS-2$
+        fgEntityLookup.put("amp", "&"); //$NON-NLS-1$ //$NON-NLS-2$
+        fgEntityLookup.put("circ", "^"); //$NON-NLS-1$ //$NON-NLS-2$
+        fgEntityLookup.put("tilde", "~"); //$NON-NLS-2$ //$NON-NLS-1$
+        fgEntityLookup.put("quot", "\"");        //$NON-NLS-1$ //$NON-NLS-2$
+    }
+
+    private int fCounter= 0;
+    private TextPresentation fTextPresentation;
+    private int fBold= 0;
+    private int fStartOffset= -1;
+    private bool fInParagraph= false;
+    private bool fIsPreformattedText= false;
+    private bool fIgnore= false;
+    private bool fHeaderDetected= false;
+
+    /**
+     * Transforms the HTML text from the reader to formatted text.
+     *
+     * @param reader the reader
+     * @param presentation If not <code>null</code>, formattings will be applied to
+     * the presentation.
+    */
+    public this(Reader reader, TextPresentation presentation) {
+        super(new PushbackReader(reader));
+        fTextPresentation= presentation;
+    }
+
+    public int read()  {
+        int c= super.read();
+        if (c !is -1)
+            ++ fCounter;
+        return c;
+    }
+
+    protected void startBold() {
+        if (fBold is 0)
+            fStartOffset= fCounter;
+        ++ fBold;
+    }
+
+    protected void startPreformattedText() {
+        fIsPreformattedText= true;
+        setSkipWhitespace(false);
+    }
+
+    protected void stopPreformattedText() {
+        fIsPreformattedText= false;
+        setSkipWhitespace(true);
+    }
+
+    protected void stopBold() {
+        -- fBold;
+        if (fBold is 0) {
+            if (fTextPresentation !is null) {
+                fTextPresentation.addStyleRange(new StyleRange(fStartOffset, fCounter - fStartOffset, null, null, DWT.BOLD));
+            }
+            fStartOffset= -1;
+        }
+    }
+
+    /*
+     * @see dwtx.jdt.internal.ui.text.SubstitutionTextReader#computeSubstitution(int)
+     */
+    protected String computeSubstitution(int c)  {
+
+        if (c is '<')
+            return  processHTMLTag();
+        else if (fIgnore)
+            return EMPTY_STRING;
+        else if (c is '&')
+            return processEntity();
+        else if (fIsPreformattedText)
+            return processPreformattedText(c);
+
+        return null;
+    }
+
+    private String html2Text(String html) {
+
+        if (html is null || html.length() is 0)
+            return EMPTY_STRING;
+
+        html= html.toLowerCase();
+
+        String tag= html;
+        if ('/' is tag.charAt(0))
+            tag= tag.substring(1);
+
+        if (!fgTags.contains(tag))
+            return EMPTY_STRING;
+
+
+        if ("pre".equals(html)) { //$NON-NLS-1$
+            startPreformattedText();
+            return EMPTY_STRING;
+        }
+
+        if ("/pre".equals(html)) { //$NON-NLS-1$
+            stopPreformattedText();
+            return EMPTY_STRING;
+        }
+
+        if (fIsPreformattedText)
+            return EMPTY_STRING;
+
+        if ("b".equals(html)) { //$NON-NLS-1$
+            startBold();
+            return EMPTY_STRING;
+        }
+
+        if ((html.length() > 1 && html.charAt(0) is 'h' && Character.isDigit(html.charAt(1))) || "dt".equals(html)) { //$NON-NLS-1$
+            startBold();
+            return EMPTY_STRING;
+        }
+
+        if ("dl".equals(html)) //$NON-NLS-1$
+            return LINE_DELIM;
+
+        if ("dd".equals(html)) //$NON-NLS-1$
+            return "\t"; //$NON-NLS-1$
+
+        if ("li".equals(html)) //$NON-NLS-1$
+            // FIXME: this hard-coded prefix does not work for RTL languages, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=91682
+            return LINE_DELIM ~ HTMLMessages.getString("HTML2TextReader.listItemPrefix"); //$NON-NLS-1$
+
+        if ("/b".equals(html)) { //$NON-NLS-1$
+            stopBold();
+            return EMPTY_STRING;
+        }
+
+        if ("p".equals(html))  { //$NON-NLS-1$
+            fInParagraph= true;
+            return LINE_DELIM;
+        }
+
+        if ("br".equals(html) || "br/".equals(html) || "div".equals(html)) //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            return LINE_DELIM;
+
+        if ("/p".equals(html))  { //$NON-NLS-1$
+            bool inParagraph= fInParagraph;
+            fInParagraph= false;
+            return inParagraph ? EMPTY_STRING : LINE_DELIM;
+        }
+
+        if ((html.startsWith("/h") && html.length() > 2 && Character.isDigit(html.charAt(2))) || "/dt".equals(html)) { //$NON-NLS-1$ //$NON-NLS-2$
+            stopBold();
+            return LINE_DELIM;
+        }
+
+        if ("/dd".equals(html)) //$NON-NLS-1$
+            return LINE_DELIM;
+
+        if ("head".equals(html) && !fHeaderDetected) { //$NON-NLS-1$
+            fHeaderDetected= true;
+            fIgnore= true;
+            return EMPTY_STRING;
+        }
+
+        if ("/head".equals(html) && fHeaderDetected && fIgnore) { //$NON-NLS-1$
+            fIgnore= false;
+            return EMPTY_STRING;
+        }
+
+        return EMPTY_STRING;
+    }
+
+    /*
+     * A '<' has been read. Process a html tag
+     */
+    private String processHTMLTag()  {
+
+        StringBuffer buf= new StringBuffer();
+        int ch;
+        do {
+
+            ch= nextDChar();
+
+            while (ch !is -1 && ch !is '>') {
+                buf.append(dcharToString(Character.toLowerCase(cast(dchar) ch)));
+                ch= nextDChar();
+                if (ch is '"'){
+                    buf.append(dcharToString(Character.toLowerCase(cast(dchar) ch)));
+                    ch= nextDChar();
+                    while (ch !is -1 && ch !is '"'){
+                        buf.append(dcharToString(Character.toLowerCase(cast(dchar) ch)));
+                        ch= nextDChar();
+                    }
+                }
+                if (ch is '<' && !isInComment(buf)) {
+                    unreadDChar(ch);
+                    return '<' ~ buf.toString();
+                }
+            }
+
+            if (ch is -1)
+                return null;
+
+            if (!isInComment(buf) || isCommentEnd(buf)) {
+                break;
+            }
+            // unfinished comment
+            buf.append(dcharToString(cast(dchar) ch));
+        } while (true);
+
+        return html2Text(buf.toString());
+    }
+
+    private static bool isInComment(StringBuffer buf) {
+        return buf.length() >= 3 && "!--".equals(buf.slice().substring(0, 3)); //$NON-NLS-1$
+    }
+
+    private static bool isCommentEnd(StringBuffer buf) {
+        int tagLen= buf.length();
+        return tagLen >= 5 && "--".equals(buf.slice().substring(tagLen - 2)); //$NON-NLS-1$
+    }
+
+    private String processPreformattedText(int c) {
+        if  (c is '\r' || c is '\n')
+            fCounter++;
+        return null;
+    }
+
+
+    private void unreadDChar(dchar ch)  {
+        char[4] buf;
+        dchar[1] ibuf;
+        ibuf[0] = ch;
+        foreach( char c; tango.text.convert.Utf.toString( ibuf[], buf[] )){
+            (cast(PushbackReader) getReader()).unread(c);
+        }
+    }
+
+    protected String entity2Text(String symbol) {
+        if (symbol.length() > 1 && symbol.charAt(0) is '#') {
+            int ch;
+            try {
+                if (symbol.charAt(1) is 'x') {
+                    ch= Integer.parseInt(symbol.substring(2), 16);
+                } else {
+                    ch= Integer.parseInt(symbol.substring(1), 10);
+                }
+                return dcharToString( cast(dchar)ch);
+            } catch (NumberFormatException e) {
+            }
+        } else {
+            String str= stringcast( fgEntityLookup.get(symbol));
+            if (str !is null) {
+                return str;
+            }
+        }
+        return "&" ~ symbol; // not found //$NON-NLS-1$
+    }
+
+    /*
+     * A '&' has been read. Process a entity
+     */
+    private String processEntity()  {
+        StringBuffer buf= new StringBuffer();
+        int ch= nextDChar();
+        while (Character.isLetterOrDigit(cast(dchar)ch) || ch is '#') {
+            buf.append(dcharToString(cast(dchar) ch));
+            ch= nextDChar();
+        }
+
+        if (ch is ';')
+            return entity2Text(buf.toString());
+
+        buf.select(0, 0);
+        buf.prepend("&");
+        if (ch !is -1)
+            buf.append(dcharToString(cast(dchar) ch));
+        return buf.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/html/HTMLMessages.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.html.HTMLMessages;
+
+import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport
+import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInput; // packageimport
+import dwtx.jface.internal.text.html.SingleCharReader; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.dwthelper.ResourceBundle;
+import dwtx.dwtxhelper.MessageFormat;
+
+
+/**
+ * Helper class to get NLSed messages.
+ *
+ * @since 3.3
+ */
+class HTMLMessages {
+
+//     private static const String RESOURCE_BUNDLE= HTMLMessages.classinfo.getName();
+
+    private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+    static this() {
+        fgResourceBundle = ResourceBundle.getBundle(
+            getImportData!("dwtx.jface.internal.text.html.HTMLMessages.properties"));
+    }
+
+    private this() {
+    }
+
+    /**
+     * Gets a string from the resource bundle.
+     *
+     * @param key the string used to get the bundle value, must not be null
+     * @return the string from the resource bundle
+     */
+    public static String getString(String key) {
+        try {
+            return fgResourceBundle.getString(key);
+        } catch (MissingResourceException e) {
+            return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Gets a string from the resource bundle and formats it with the given arguments.
+     *
+     * @param key the string used to get the bundle value, must not be null
+     * @param args the arguments used to format the string
+     * @return the formatted string
+     */
+    public static String getFormattedString(String key, Object[] args...) {
+        String format= null;
+        try {
+            format= fgResourceBundle.getString(key);
+        } catch (MissingResourceException e) {
+            return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$
+        }
+        return MessageFormat.format(format, args);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/html/HTMLPrinter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,317 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.html.HTMLPrinter;
+
+import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport
+import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInput; // packageimport
+import dwtx.jface.internal.text.html.SingleCharReader; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport
+import dwtx.jface.internal.text.html.HTMLMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.URL;
+
+import dwt.DWT;
+import dwt.DWTError;
+import dwt.graphics.FontData;
+import dwt.graphics.RGB;
+import dwt.widgets.Display;
+
+
+/**
+ * Provides a set of convenience methods for creating HTML pages.
+ * <p>
+ * Moved into this package from <code>dwtx.jface.internal.text.revisions</code>.</p>
+ */
+public class HTMLPrinter {
+
+    private static RGB BG_COLOR_RGB_;
+    private static RGB FG_COLOR_RGB_;
+
+    private static RGB BG_COLOR_RGB(){
+        COLOR_RGB_init();
+        return BG_COLOR_RGB_;
+    }
+    private static RGB FG_COLOR_RGB(){
+        COLOR_RGB_init();
+        return FG_COLOR_RGB_;
+    }
+
+    private static bool COLOR_RGB_init_complete = false;
+    private static void COLOR_RGB_init() {
+        if( COLOR_RGB_init_complete ){
+            return;
+        }
+        COLOR_RGB_init_complete = true;
+        BG_COLOR_RGB_= new RGB(255, 255, 225); // RGB value of info bg color on WindowsXP
+        FG_COLOR_RGB_= new RGB(0, 0, 0); // RGB value of info fg color on WindowsXP
+        Display display= Display.getDefault();
+        if (display !is null && !display.isDisposed()) {
+            try {
+                display.asyncExec( dgRunnable( (Display display_){
+                    BG_COLOR_RGB_= display_.getSystemColor(DWT.COLOR_INFO_BACKGROUND).getRGB();
+                    FG_COLOR_RGB_= display_.getSystemColor(DWT.COLOR_INFO_FOREGROUND).getRGB();
+                }, display ));
+            } catch (DWTError err) {
+                // see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=45294
+                if (err.code !is DWT.ERROR_DEVICE_DISPOSED)
+                    throw err;
+            }
+        }
+    }
+
+    private this() {
+    }
+
+    private static String replace(String text, char c, String s) {
+
+        int previous= 0;
+        int current= text.indexOf(c, previous);
+
+        if (current is -1)
+            return text;
+
+        StringBuffer buffer= new StringBuffer();
+        while (current > -1) {
+            buffer.append(text.substring(previous, current));
+            buffer.append(s);
+            previous= current + 1;
+            current= text.indexOf(c, previous);
+        }
+        buffer.append(text.substring(previous));
+
+        return buffer.toString();
+    }
+
+    public static String convertToHTMLContent(String content) {
+        content= replace(content, '&', "&amp;"); //$NON-NLS-1$
+        content= replace(content, '"', "&quot;"); //$NON-NLS-1$
+        content= replace(content, '<', "&lt;"); //$NON-NLS-1$
+        return replace(content, '>', "&gt;"); //$NON-NLS-1$
+    }
+
+    public static String read(Reader rd) {
+
+        StringBuffer buffer= new StringBuffer();
+        char[] readBuffer= new char[2048];
+
+        try {
+            int n= rd.read(readBuffer);
+            while (n > 0) {
+                buffer.append(readBuffer[ 0 .. n ]);
+                n= rd.read(readBuffer);
+            }
+            return buffer.toString();
+        } catch (IOException x) {
+        }
+
+        return null;
+    }
+
+    public static void insertPageProlog(StringBuffer buffer, int position, RGB fgRGB, RGB bgRGB, String styleSheet) {
+        if (fgRGB is null)
+            fgRGB= FG_COLOR_RGB;
+        if (bgRGB is null)
+            bgRGB= BG_COLOR_RGB;
+
+        StringBuffer pageProlog= new StringBuffer(300);
+
+        pageProlog.append("<html>"); //$NON-NLS-1$
+
+        appendStyleSheetURL(pageProlog, styleSheet);
+
+        appendColors(pageProlog, fgRGB, bgRGB);
+
+        buffer.select(position,0);
+        buffer.replace(pageProlog.toString());
+    }
+
+    private static void appendColors(StringBuffer pageProlog, RGB fgRGB, RGB bgRGB) {
+        pageProlog.append("<body text=\""); //$NON-NLS-1$
+        appendColor(pageProlog, fgRGB);
+        pageProlog.append("\" bgcolor=\""); //$NON-NLS-1$
+        appendColor(pageProlog, bgRGB);
+        pageProlog.append("\">"); //$NON-NLS-1$
+    }
+
+    private static void appendColor(StringBuffer buffer, RGB rgb) {
+        buffer.append('#');
+        appendAsHexString(buffer, rgb.red);
+        appendAsHexString(buffer, rgb.green);
+        appendAsHexString(buffer, rgb.blue);
+    }
+
+    private static void appendAsHexString(StringBuffer buffer, int intValue) {
+        String hexValue= Integer.toHexString(intValue);
+        if (hexValue.length() is 1)
+            buffer.append('0');
+        buffer.append(hexValue);
+    }
+
+    public static void insertStyles(StringBuffer buffer, String[] styles) {
+        if (styles is null || styles.length is 0)
+            return;
+
+        StringBuffer styleBuf= new StringBuffer(10 * styles.length);
+        for (int i= 0; styles !is null && i < styles.length; i++) {
+            styleBuf.append(" style=\""); //$NON-NLS-1$
+            styleBuf.append(styles[i]);
+            styleBuf.append('"');
+        }
+
+        // Find insertion index
+        // a) within existing body tag with trailing space
+        int index= buffer.slice().indexOf("<body "); //$NON-NLS-1$
+        if (index !is -1) {
+            buffer.select(index+5, 0);
+            buffer.replace(styleBuf);
+            return;
+        }
+
+        // b) within existing body tag without attributes
+        index= buffer.slice().indexOf("<body>"); //$NON-NLS-1$
+        if (index !is -1) {
+            buffer.select(index+5, 0);
+            buffer.replace( " " );
+            buffer.select(index+6, 0);
+            buffer.replace(styleBuf);
+            return;
+        }
+    }
+
+    private static void appendStyleSheetURL(StringBuffer buffer, String styleSheet) {
+        if (styleSheet is null)
+            return;
+
+        buffer.append("<head><style CHARSET=\"ISO-8859-1\" TYPE=\"text/css\">"); //$NON-NLS-1$
+        buffer.append(styleSheet);
+        buffer.append("</style></head>"); //$NON-NLS-1$
+    }
+
+    private static void appendStyleSheetURL(StringBuffer buffer, URL styleSheetURL) {
+        if (styleSheetURL is null)
+            return;
+
+        buffer.append("<head>"); //$NON-NLS-1$
+
+        buffer.append("<LINK REL=\"stylesheet\" HREF= \""); //$NON-NLS-1$
+        buffer.append(styleSheetURL.toString());
+        buffer.append("\" CHARSET=\"ISO-8859-1\" TYPE=\"text/css\">"); //$NON-NLS-1$
+
+        buffer.append("</head>"); //$NON-NLS-1$
+    }
+
+    public static void insertPageProlog(StringBuffer buffer, int position) {
+        StringBuffer pageProlog= new StringBuffer(60);
+        pageProlog.append("<html>"); //$NON-NLS-1$
+        appendColors(pageProlog, FG_COLOR_RGB, BG_COLOR_RGB);
+        buffer.select(position, 0);
+        buffer.replace(pageProlog.toString());
+    }
+
+    public static void insertPageProlog(StringBuffer buffer, int position, URL styleSheetURL) {
+        StringBuffer pageProlog= new StringBuffer(300);
+        pageProlog.append("<html>"); //$NON-NLS-1$
+        appendStyleSheetURL(pageProlog, styleSheetURL);
+        appendColors(pageProlog, FG_COLOR_RGB, BG_COLOR_RGB);
+        buffer.select(position, 0);
+        buffer.replace(pageProlog.toString());
+    }
+
+    public static void insertPageProlog(StringBuffer buffer, int position, String styleSheet) {
+        insertPageProlog(buffer, position, null, null, styleSheet);
+    }
+
+    public static void addPageProlog(StringBuffer buffer) {
+        insertPageProlog(buffer, buffer.length());
+    }
+
+    public static void addPageEpilog(StringBuffer buffer) {
+        buffer.append("</font></body></html>"); //$NON-NLS-1$
+    }
+
+    public static void startBulletList(StringBuffer buffer) {
+        buffer.append("<ul>"); //$NON-NLS-1$
+    }
+
+    public static void endBulletList(StringBuffer buffer) {
+        buffer.append("</ul>"); //$NON-NLS-1$
+    }
+
+    public static void addBullet(StringBuffer buffer, String bullet) {
+        if (bullet !is null) {
+            buffer.append("<li>"); //$NON-NLS-1$
+            buffer.append(bullet);
+            buffer.append("</li>"); //$NON-NLS-1$
+        }
+    }
+
+    public static void addSmallHeader(StringBuffer buffer, String header) {
+        if (header !is null) {
+            buffer.append("<h5>"); //$NON-NLS-1$
+            buffer.append(header);
+            buffer.append("</h5>"); //$NON-NLS-1$
+        }
+    }
+
+    public static void addParagraph(StringBuffer buffer, String paragraph) {
+        if (paragraph !is null) {
+            buffer.append("<p>"); //$NON-NLS-1$
+            buffer.append(paragraph);
+        }
+    }
+
+    public static void addParagraph(StringBuffer buffer, Reader paragraphReader) {
+        if (paragraphReader !is null)
+            addParagraph(buffer, read(paragraphReader));
+    }
+
+    /**
+     * Replaces the following style attributes of the font definition of the <code>html</code>
+     * element:
+     * <ul>
+     * <li>font-size</li>
+     * <li>font-weight</li>
+     * <li>font-style</li>
+     * <li>font-family</li>
+     * </ul>
+     * The font's name is used as font family, a <code>sans-serif</code> default font family is
+     * appended for the case that the given font name is not available.
+     * <p>
+     * If the listed font attributes are not contained in the passed style list, nothing happens.
+     * </p>
+     *
+     * @param styles CSS style definitions
+     * @param fontData the font information to use
+     * @return the modified style definitions
+     * @since 3.3
+     */
+    public static String convertTopLevelFont(String styles, FontData fontData) {
+        bool bold= (fontData.getStyle() & DWT.BOLD) !is 0;
+        bool italic= (fontData.getStyle() & DWT.ITALIC) !is 0;
+
+        // See: https://bugs.eclipse.org/bugs/show_bug.cgi?id=155993
+        String size= Integer.toString(fontData.getHeight()) ~ ("carbon".equals(DWT.getPlatform()) ? "px" : "pt"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+        String family= "'" ~ fontData.getName() ~ "',sans-serif"; //$NON-NLS-1$ //$NON-NLS-2$
+        styles= styles.replaceFirst("(html\\s*\\{.*(?:\\s|;)font-size:\\s*)\\d+pt(\\;?.*\\})", "$1" ~ size ~ "$2"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        styles= styles.replaceFirst("(html\\s*\\{.*(?:\\s|;)font-weight:\\s*)\\w+(\\;?.*\\})", "$1" ~ (bold ? "bold" : "normal") ~ "$2"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        styles= styles.replaceFirst("(html\\s*\\{.*(?:\\s|;)font-style:\\s*)\\w+(\\;?.*\\})", "$1" ~ (italic ? "italic" : "normal") ~ "$2"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+        styles= styles.replaceFirst("(html\\s*\\{.*(?:\\s|;)font-family:\\s*).+?(;.*\\})", "$1" ~ family ~ "$2"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+        return styles;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/html/HTMLTextPresenter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.html.HTMLTextPresenter;
+
+import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport
+import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport
+import dwtx.jface.internal.text.html.BrowserInput; // packageimport
+import dwtx.jface.internal.text.html.SingleCharReader; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport
+import dwtx.jface.internal.text.html.HTMLMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import dwtx.dwtxhelper.StringReader;
+
+import dwt.custom.StyleRange;
+import dwt.graphics.Drawable;
+import dwt.graphics.GC;
+import dwt.widgets.Display;
+import dwtx.jface.internal.text.link.contentassist.LineBreakingReader;
+import dwtx.jface.text.DefaultInformationControl;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextPresentation;
+
+
+/**
+ * <p>
+ * Moved into this package from <code>dwtx.jface.internal.text.revisions</code>.</p>
+ */
+public class HTMLTextPresenter : DefaultInformationControl_IInformationPresenter, DefaultInformationControl_IInformationPresenterExtension {
+
+    private static String LINE_DELIM_;
+    private static String LINE_DELIM() {
+        if( LINE_DELIM_ is null ){
+            LINE_DELIM_ = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        return LINE_DELIM_;
+    }
+
+    private int fCounter;
+    private bool fEnforceUpperLineLimit;
+
+    public this(bool enforceUpperLineLimit) {
+//         super();
+        fEnforceUpperLineLimit= enforceUpperLineLimit;
+    }
+
+    public this() {
+        this(true);
+    }
+
+    protected Reader createReader(String hoverInfo, TextPresentation presentation) {
+        return new HTML2TextReader(new StringReader(hoverInfo), presentation);
+    }
+
+    protected void adaptTextPresentation(TextPresentation presentation, int offset, int insertLength) {
+
+        int yoursStart= offset;
+        int yoursEnd=   offset + insertLength -1;
+        yoursEnd= Math.max(yoursStart, yoursEnd);
+
+        Iterator e= presentation.getAllStyleRangeIterator();
+        while (e.hasNext()) {
+
+            StyleRange range= cast(StyleRange) e.next();
+
+            int myStart= range.start;
+            int myEnd=   range.start + range.length -1;
+            myEnd= Math.max(myStart, myEnd);
+
+            if (myEnd < yoursStart)
+                continue;
+
+            if (myStart < yoursStart)
+                range.length += insertLength;
+            else
+                range.start += insertLength;
+        }
+    }
+
+    private void append(StringBuffer buffer, String string, TextPresentation presentation) {
+
+        int length= string.length();
+        buffer.append(string);
+
+        if (presentation !is null)
+            adaptTextPresentation(presentation, fCounter, length);
+
+        fCounter += length;
+    }
+
+    private String getIndent(String line) {
+        int length= line.length();
+
+        int i= 0;
+        while (i < length && Character.isWhitespace(line.getRelativeCodePoint(i,0)))
+            i += line.getRelativeCodePointOffset(i,1);
+
+        return (i is length ? line : line.substring(0, i)) ~ " "; //$NON-NLS-1$
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @see dwtx.jface.text.DefaultInformationControl.IInformationPresenter#updatePresentation(dwt.widgets.Display, java.lang.String, dwtx.jface.text.TextPresentation, int, int)
+     * @deprecated
+     */
+    public String updatePresentation(Display display, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight) {
+        return updatePresentation(cast(Drawable)display, hoverInfo, presentation, maxWidth, maxHeight);
+    }
+
+    /*
+     * @see IHoverInformationPresenterExtension#updatePresentation(Drawable drawable, String, TextPresentation, int, int)
+     * @since 3.2
+     */
+    public String updatePresentation(Drawable drawable, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight) {
+
+        if (hoverInfo is null)
+            return null;
+
+        GC gc= new GC(drawable);
+        try {
+
+            StringBuffer buffer= new StringBuffer();
+            int maxNumberOfLines= cast(int) Math.round(maxHeight / gc.getFontMetrics().getHeight());
+
+            fCounter= 0;
+            LineBreakingReader reader= new LineBreakingReader(createReader(hoverInfo, presentation), gc, maxWidth);
+
+            bool lastLineFormatted= false;
+            String lastLineIndent= null;
+
+            String line=reader.readLine();
+            bool lineFormatted= reader.isFormattedLine();
+            bool firstLineProcessed= false;
+
+            while (line !is null) {
+
+                if (fEnforceUpperLineLimit && maxNumberOfLines <= 0)
+                    break;
+
+                if (firstLineProcessed) {
+                    if (!lastLineFormatted)
+                        append(buffer, LINE_DELIM, null);
+                    else {
+                        append(buffer, LINE_DELIM, presentation);
+                        if (lastLineIndent !is null)
+                            append(buffer, lastLineIndent, presentation);
+                    }
+                }
+
+                append(buffer, line, null);
+                firstLineProcessed= true;
+
+                lastLineFormatted= lineFormatted;
+                if (!lineFormatted)
+                    lastLineIndent= null;
+                else if (lastLineIndent is null)
+                    lastLineIndent= getIndent(line);
+
+                line= reader.readLine();
+                lineFormatted= reader.isFormattedLine();
+
+                maxNumberOfLines--;
+            }
+
+            if (line !is null) {
+                append(buffer, LINE_DELIM, lineFormatted ? presentation : null);
+                append(buffer, HTMLMessages.getString("HTMLTextPresenter.ellipse"), presentation); //$NON-NLS-1$
+            }
+
+            return trim(buffer, presentation);
+
+        } catch (IOException e) {
+
+            // ignore TODO do something else?
+            return null;
+
+        } finally {
+            gc.dispose();
+        }
+    }
+
+    private String trim(StringBuffer buffer, TextPresentation presentation) {
+
+        int length= buffer.length();
+
+        int end= length -1;
+
+        while (end >= 0 && Character.isWhitespace(buffer.slice().getRelativeCodePoint( end, -1 )))
+            end += buffer.slice().getRelativeCodePointOffset( end, -1 );
+
+        if (end <= -1)
+            return ""; //$NON-NLS-1$
+
+        if (end < buffer.slice().getAbsoluteCodePointOffset( length, -1 ))
+            buffer.truncate(buffer.slice().getAbsoluteCodePointOffset( end, 1));
+        else
+            end= length;
+
+        int start= 0;
+        while (start < end && Character.isWhitespace(buffer.slice().getRelativeCodePoint(start, 0)))
+            start += buffer.slice().getRelativeCodePointOffset( start, 1 );
+
+        buffer.select(0, start);
+        buffer.remove();
+        presentation.setResultWindow(new Region(start, buffer.length()));
+        return buffer.toString();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/html/SingleCharReader.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.html.SingleCharReader;
+
+import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport
+import dwtx.jface.internal.text.html.SubstitutionTextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInput; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport
+import dwtx.jface.internal.text.html.HTMLMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * <p>
+ * Moved into this package from <code>dwtx.jface.internal.text.revisions</code>.</p>
+ */
+public abstract class SingleCharReader : Reader {
+
+    /**
+     * @see Reader#read()
+     */
+    public abstract int read() ;
+
+    /**
+     * @see Reader#read(char[],int,int)
+     */
+    public int read(char cbuf[], int off, int len)  {
+        int end= off + len;
+        for (int i= off; i < end; i++) {
+            int ch= read();
+            if (ch is -1) {
+                if (i is off)
+                    return -1;
+                return i - off;
+            }
+            cbuf[i]= cast(char)ch;
+        }
+        return len;
+    }
+
+    /**
+     * @see Reader#ready()
+     */
+    public bool ready()  {
+        return true;
+    }
+
+    /**
+     * Returns the readable content as string.
+     * @return the readable content as string
+     * @exception IOException in case reading fails
+     */
+    public String getString()  {
+        StringBuffer buf= new StringBuffer();
+        int ch;
+        while ((ch= read()) !is -1) {
+            buf.append(cast(char)ch);
+        }
+        return buf.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/html/SubstitutionTextReader.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.html.SubstitutionTextReader;
+
+import dwtx.jface.internal.text.html.HTML2TextReader; // packageimport
+import dwtx.jface.internal.text.html.HTMLPrinter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControl; // packageimport
+import dwtx.jface.internal.text.html.HTMLTextPresenter; // packageimport
+import dwtx.jface.internal.text.html.BrowserInput; // packageimport
+import dwtx.jface.internal.text.html.SingleCharReader; // packageimport
+import dwtx.jface.internal.text.html.BrowserInformationControlInput; // packageimport
+import dwtx.jface.internal.text.html.HTMLMessages; // packageimport
+
+import dwt.dwthelper.utils;
+import tango.core.Exception;
+
+/**
+ * Reads the text contents from a reader and computes for each character
+ * a potential substitution. The substitution may eat more characters than
+ * only the one passed into the computation routine.
+ * <p>
+ * Moved into this package from <code>dwtx.jface.internal.text.revisions</code>.</p>
+ */
+public abstract class SubstitutionTextReader : SingleCharReader {
+
+    private static String LINE_DELIM_;
+    protected static String LINE_DELIM() {
+        if( LINE_DELIM_ is null ){
+            LINE_DELIM_ = System.getProperty("line.separator", "\n"); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        return LINE_DELIM_;
+    }
+
+    private Reader fReader;
+    protected bool fWasWhiteSpace;
+    private int fCharAfterWhiteSpace;
+
+    /**
+     * Tells whether white space characters are skipped.
+     */
+    private bool fSkipWhiteSpace= true;
+
+    private bool fReadFromBuffer;
+    private StringBuffer fBuffer;
+    private int fIndex;
+
+
+    protected this(Reader reader) {
+        fReader= reader;
+        fBuffer= new StringBuffer();
+        fIndex= 0;
+        fReadFromBuffer= false;
+        fCharAfterWhiteSpace= -1;
+        fWasWhiteSpace= true;
+    }
+
+    /**
+     * Computes the substitution for the given character and if necessary
+     * subsequent characters. Implementation should use <code>nextChar</code>
+     * to read subsequent characters.
+     *
+     * @param c the character to be substituted
+     * @return the substitution for <code>c</code>
+     * @throws IOException in case computing the substitution fails
+     */
+    protected abstract String computeSubstitution(int c) ;
+
+    /**
+     * Returns the internal reader.
+     *
+     * @return the internal reader
+     */
+    protected Reader getReader() {
+        return fReader;
+    }
+
+    /**
+     * Returns the next character.
+     * @return the next character
+     * @throws IOException in case reading the character fails
+     */
+    protected int nextChar()  {
+        fReadFromBuffer= (fBuffer.length() > 0);
+        if (fReadFromBuffer) {
+            char ch= fBuffer.slice().charAt(fIndex++);
+            if (fIndex >= fBuffer.length()) {
+                fBuffer.truncate(0);
+                fIndex= 0;
+            }
+            return ch;
+        }
+
+        int ch= fCharAfterWhiteSpace;
+        if (ch is -1) {
+            ch= fReader.read();
+        }
+        if (fSkipWhiteSpace && Character.isWhitespace(cast(char)ch)) {
+            do {
+                ch= fReader.read();
+            } while (Character.isWhitespace(cast(char)ch));
+            if (ch !is -1) {
+                fCharAfterWhiteSpace= ch;
+                return ' ';
+            }
+        } else {
+            fCharAfterWhiteSpace= -1;
+        }
+        return ch;
+    }
+
+    /// DWT
+    protected int nextDChar()  {
+        char[4] buf = void;
+        int ch1 = nextChar();
+        if( ch1 is -1 ) return -1;
+        buf[0] = cast(char)ch1;
+        if(( ch1 & 0x80 ) is 0x00 ){
+            return ch1;
+        }
+        else if(( ch1 & 0xE0 ) is 0xC0 ){
+            int ch2 = nextChar();
+            if( ch2 is -1 ) throw new UnicodeException(__FILE__,__LINE__);
+            buf[1] = cast(char)ch2;
+        }
+        else if(( ch1 & 0xF0 ) is 0xE0 ){
+            int ch2 = nextChar();
+            if( ch1 is -1 ) throw new UnicodeException(__FILE__,__LINE__);
+            buf[1] = cast(char)ch2;
+            int ch3 = nextChar();
+            if( ch3 is -1 ) throw new UnicodeException(__FILE__,__LINE__);
+            buf[2] = cast(char)ch3;
+        }
+        else if(( ch1 & 0xF8 ) is 0xF0 ){
+            int ch2 = nextChar();
+            if( ch1 is -1 ) throw new UnicodeException(__FILE__,__LINE__);
+            buf[1] = cast(char)ch2;
+            int ch3 = nextChar();
+            if( ch3 is -1 ) throw new UnicodeException(__FILE__,__LINE__);
+            buf[2] = cast(char)ch3;
+            int ch4 = nextChar();
+            if( ch4 is -1 ) throw new UnicodeException(__FILE__,__LINE__);
+            buf[3] = cast(char)ch4;
+        }
+        else {
+            throw new UnicodeException(__FILE__,__LINE__);
+        }
+        uint ate;
+        return tango.text.convert.Utf.decode( buf, ate );
+    }
+
+    /**
+     * @see Reader#read()
+     */
+    public int read()  {
+        int c;
+        do {
+
+            c= nextChar();
+            while (!fReadFromBuffer) {
+                String s= computeSubstitution(c);
+                if (s is null)
+                    break;
+                if (s.length() > 0){
+                    fBuffer.select(0, 0);
+                    fBuffer.replace(s);
+                }
+                c= nextChar();
+            }
+
+        } while (fSkipWhiteSpace && fWasWhiteSpace && (c is ' '));
+        fWasWhiteSpace= (c is ' ' || c is '\r' || c is '\n');
+        return c;
+    }
+
+    /**
+     * @see Reader#ready()
+     */
+    public bool ready()  {
+        return fReader.ready();
+    }
+
+    /**
+     * @see Reader#close()
+     */
+    public void close()  {
+        fReader.close();
+    }
+
+    /**
+     * @see Reader#reset()
+     */
+    public void reset()  {
+        fReader.reset();
+        fWasWhiteSpace= true;
+        fCharAfterWhiteSpace= -1;
+        fBuffer.truncate(0);
+        fIndex= 0;
+    }
+
+    protected final void setSkipWhitespace(bool state) {
+        fSkipWhiteSpace= state;
+    }
+
+    protected final bool isSkippingWhitespace() {
+        return fSkipWhiteSpace;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/link/contentassist/AdditionalInfoController2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,273 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2;
+
+import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport
+import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport
+import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport
+import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport
+
+import dwt.dwthelper.utils;
+import tango.core.Thread;
+
+import dwt.events.SelectionEvent;
+import dwt.events.SelectionListener;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Control;
+import dwt.widgets.Table;
+import dwt.widgets.TableItem;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.AbstractInformationControlManager;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.contentassist.ICompletionProposal;
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3;
+
+
+
+/**
+ * Displays the additional information available for a completion proposal.
+ *
+ * @since 2.0
+ */
+class AdditionalInfoController2 : AbstractInformationControlManager , Runnable {
+
+    /**
+     * Internal table selection listener.
+     */
+    private class TableSelectionListener : SelectionListener {
+
+        /*
+         * @see SelectionListener#widgetSelected(SelectionEvent)
+         */
+        public void widgetSelected(SelectionEvent e) {
+            handleTableSelectionChanged();
+        }
+
+        /*
+         * @see SelectionListener#widgetDefaultSelected(SelectionEvent)
+         */
+        public void widgetDefaultSelected(SelectionEvent e) {
+        }
+    }
+
+
+    /** The proposal table */
+    private Table fProposalTable;
+    /** The thread controlling the delayed display of the additional info */
+    private Thread fThread;
+    /** Indicates whether the display delay has been reset */
+    private bool fIsReset= false;
+    /** Object to synchronize display thread and table selection changes */
+    private const Object fMutex;
+    /** Thread access lock. */
+    private const Object fThreadAccess;
+    /** Object to synchronize initial display of additional info */
+    private Object fStartSignal;
+    /** The table selection listener */
+    private SelectionListener fSelectionListener;
+    /** The delay after which additional information is displayed */
+    private int fDelay;
+
+
+    /**
+     * Creates a new additional information controller.
+     *
+     * @param creator the information control creator to be used by this controller
+     * @param delay time in milliseconds after which additional info should be displayed
+     */
+    this(IInformationControlCreator creator, int delay) {
+        fSelectionListener= new TableSelectionListener();
+        fThreadAccess= new Object();
+        fMutex= new Object();
+        super(creator);
+        fDelay= delay;
+        setAnchor(ANCHOR_RIGHT);
+        setFallbackAnchors([ANCHOR_RIGHT, ANCHOR_LEFT, ANCHOR_BOTTOM ]);
+    }
+
+    /*
+     * @see AbstractInformationControlManager#install(Control)
+     */
+    public void install(Control control) {
+
+        if (fProposalTable is control) {
+            // already installed
+            return;
+        }
+
+        super.install(control);
+
+        Assert.isTrue( null !is cast(Table)control );
+        fProposalTable= cast(Table) control;
+        fProposalTable.addSelectionListener(fSelectionListener);
+        synchronized (fThreadAccess) {
+            if (fThread !is null)
+                fThread.interrupt();
+            fThread= new Thread(this, ContentAssistMessages.getString("InfoPopup.info_delay_timer_name")); //$NON-NLS-1$
+
+            fStartSignal= new Object();
+            synchronized (fStartSignal) {
+                fThread.start();
+                try {
+                    // wait until thread is ready
+                    fStartSignal.wait();
+                } catch (InterruptedException x) {
+                }
+            }
+        }
+    }
+
+    /*
+     * @see AbstractInformationControlManager#disposeInformationControl()
+     */
+     public void disposeInformationControl() {
+
+        synchronized (fThreadAccess) {
+            if (fThread !is null) {
+                fThread.interrupt();
+                fThread= null;
+            }
+        }
+
+        if (fProposalTable !is null && !fProposalTable.isDisposed()) {
+            fProposalTable.removeSelectionListener(fSelectionListener);
+            fProposalTable= null;
+        }
+
+        super.disposeInformationControl();
+    }
+
+    /*
+     * @see java.lang.Runnable#run()
+     */
+    public void run() {
+        try {
+            while (true) {
+
+                synchronized (fMutex) {
+
+                    if (fStartSignal !is null) {
+                        synchronized (fStartSignal) {
+                            fStartSignal.notifyAll();
+                            fStartSignal= null;
+                        }
+                    }
+
+                    // Wait for a selection event to occur.
+                    fMutex.wait();
+
+                    while (true) {
+                        fIsReset= false;
+                        // Delay before showing the popup.
+                        fMutex.wait(fDelay);
+                        if (!fIsReset)
+                            break;
+                    }
+                }
+
+                if (fProposalTable !is null && !fProposalTable.isDisposed()) {
+                    fProposalTable.getDisplay().asyncExec(new class()  Runnable {
+                        public void run() {
+                            if (!fIsReset)
+                                showInformation();
+                        }
+                    });
+                }
+
+            }
+        } catch (InterruptedException e) {
+        }
+
+        synchronized (fThreadAccess) {
+            // only null fThread if it is us!
+            if (Thread.currentThread() is fThread)
+                fThread= null;
+        }
+    }
+
+    /**
+     *Handles a change of the line selected in the associated selector.
+     */
+    public void handleTableSelectionChanged() {
+
+        if (fProposalTable !is null && !fProposalTable.isDisposed() && fProposalTable.isVisible()) {
+            synchronized (fMutex) {
+                fIsReset= true;
+                fMutex.notifyAll();
+            }
+        }
+    }
+
+    /*
+     * @see AbstractInformationControlManager#computeInformation()
+     */
+    protected void computeInformation() {
+
+        if (fProposalTable is null || fProposalTable.isDisposed())
+            return;
+
+        TableItem[] selection= fProposalTable.getSelection();
+        if (selection !is null && selection.length > 0) {
+
+            TableItem item= selection[0];
+
+            // compute information
+            String information= null;
+            Object d= item.getData();
+
+            if ( cast(ICompletionProposal)d ) {
+                ICompletionProposal p= cast(ICompletionProposal) d;
+                information= p.getAdditionalProposalInfo();
+            }
+
+            if ( cast(ICompletionProposalExtension3)d )
+                setCustomInformationControlCreator((cast(ICompletionProposalExtension3) d).getInformationControlCreator());
+            else
+                setCustomInformationControlCreator(null);
+
+            // compute subject area
+            setMargins(4, -1);
+            Rectangle area= fProposalTable.getBounds();
+            area.x= 0; // subject area is the whole subject control
+            area.y= 0;
+
+            // set information & subject area
+            setInformation(information, area);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#computeSizeConstraints(Control, IInformationControl)
+     */
+    protected Point computeSizeConstraints(Control subjectControl, IInformationControl informationControl) {
+        // at least as big as the proposal table
+        Point sizeConstraint= super.computeSizeConstraints(subjectControl, informationControl);
+        Point size= subjectControl.getSize();
+        if (sizeConstraint.x < size.x)
+            sizeConstraint.x= size.x;
+        if (sizeConstraint.y < size.y)
+            sizeConstraint.y= size.y;
+        return sizeConstraint;
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/link/contentassist/CompletionProposalPopup2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,968 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Sean Montgomery, sean_montgomery@comcast.net - https://bugs.eclipse.org/bugs/show_bug.cgi?id=116454
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2;
+
+import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport
+import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport
+import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwt.DWT;
+import dwt.custom.StyleRange;
+import dwt.custom.StyledText;
+import dwt.events.ControlEvent;
+import dwt.events.ControlListener;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.events.SelectionEvent;
+import dwt.events.SelectionListener;
+import dwt.events.VerifyEvent;
+import dwt.graphics.Color;
+import dwt.graphics.Point;
+import dwt.layout.GridData;
+import dwt.layout.GridLayout;
+import dwt.widgets.Control;
+import dwt.widgets.Shell;
+import dwt.widgets.Table;
+import dwt.widgets.TableItem;
+import dwtx.jface.internal.text.TableOwnerDrawSupport;
+import dwtx.jface.resource.JFaceResources;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentListener;
+import dwtx.jface.text.IEditingSupport;
+import dwtx.jface.text.IEditingSupportRegistry;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.IRewriteTarget;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension;
+import dwtx.jface.text.TextUtilities;
+import dwtx.jface.text.contentassist.ICompletionProposal;
+import dwtx.jface.text.contentassist.ICompletionProposalExtension;
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2;
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6;
+import dwtx.jface.text.contentassist.IContextInformation;
+import dwtx.jface.viewers.StyledString;
+
+
+
+/**
+ * This class is used to present proposals to the user. If additional
+ * information exists for a proposal, then selecting that proposal
+ * will result in the information being displayed in a secondary
+ * window.
+ *
+ * @see dwtx.jface.text.contentassist.ICompletionProposal
+ * @see dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2
+ */
+class CompletionProposalPopup2 : IContentAssistListener2 {
+
+    /** The associated text viewer */
+    private ITextViewer fViewer;
+    /** The associated content assistant */
+    private ContentAssistant2 fContentAssistant;
+    /** The used additional info controller */
+    private AdditionalInfoController2 fAdditionalInfoController;
+    /** The closing strategy for this completion proposal popup */
+    private PopupCloser2 fPopupCloser;
+    /** The popup shell */
+    private Shell fProposalShell;
+    /** The proposal table */
+    private Table fProposalTable;
+    /** Indicates whether a completion proposal is being inserted */
+    private bool fInserting= false;
+    /** The key listener to control navigation */
+    private KeyListener fKeyListener;
+    /** List of document events used for filtering proposals */
+    private List fDocumentEvents;
+    /** Listener filling the document event queue */
+    private IDocumentListener fDocumentListener;
+    /** Reentrance count for <code>filterProposals</code> */
+    private long fInvocationCounter= 0;
+    /** The filter list of proposals */
+    private ICompletionProposal[] fFilteredProposals;
+    /** The computed list of proposals */
+    private ICompletionProposal[] fComputedProposals;
+    /** The offset for which the proposals have been computed */
+    private int fInvocationOffset;
+    /** The offset for which the computed proposals have been filtered */
+    private int fFilterOffset;
+    /** The default line delimiter of the viewer's widget */
+    private String fLineDelimiter;
+    /** The most recently selected proposal. */
+    private ICompletionProposal fLastProposal;
+    /**
+     * Tells whether colored labels support is enabled.
+     * Only valid while the popup is active.
+     *
+     * @since 3.4
+     */
+    private bool fIsColoredLabelsSupportEnabled= false;
+
+    private IEditingSupport fFocusEditingSupport;
+    private void fFocusEditingSupport_init() {
+        fFocusEditingSupport = new class() IEditingSupport {
+
+            public bool isOriginator(DocumentEvent event, IRegion focus) {
+                return false;
+            }
+
+            public bool ownsFocusShell() {
+                return Helper2.okToUse(fProposalShell) && fProposalShell.isFocusControl()
+                        || Helper2.okToUse(fProposalTable) && fProposalTable.isFocusControl();
+            }
+
+        };
+    }
+    private IEditingSupport fModificationEditingSupport;
+    private void fModificationEditingSupport_init() {
+        fModificationEditingSupport = new class()  IEditingSupport {
+
+            public bool isOriginator(DocumentEvent event, IRegion focus) {
+                if (fViewer !is null) {
+                    Point selection= fViewer.getSelectedRange();
+                    return selection.x <= focus.getOffset() + focus.getLength() && selection.x + selection.y >= focus.getOffset();
+                }
+                return false;
+            }
+
+            public bool ownsFocusShell() {
+                return false;
+            }
+
+        };
+    }
+
+    /**
+     * Creates a new completion proposal popup for the given elements.
+     *
+     * @param contentAssistant the content assistant feeding this popup
+     * @param viewer the viewer on top of which this popup appears
+     * @param infoController the info control collaborating with this popup
+     * @since 2.0
+     */
+    public this(ContentAssistant2 contentAssistant, ITextViewer viewer, AdditionalInfoController2 infoController) {
+        fPopupCloser= new PopupCloser2();
+        fDocumentEvents= new ArrayList();
+
+        fModificationEditingSupport_init();
+        fFocusEditingSupport_init();
+
+        fContentAssistant= contentAssistant;
+        fViewer= viewer;
+        fAdditionalInfoController= infoController;
+    }
+
+    /**
+     * Computes and presents completion proposals. The flag indicates whether this call has
+     * be made out of an auto activation context.
+     *
+     * @param autoActivated <code>true</code> if auto activation context
+     * @return an error message or <code>null</code> in case of no error
+     */
+    public String showProposals(bool autoActivated) {
+
+        if (fKeyListener is null) {
+            fKeyListener= new class()  KeyListener {
+                public void keyPressed(KeyEvent e) {
+                    if (!Helper2.okToUse(fProposalShell))
+                        return;
+
+                    if (e.character is 0 && e.keyCode is DWT.CTRL) {
+                        // http://dev.eclipse.org/bugs/show_bug.cgi?id=34754
+                        int index= fProposalTable.getSelectionIndex();
+                        if (index >= 0)
+                            selectProposal(index, true);
+                    }
+                }
+
+                public void keyReleased(KeyEvent e) {
+                    if (!Helper2.okToUse(fProposalShell))
+                        return;
+
+                    if (e.character is 0 && e.keyCode is DWT.CTRL) {
+                        // http://dev.eclipse.org/bugs/show_bug.cgi?id=34754
+                        int index= fProposalTable.getSelectionIndex();
+                        if (index >= 0)
+                            selectProposal(index, false);
+                    }
+                }
+            };
+        }
+
+        final StyledText styledText= fViewer.getTextWidget();
+        if (styledText !is null && !styledText.isDisposed())
+            styledText.addKeyListener(fKeyListener);
+
+//      BusyIndicator.showWhile(styledText.getDisplay(), new class()  Runnable {
+//          public void run() {
+
+                fInvocationOffset= fViewer.getSelectedRange().x;
+                // lazily compute proposals
+//              if (fComputedProposals is null) fComputedProposals= computeProposals(fContentAssistant.getCompletionPosition());
+                fComputedProposals= computeProposals(fInvocationOffset);
+
+                int count= (fComputedProposals is null ? 0 : fComputedProposals.length);
+                if (count is 0) {
+
+                    if (!autoActivated)
+                        styledText.getDisplay().beep();
+
+                } else {
+
+                    if (count is 1 && !autoActivated && fContentAssistant.isAutoInserting())
+
+                        insertProposal(fComputedProposals[0], cast(wchar) 0, 0, fInvocationOffset);
+
+                    else {
+
+                        if (fLineDelimiter is null)
+                            fLineDelimiter= styledText.getLineDelimiter();
+
+                        createProposalSelector();
+                        setProposals(fComputedProposals);
+                        resizeProposalSelector(true);
+                        displayProposals();
+                    }
+                }
+//          }
+//      });
+
+        return getErrorMessage();
+    }
+
+    /**
+     * Returns the completion proposal available at the given offset of the
+     * viewer's document. Delegates the work to the content assistant.
+     *
+     * @param offset the offset
+     * @return the completion proposals available at this offset
+     */
+    private ICompletionProposal[] computeProposals(int offset) {
+        return fContentAssistant.computeCompletionProposals(fViewer, offset);
+    }
+
+    /**
+     * Returns the error message.
+     *
+     * @return the error message
+     */
+    private String getErrorMessage() {
+        return fContentAssistant.getErrorMessage();
+    }
+
+    /**
+     * Creates the proposal selector.
+     */
+    private void createProposalSelector() {
+        if (Helper2.okToUse(fProposalShell))
+            return;
+
+        Control control= fViewer.getTextWidget();
+        fProposalShell= new Shell(control.getShell(), DWT.ON_TOP);
+//      fProposalShell= new Shell(control.getShell(), DWT.ON_TOP | DWT.RESIZE );
+        fProposalTable= new Table(fProposalShell, DWT.H_SCROLL | DWT.V_SCROLL);
+//      fProposalTable= new Table(fProposalShell, DWT.H_SCROLL | DWT.V_SCROLL);
+
+
+        fIsColoredLabelsSupportEnabled= fContentAssistant.isColoredLabelsSupportEnabled();
+        if (fIsColoredLabelsSupportEnabled)
+            TableOwnerDrawSupport.install(fProposalTable);
+
+        fProposalTable.setLocation(0, 0);
+        if (fAdditionalInfoController !is null)
+            fAdditionalInfoController.setSizeConstraints(50, 10, true, false);
+
+        GridLayout layout= new GridLayout();
+        layout.marginWidth= 0;
+        layout.marginHeight= 0;
+        fProposalShell.setLayout(layout);
+
+        GridData data= new GridData(GridData.FILL_BOTH);
+        fProposalTable.setLayoutData(data);
+
+        fProposalShell.pack();
+
+        // set location
+        Point currentLocation= fProposalShell.getLocation();
+        Point newLocation= getLocation();
+        if ((newLocation.x < currentLocation.x && newLocation.y is currentLocation.y) || newLocation.y < currentLocation.y)
+            fProposalShell.setLocation(newLocation);
+
+        if (fAdditionalInfoController !is null) {
+            fProposalShell.addControlListener(new class()  ControlListener {
+
+                public void controlMoved(ControlEvent e) {}
+
+                public void controlResized(ControlEvent e) {
+                    // resets the cached resize constraints
+                    fAdditionalInfoController.setSizeConstraints(50, 10, true, false);
+                }
+            });
+        }
+
+        fProposalShell.setBackground(control.getDisplay().getSystemColor(DWT.COLOR_BLACK));
+
+        Color c= control.getDisplay().getSystemColor(DWT.COLOR_INFO_BACKGROUND);
+        fProposalTable.setBackground(c);
+
+        c= control.getDisplay().getSystemColor(DWT.COLOR_INFO_FOREGROUND);
+        fProposalTable.setForeground(c);
+
+        fProposalTable.addSelectionListener(new class()  SelectionListener {
+
+            public void widgetSelected(SelectionEvent e) {}
+
+            public void widgetDefaultSelected(SelectionEvent e) {
+                selectProposalWithMask(e.stateMask);
+            }
+        });
+
+        fPopupCloser.install(fContentAssistant, fProposalTable);
+
+        fProposalShell.addDisposeListener(new class()  DisposeListener {
+            public void widgetDisposed(DisposeEvent e) {
+                unregister(); // but don't dispose the shell, since we're being called from its disposal event!
+            }
+        });
+
+        fProposalTable.setHeaderVisible(false);
+        fContentAssistant.addToLayout(this, fProposalShell, ContentAssistant2.LayoutManager.LAYOUT_PROPOSAL_SELECTOR, fContentAssistant.getSelectionOffset());
+    }
+
+    /**
+     * Returns the proposal selected in the proposal selector.
+     *
+     * @return the selected proposal
+     * @since 2.0
+     */
+    private ICompletionProposal getSelectedProposal() {
+        int i= fProposalTable.getSelectionIndex();
+        if (i < 0 || i >= fFilteredProposals.length)
+            return null;
+        return fFilteredProposals[i];
+    }
+
+    /**
+     * Takes the selected proposal and applies it.
+     *
+     * @param stateMask the state mask
+     * @since 2.1
+     */
+    private void selectProposalWithMask(int stateMask) {
+        ICompletionProposal p= getSelectedProposal();
+        hide();
+        if (p !is null)
+            insertProposal(p, cast(wchar) 0, stateMask, fViewer.getSelectedRange().x);
+    }
+
+    /**
+     * Applies the given proposal at the given offset. The given character is the
+     * one that triggered the insertion of this proposal.
+     *
+     * @param p the completion proposal
+     * @param trigger the trigger character
+     * @param stateMask the state mask of the keyboard event triggering the insertion
+     * @param offset the offset
+     * @since 2.1
+     */
+    private void insertProposal(ICompletionProposal p, char trigger, int stateMask, int offset) {
+
+        fInserting= true;
+        IRewriteTarget target= null;
+        IEditingSupportRegistry registry= null;
+
+        try {
+
+            IDocument document= fViewer.getDocument();
+
+            if ( cast(ITextViewerExtension)fViewer ) {
+                ITextViewerExtension extension= cast(ITextViewerExtension) fViewer;
+                target= extension.getRewriteTarget();
+            }
+
+            if (target !is null)
+                target.beginCompoundChange();
+
+            if ( cast(IEditingSupportRegistry)fViewer ) {
+                registry= cast(IEditingSupportRegistry) fViewer;
+                registry.register(fModificationEditingSupport);
+            }
+
+            if ( cast(ICompletionProposalExtension2)p ) {
+                ICompletionProposalExtension2 e= cast(ICompletionProposalExtension2) p;
+                e.apply(fViewer, trigger, stateMask, offset);
+            } else if ( cast(ICompletionProposalExtension)p ) {
+                ICompletionProposalExtension e= cast(ICompletionProposalExtension) p;
+                e.apply(document, trigger, offset);
+            } else {
+                p.apply(document);
+            }
+
+            Point selection= p.getSelection(document);
+            if (selection !is null) {
+                fViewer.setSelectedRange(selection.x, selection.y);
+                fViewer.revealRange(selection.x, selection.y);
+            }
+
+            IContextInformation info= p.getContextInformation();
+            if (info !is null) {
+
+                int position;
+                if ( cast(ICompletionProposalExtension)p ) {
+                    ICompletionProposalExtension e= cast(ICompletionProposalExtension) p;
+                    position= e.getContextInformationPosition();
+                } else {
+                    if (selection is null)
+                        selection= fViewer.getSelectedRange();
+                    position= selection.x + selection.y;
+                }
+
+                fContentAssistant.showContextInformation(info, position);
+            }
+
+            fContentAssistant.fireProposalChosen(p);
+
+        } finally {
+            if (target !is null)
+                target.endCompoundChange();
+
+            if (registry !is null)
+                registry.unregister(fModificationEditingSupport);
+
+            fInserting= false;
+        }
+    }
+
+    /**
+     * Returns whether this popup has the focus.
+     *
+     * @return <code>true</code> if the popup has the focus
+     */
+    public bool hasFocus() {
+        if (Helper2.okToUse(fProposalShell))
+            return (fProposalShell.isFocusControl() || fProposalTable.isFocusControl());
+
+        return false;
+    }
+
+    /**
+     * Hides this popup.
+     */
+    public void hide() {
+
+        unregister();
+
+        if ( cast(IEditingSupportRegistry)fViewer ) {
+            IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer;
+            registry.unregister(fFocusEditingSupport);
+        }
+
+        if (Helper2.okToUse(fProposalShell)) {
+            fContentAssistant.removeContentAssistListener(this, ContentAssistant2.PROPOSAL_SELECTOR);
+
+            fPopupCloser.uninstall();
+            // see bug 47511: setVisible may run the event loop on GTK
+            // and trigger a rentrant call - have to make sure we don't
+            // dispose another shell that was already brought up in a
+            // reentrant call when calling setVisible()
+            Shell tempShell= fProposalShell;
+            fProposalShell= null;
+            tempShell.setVisible(false);
+            tempShell.dispose();
+        }
+    }
+
+    private void unregister() {
+        if (fDocumentListener !is null) {
+            IDocument document= fViewer.getDocument();
+            if (document !is null)
+                document.removeDocumentListener(fDocumentListener);
+            fDocumentListener= null;
+        }
+        fDocumentEvents.clear();
+
+        StyledText styledText= fViewer.getTextWidget();
+        if (fKeyListener !is null && styledText !is null && !styledText.isDisposed())
+            styledText.removeKeyListener(fKeyListener);
+
+        if (fLastProposal !is null) {
+            if ( cast(ICompletionProposalExtension2)fLastProposal ) {
+                ICompletionProposalExtension2 extension= cast(ICompletionProposalExtension2) fLastProposal;
+                extension.unselected(fViewer);
+            }
+
+            fLastProposal= null;
+        }
+
+        fFilteredProposals= null;
+
+        fContentAssistant.possibleCompletionsClosed_package();
+    }
+
+    /**
+     *Returns whether this popup is active. It is active if the propsal selector is visible.
+     *
+     * @return <code>true</code> if this popup is active
+     */
+    public bool isActive() {
+        return fProposalShell !is null && !fProposalShell.isDisposed();
+    }
+
+    /**
+     * Initializes the proposal selector with these given proposals.
+     *
+     * @param proposals the proposals
+     */
+    private void setProposals(ICompletionProposal[] proposals) {
+        if (Helper2.okToUse(fProposalTable)) {
+
+            ICompletionProposal oldProposal= getSelectedProposal();
+            if ( cast(ICompletionProposalExtension2)oldProposal )
+                (cast(ICompletionProposalExtension2) oldProposal).unselected(fViewer);
+
+            fFilteredProposals= proposals;
+
+            fProposalTable.setRedraw(false);
+            fProposalTable.removeAll();
+
+            Point selection= fViewer.getSelectedRange();
+            int endOffset;
+            endOffset= selection.x + selection.y;
+            IDocument document= fViewer.getDocument();
+            bool validate= false;
+            if (selection.y !is 0 && document !is null) validate= true;
+            int selectionIndex= 0;
+
+            TableItem item;
+            ICompletionProposal p;
+            for (int i= 0; i < proposals.length; i++) {
+                p= proposals[i];
+                item= new TableItem(fProposalTable, DWT.NULL);
+                if (p.getImage() !is null)
+                    item.setImage(p.getImage());
+
+                String displayString;
+                StyleRange[] styleRanges= null;
+                if (fIsColoredLabelsSupportEnabled && cast(ICompletionProposalExtension6)p ) {
+                    StyledString styledString= (cast(ICompletionProposalExtension6)p).getStyledDisplayString();
+                    displayString= styledString.getString();
+                    styleRanges= styledString.getStyleRanges();
+                } else
+                    displayString= p.getDisplayString();
+
+                item.setText(displayString);
+                if (fIsColoredLabelsSupportEnabled)
+                    TableOwnerDrawSupport.storeStyleRanges(item, 0, styleRanges);
+
+                item.setData(cast(Object)p);
+
+                if (validate && validateProposal(document, p, endOffset, null)) {
+                    selectionIndex= i;
+                    validate= false;
+                }
+            }
+
+            resizeProposalSelector(false);
+
+            selectProposal(selectionIndex, false);
+            fProposalTable.setRedraw(true);
+        }
+    }
+
+    private void resizeProposalSelector(bool adjustWidth) {
+        // in order to fill in the table items so size computation works correctly
+        // will cause flicker, though
+        fProposalTable.setRedraw(true);
+
+        int width= adjustWidth ? DWT.DEFAULT : (cast(GridData)fProposalTable.getLayoutData()).widthHint;
+        Point size= fProposalTable.computeSize(width, DWT.DEFAULT, true);
+
+        GridData data= new GridData(GridData.FILL_BOTH);
+        data.widthHint= adjustWidth ? Math.min(size.x, 300) : width;
+        data.heightHint= Math.min(getTableHeightHint(fProposalTable, fProposalTable.getItemCount()), getTableHeightHint(fProposalTable, 10));
+        fProposalTable.setLayoutData(data);
+
+        fProposalShell.layout(true);
+        fProposalShell.pack();
+
+        if (adjustWidth) {
+            fProposalShell.setLocation(getLocation());
+        }
+    }
+
+    /**
+     * Computes the table hight hint for <code>table</code>.
+     *
+     * @param table the table to compute the height for
+     * @param rows the number of rows to compute the height for
+     * @return the height hint for <code>table</code>
+     */
+    private int getTableHeightHint(Table table, int rows) {
+        if (table.getFont().opEquals(JFaceResources.getDefaultFont()))
+            table.setFont(JFaceResources.getDialogFont());
+        int result= table.getItemHeight() * rows;
+        if (table.getLinesVisible())
+            result+= table.getGridLineWidth() * (rows - 1);
+
+        // TODO adjust to correct size. +4 works on windows, but not others
+//      return result + 4;
+        return result;
+    }
+
+    private bool validateProposal(IDocument document, ICompletionProposal p, int offset, DocumentEvent event) {
+        // detect selected
+        if ( cast(ICompletionProposalExtension2)p ) {
+            ICompletionProposalExtension2 e= cast(ICompletionProposalExtension2) p;
+            if (e.validate(document, offset, event))
+                return true;
+        } else if ( cast(ICompletionProposalExtension)p ) {
+            ICompletionProposalExtension e= cast(ICompletionProposalExtension) p;
+            if (e.isValidFor(document, offset))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the graphical location at which this popup should be made visible.
+     *
+     * @return the location of this popup
+     */
+    private Point getLocation() {
+        StyledText text= fViewer.getTextWidget();
+        Point selection= text.getSelection();
+        Point p= text.getLocationAtOffset(selection.x);
+        p.x -= fProposalShell.getBorderWidth();
+        if (p.x < 0) p.x= 0;
+        if (p.y < 0) p.y= 0;
+        p= new Point(p.x, p.y + text.getLineHeight(selection.x));
+        p= text.toDisplay(p);
+        return p;
+    }
+
+    /**
+     *Displays this popup and install the additional info controller, so that additional info
+     * is displayed when a proposal is selected and additional info is available.
+     */
+    private void displayProposals() {
+        if (fContentAssistant.addContentAssistListener(this, ContentAssistant2.PROPOSAL_SELECTOR)) {
+
+            if (fDocumentListener is null)
+                fDocumentListener=  new class()   IDocumentListener {
+                    public void documentAboutToBeChanged(DocumentEvent event) {
+                        if (!fInserting)
+                            fDocumentEvents.add(event);
+                    }
+
+                    public void documentChanged(DocumentEvent event) {
+                        if (!fInserting)
+                            filterProposals();
+                    }
+                };
+            IDocument document= fViewer.getDocument();
+            if (document !is null)
+                document.addDocumentListener(fDocumentListener);
+
+
+            if ( cast(IEditingSupportRegistry)fViewer ) {
+                IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer;
+                registry.register(fFocusEditingSupport);
+            }
+
+            fProposalShell.setVisible(true);
+            // see bug 47511: setVisible may run the event loop on GTK
+            // and trigger a rentrant call - have to check whether we are still
+            // visible
+            if (!Helper2.okToUse(fProposalShell))
+                return;
+
+
+            if (fAdditionalInfoController !is null) {
+                fAdditionalInfoController.install(fProposalTable);
+                fAdditionalInfoController.handleTableSelectionChanged();
+            }
+        }
+    }
+
+        /*
+         * @see IContentAssistListener#verifyKey(VerifyEvent)
+         */
+        public bool verifyKey(VerifyEvent e) {
+            if (!Helper2.okToUse(fProposalShell))
+                return true;
+
+            char key= e.character;
+            if (key is 0) {
+                int newSelection= fProposalTable.getSelectionIndex();
+                int visibleRows= (fProposalTable.getSize().y / fProposalTable.getItemHeight()) - 1;
+                bool smartToggle= false;
+                switch (e.keyCode) {
+
+                    case DWT.ARROW_LEFT :
+                    case DWT.ARROW_RIGHT :
+                        filterProposals();
+                        return true;
+
+                    case DWT.ARROW_UP :
+                        newSelection -= 1;
+                        if (newSelection < 0)
+                            newSelection= fProposalTable.getItemCount() - 1;
+                        break;
+
+                    case DWT.ARROW_DOWN :
+                        newSelection += 1;
+                        if (newSelection > fProposalTable.getItemCount() - 1)
+                            newSelection= 0;
+                        break;
+
+                    case DWT.PAGE_DOWN :
+                        newSelection += visibleRows;
+                        if (newSelection >= fProposalTable.getItemCount())
+                            newSelection= fProposalTable.getItemCount() - 1;
+                        break;
+
+                    case DWT.PAGE_UP :
+                        newSelection -= visibleRows;
+                        if (newSelection < 0)
+                            newSelection= 0;
+                        break;
+
+                    case DWT.HOME :
+                        newSelection= 0;
+                        break;
+
+                    case DWT.END :
+                        newSelection= fProposalTable.getItemCount() - 1;
+                        break;
+
+                    default :
+                        if (e.keyCode !is DWT.MOD1 && e.keyCode !is DWT.MOD2 && e.keyCode !is DWT.MOD3 && e.keyCode !is DWT.MOD4)
+                            hide();
+                        return true;
+                }
+
+                selectProposal(newSelection, smartToggle);
+
+                e.doit= false;
+                return false;
+
+            }
+
+            // key !is 0
+            switch (key) {
+                case 0x1B: // Esc
+                    e.doit= false;
+                    hide();
+                    break;
+
+                case '\n': // Ctrl-Enter on w2k
+                case '\r': // Enter
+                    if ((e.stateMask & DWT.CTRL) is 0) {
+                        e.doit= false;
+                        selectProposalWithMask(e.stateMask);
+                    }
+                    break;
+
+                    // in linked mode: hide popup
+                    // plus: don't invalidate the event in order to give LinkedUI a chance to handle it
+                case '\t':
+//                  hide();
+                    break;
+
+                default:
+                    ICompletionProposal p= getSelectedProposal();
+                if ( cast(ICompletionProposalExtension)p ) {
+                    ICompletionProposalExtension t= cast(ICompletionProposalExtension) p;
+                    char[] triggers= t.getTriggerCharacters();
+                    if (contains(triggers, key)) {
+                        hide();
+                        if (key is ';') {
+                            e.doit= true;
+                            insertProposal(p, cast(wchar) 0, e.stateMask, fViewer.getSelectedRange().x);
+                        } else {
+                            e.doit= false;
+                            insertProposal(p, key, e.stateMask, fViewer.getSelectedRange().x);
+                        }
+                    }
+                }
+            }
+
+            return true;
+        }
+
+    /**
+     * Selects the entry with the given index in the proposal selector and feeds
+     * the selection to the additional info controller.
+     *
+     * @param index the index in the list
+     * @param smartToggle <code>true</code> if the smart toogle key has been pressed
+     * @since 2.1
+     */
+    private void selectProposal(int index, bool smartToggle) {
+
+        ICompletionProposal oldProposal= getSelectedProposal();
+        if ( cast(ICompletionProposalExtension2)oldProposal )
+            (cast(ICompletionProposalExtension2) oldProposal).unselected(fViewer);
+
+        ICompletionProposal proposal= fFilteredProposals[index];
+        if ( cast(ICompletionProposalExtension2)proposal )
+            (cast(ICompletionProposalExtension2) proposal).selected(fViewer, smartToggle);
+
+        fLastProposal= proposal;
+
+        fProposalTable.setSelection(index);
+        fProposalTable.showSelection();
+        if (fAdditionalInfoController !is null)
+            fAdditionalInfoController.handleTableSelectionChanged();
+    }
+
+    /**
+     * Returns whether the given character is contained in the given array of
+     * characters.
+     *
+     * @param characters the list of characters
+     * @param c the character to look for in the list
+     * @return <code>true</code> if character belongs to the list
+     * @since 2.0
+     */
+    private bool contains(char[] characters, char c) {
+
+        if (characters is null)
+            return false;
+
+        for (int i= 0; i < characters.length; i++) {
+            if (c is characters[i])
+                return true;
+        }
+
+        return false;
+    }
+
+    /*
+     * @see IEventConsumer#processEvent(VerifyEvent)
+     */
+    public void processEvent(VerifyEvent e) {
+    }
+
+    /**
+     * Filters the displayed proposal based on the given cursor position and the
+     * offset of the original invocation of the content assistant.
+     */
+    private void filterProposals() {
+        ++ fInvocationCounter;
+        Control control= fViewer.getTextWidget();
+        control.getDisplay().asyncExec(dgRunnable( (long fInvocationCounter_) {
+            long fCounter= fInvocationCounter_;
+
+            if (fCounter !is fInvocationCounter) return;
+
+            int offset= fViewer.getSelectedRange().x;
+            ICompletionProposal[] proposals= null;
+            try  {
+                if (offset > -1) {
+                    DocumentEvent event= TextUtilities.mergeProcessedDocumentEvents(fDocumentEvents);
+                    proposals= computeFilteredProposals(offset, event);
+                }
+            } catch (BadLocationException x)  {
+            } finally  {
+                fDocumentEvents.clear();
+            }
+            fFilterOffset= offset;
+
+            if (proposals !is null && proposals.length > 0)
+                setProposals(proposals);
+            else
+                hide();
+        }, fInvocationCounter));
+    }
+
+    /**
+     * Computes the subset of already computed propsals that are still valid for
+     * the given offset.
+     *
+     * @param offset the offset
+     * @param event the merged document event
+     * @return the set of filtered proposals
+     * @since 2.0
+     */
+    private ICompletionProposal[] computeFilteredProposals(int offset, DocumentEvent event) {
+
+        if (offset is fInvocationOffset && event is null)
+            return fComputedProposals;
+
+        if (offset < fInvocationOffset) {
+            return null;
+        }
+
+        ICompletionProposal[] proposals= fComputedProposals;
+        if (offset > fFilterOffset)
+            proposals= fFilteredProposals;
+
+        if (proposals is null)
+            return null;
+
+        IDocument document= fViewer.getDocument();
+        int length= proposals.length;
+        List filtered= new ArrayList(length);
+        for (int i= 0; i < length; i++) {
+
+            if (cast(ICompletionProposalExtension2)proposals[i] ) {
+
+                ICompletionProposalExtension2 p= cast(ICompletionProposalExtension2) proposals[i];
+                if (p.validate(document, offset, event))
+                    filtered.add(cast(Object)p);
+
+            } else if (cast(ICompletionProposalExtension)proposals[i] ) {
+
+                ICompletionProposalExtension p= cast(ICompletionProposalExtension) proposals[i];
+                if (p.isValidFor(document, offset))
+                    filtered.add(cast(Object)p);
+
+            } else {
+                // restore original behavior
+                fInvocationOffset= offset;
+                fComputedProposals= computeProposals(fInvocationOffset);
+                return fComputedProposals;
+            }
+        }
+
+        return arraycast!(ICompletionProposal)(filtered.toArray());
+    }
+
+    /**
+     * Requests the proposal shell to take focus.
+     *
+     * @since 3.0
+     */
+    public void setFocus() {
+        if (Helper2.okToUse(fProposalShell))
+            fProposalShell.setFocus();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/link/contentassist/ContentAssistMessages.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.link.contentassist.ContentAssistMessages;
+
+
+import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport
+import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport
+import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwt.dwthelper.ResourceBundle;
+import dwtx.dwtxhelper.MessageFormat;
+
+
+/**
+ * Helper class to get NLSed messages.
+ *
+ * @since 3.0
+ */
+class ContentAssistMessages {
+
+//     private static const String RESOURCE_BUNDLE= ContentAssistMessages.classinfo.getName();
+
+    private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+    static this() {
+        fgResourceBundle = ResourceBundle.getBundle(
+            getImportData!("dwtx.jface.internal.text.link.contentassist.ContentAssistMessages.properties"));
+    }
+
+    private this() {
+    }
+
+    /**
+     * Gets a string from the resource bundle.
+     *
+     * @param key the string used to get the bundle value, must not be null
+     * @return the string from the resource bundle
+     */
+    public static String getString(String key) {
+        try {
+            return fgResourceBundle.getString(key);
+        } catch (MissingResourceException e) {
+            return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Gets a string from the resource bundle and formats it with the given arguments.
+     *
+     * @param key the string used to get the bundle value, must not be null
+     * @param args the arguments used to format the string
+     * @return the formatted string
+     */
+    public static String getFormattedString(String key, Object[] args... ) {
+        String format= null;
+        try {
+            format= fgResourceBundle.getString(key);
+        } catch (MissingResourceException e) {
+            return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$
+        }
+        return MessageFormat.format(format, args);
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/link/contentassist/ContentAssistant2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1603 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.link.contentassist.ContentAssistant2;
+
+import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport
+import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport
+import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport
+import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.core.Thread;
+
+import dwt.DWT;
+import dwt.DWTError;
+import dwt.custom.StyledText;
+import dwt.custom.VerifyKeyListener;
+import dwt.events.ControlEvent;
+import dwt.events.ControlListener;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.FocusEvent;
+import dwt.events.FocusListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.events.VerifyEvent;
+import dwt.graphics.Color;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwt.widgets.Shell;
+import dwt.widgets.Widget;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.DefaultInformationControl;
+import dwtx.jface.text.IEventConsumer;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension;
+import dwtx.jface.text.IViewportListener;
+import dwtx.jface.text.IWidgetTokenKeeper;
+import dwtx.jface.text.IWidgetTokenKeeperExtension;
+import dwtx.jface.text.IWidgetTokenOwner;
+import dwtx.jface.text.IWidgetTokenOwnerExtension;
+import dwtx.jface.text.TextUtilities;
+import dwtx.jface.text.contentassist.CompletionProposal;
+import dwtx.jface.text.contentassist.ICompletionProposal;
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6;
+import dwtx.jface.text.contentassist.IContentAssistProcessor;
+import dwtx.jface.text.contentassist.IContentAssistant;
+import dwtx.jface.text.contentassist.IContentAssistantExtension;
+import dwtx.jface.text.contentassist.IContextInformation;
+import dwtx.jface.text.contentassist.IContextInformationPresenter;
+import dwtx.jface.text.contentassist.IContextInformationValidator;
+
+
+/**
+ * A custom implementation of the <code>IContentAssistant</code> interface.
+ * This implementation is used by the linked mode UI. This is internal and subject
+ * to change without notice.
+ */
+public class ContentAssistant2 : IContentAssistant, IContentAssistantExtension, IWidgetTokenKeeper, IWidgetTokenKeeperExtension {
+
+    /**
+     * A generic closer class used to monitor various
+     * interface events in order to determine whether
+     * content-assist should be terminated and all
+     * associated windows closed.
+     */
+    class Closer : ControlListener, MouseListener, FocusListener, DisposeListener, IViewportListener {
+
+        /** The shell on which we add listeners. */
+        private Shell fShell;
+        private long fViewportListenerStartTime;
+
+        /**
+         * Installs this closer on it's viewer's text widget.
+         */
+        protected void install() {
+            Control w= fViewer.getTextWidget();
+            if (Helper2.okToUse(w)) {
+
+                Shell shell= w.getShell();
+                fShell= shell;
+                shell.addControlListener(this);
+
+                w.addMouseListener(this);
+                w.addFocusListener(this);
+
+                /*
+                 * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of Internal Errors
+                 */
+                w.addDisposeListener(this);
+            }
+
+            fViewer.addViewportListener(this);
+            fViewportListenerStartTime= System.currentTimeMillis() + 500;
+        }
+
+        /**
+         * Uninstalls this closer from the viewer's text widget.
+         */
+        protected void uninstall() {
+            Shell shell= fShell;
+            fShell= null;
+            if (Helper2.okToUse(shell))
+                shell.removeControlListener(this);
+
+            Control w= fViewer.getTextWidget();
+            if (Helper2.okToUse(w)) {
+
+                w.removeMouseListener(this);
+                w.removeFocusListener(this);
+
+                /*
+                 * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of Internal Errors
+                 */
+                w.removeDisposeListener(this);
+            }
+
+            fViewer.removeViewportListener(this);
+        }
+
+        /*
+         * @see ControlListener#controlResized(ControlEvent)
+         */
+        public void controlResized(ControlEvent e) {
+            hide();
+        }
+
+        /*
+         * @see ControlListener#controlMoved(ControlEvent)
+         */
+        public void controlMoved(ControlEvent e) {
+            hide();
+        }
+
+        /*
+         * @see MouseListener#mouseDown(MouseEvent)
+         */
+        public void mouseDown(MouseEvent e) {
+            hide();
+        }
+
+        /*
+         * @see MouseListener#mouseUp(MouseEvent)
+         */
+        public void mouseUp(MouseEvent e) {
+        }
+
+        /*
+         * @see MouseListener#mouseDoubleClick(MouseEvent)
+         */
+        public void mouseDoubleClick(MouseEvent e) {
+            hide();
+        }
+
+        /*
+         * @see FocusListener#focusGained(FocusEvent)
+         */
+        public void focusGained(FocusEvent e) {
+        }
+
+        /*
+         * @see FocusListener#focusLost(FocusEvent)
+         */
+        public void focusLost(FocusEvent e) {
+            if (fViewer !is null) {
+                Control control= fViewer.getTextWidget();
+                if (control !is null) {
+                    Display d= control.getDisplay();
+                    if (d !is null) {
+                        d.asyncExec(new class()  Runnable {
+                            public void run() {
+                                if (!hasFocus())
+                                    hide();
+                            }
+                        });
+                    }
+                }
+            }
+        }
+
+        /*
+         * @seeDisposeListener#widgetDisposed(DisposeEvent)
+         */
+        public void widgetDisposed(DisposeEvent e) {
+            /*
+             * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of Internal Errors
+             */
+            hide();
+        }
+
+        /*
+         * @see IViewportListener#viewportChanged(int)
+         */
+        public void viewportChanged(int topIndex) {
+            if (System.currentTimeMillis() > fViewportListenerStartTime)
+                hide();
+        }
+    }
+
+    /**
+     * An implementation of <code>IContentAssistListener</code>, this class is
+     * used to monitor key events in support of automatic activation
+     * of the content assistant. If enabled, the implementation utilizes a
+     * thread to watch for input characters matching the activation
+     * characters specified by the content assist processor, and if
+     * detected, will wait the indicated delay interval before
+     * activating the content assistant.
+     */
+    class AutoAssistListener : VerifyKeyListener, Runnable {
+
+        private Thread fThread;
+        private bool fIsReset= false;
+        private Object fMutex= new Object();
+        private int fShowStyle;
+
+        private const static int SHOW_PROPOSALS= 1;
+        private const static int SHOW_CONTEXT_INFO= 2;
+
+        protected this() {
+        }
+
+        protected void start(int showStyle) {
+            fShowStyle= showStyle;
+            fThread= new Thread(&run);
+            fThread.name = ContentAssistMessages.getString("ContentAssistant.assist_delay_timer_name"); //$NON-NLS-1$
+            fThread.start();
+        }
+
+        public void run() {
+            try {
+                while (true) {
+                    synchronized (fMutex) {
+                        if (fAutoActivationDelay !is 0)
+                            fMutex.wait(fAutoActivationDelay);
+                        if (fIsReset) {
+                            fIsReset= false;
+                            continue;
+                        }
+                    }
+                    showAssist(fShowStyle);
+                    break;
+                }
+            } catch (InterruptedException e) {
+            }
+            fThread= null;
+        }
+
+        protected void reset(int showStyle) {
+            synchronized (fMutex) {
+                fShowStyle= showStyle;
+                fIsReset= true;
+                fMutex.notifyAll();
+            }
+        }
+
+        protected void stop() {
+            Thread threadToStop= fThread;
+            if (threadToStop !is null)
+                threadToStop.interrupt();
+        }
+
+        private bool contains(char[] characters, char character) {
+            if (characters !is null) {
+                for (int i= 0; i < characters.length; i++) {
+                    if (character is characters[i])
+                        return true;
+                }
+            }
+            return false;
+        }
+
+        public void verifyKey(VerifyEvent e) {
+            // Only act on typed characters and ignore modifier-only events
+            if (e.character is 0 && (e.keyCode & DWT.KEYCODE_BIT) is 0)
+                return;
+
+            if (e.character !is 0 && (e.stateMask is DWT.ALT))
+                return;
+
+            int showStyle;
+            int pos= fViewer.getSelectedRange().x;
+            char[] activation= getCompletionProposalAutoActivationCharacters(fViewer, pos);
+
+            if (contains(activation, e.character) && !fProposalPopup.isActive())
+                showStyle= SHOW_PROPOSALS;
+            else {
+                activation= getContextInformationAutoActivationCharacters(fViewer, pos);
+                if (contains(activation, e.character) && !fContextInfoPopup.isActive())
+                    showStyle= SHOW_CONTEXT_INFO;
+                else {
+                    if (fThread !is null && fThread.isAlive())
+                        stop();
+                    return;
+                }
+            }
+
+            if (fThread !is null && fThread.isAlive())
+                reset(showStyle);
+            else
+                start(showStyle);
+        }
+
+        protected void showAssist(int showStyle) {
+            Control control= fViewer.getTextWidget();
+            Display d= control.getDisplay();
+            if (d !is null) {
+                try {
+                    d.syncExec(new class()  Runnable {
+                        public void run() {
+                            if (showStyle is SHOW_PROPOSALS)
+                                fProposalPopup.showProposals(true);
+                            else if (showStyle is SHOW_CONTEXT_INFO)
+                                fContextInfoPopup.showContextProposals(true);
+                        }
+                    });
+                } catch (DWTError e) {
+                }
+            }
+        }
+    }
+
+    /**
+     * The layout manager layouts the various
+     * windows associated with the content assistant based on the
+     * settings of the content assistant.
+     */
+    class LayoutManager : Listener {
+
+        // Presentation types.
+        /** proposal selector */
+        public const static int LAYOUT_PROPOSAL_SELECTOR= 0;
+        /** context selector */
+        public const static int LAYOUT_CONTEXT_SELECTOR= 1;
+        /** context info */
+        public const static int LAYOUT_CONTEXT_INFO_POPUP= 2;
+
+        int fContextType= LAYOUT_CONTEXT_SELECTOR;
+        Shell[] fShells= new Shell[3];
+        Object[] fPopups= new Object[3];
+
+        protected void add(Object popup, Shell shell, int type, int offset) {
+            Assert.isNotNull(popup);
+            Assert.isTrue(shell !is null && !shell.isDisposed());
+            checkType(type);
+
+            if (fShells[type] !is shell) {
+                if (fShells[type] !is null)
+                    fShells[type].removeListener(DWT.Dispose, this);
+                shell.addListener(DWT.Dispose, this);
+                fShells[type]= shell;
+            }
+
+            fPopups[type]= popup;
+            if (type is LAYOUT_CONTEXT_SELECTOR || type is LAYOUT_CONTEXT_INFO_POPUP)
+                fContextType= type;
+
+            layout(type, offset);
+            adjustListeners(type);
+        }
+
+        protected void checkType(int type) {
+            Assert.isTrue(type is LAYOUT_PROPOSAL_SELECTOR ||
+                type is LAYOUT_CONTEXT_SELECTOR || type is LAYOUT_CONTEXT_INFO_POPUP);
+        }
+
+        public void handleEvent(Event event) {
+            Widget source= event.widget;
+            source.removeListener(DWT.Dispose, this);
+
+            int type= getShellType(source);
+            checkType(type);
+            fShells[type]= null;
+
+            switch (type) {
+                case LAYOUT_PROPOSAL_SELECTOR:
+                    if (fContextType is LAYOUT_CONTEXT_SELECTOR &&
+                            Helper2.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR])) {
+                        // Restore event notification to the tip popup.
+                        addContentAssistListener(cast(IContentAssistListener2) fPopups[LAYOUT_CONTEXT_SELECTOR], CONTEXT_SELECTOR);
+                    }
+                    break;
+
+                case LAYOUT_CONTEXT_SELECTOR:
+                    if (Helper2.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
+                        if (fProposalPopupOrientation is PROPOSAL_STACKED)
+                            layout(LAYOUT_PROPOSAL_SELECTOR, getSelectionOffset());
+                        // Restore event notification to the proposal popup.
+                        addContentAssistListener(cast(IContentAssistListener2) fPopups[LAYOUT_PROPOSAL_SELECTOR], PROPOSAL_SELECTOR);
+                    }
+                    fContextType= LAYOUT_CONTEXT_INFO_POPUP;
+                    break;
+
+                case LAYOUT_CONTEXT_INFO_POPUP:
+                    if (Helper2.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
+                        if (fContextInfoPopupOrientation is CONTEXT_INFO_BELOW)
+                            layout(LAYOUT_PROPOSAL_SELECTOR, getSelectionOffset());
+                    }
+                    fContextType= LAYOUT_CONTEXT_SELECTOR;
+                    break;
+            }
+        }
+
+        protected int getShellType(Widget shell) {
+            for (int i=0; i<fShells.length; i++) {
+                if (fShells[i] is shell)
+                    return i;
+            }
+            return -1;
+        }
+
+        protected void layout(int type, int offset) {
+            switch (type) {
+                case LAYOUT_PROPOSAL_SELECTOR:
+                    layoutProposalSelector(offset);
+                    break;
+                case LAYOUT_CONTEXT_SELECTOR:
+                    layoutContextSelector(offset);
+                    break;
+                case LAYOUT_CONTEXT_INFO_POPUP:
+                    layoutContextInfoPopup(offset);
+                    break;
+            }
+        }
+
+        protected void layoutProposalSelector(int offset) {
+            if (fContextType is LAYOUT_CONTEXT_INFO_POPUP &&
+                    fContextInfoPopupOrientation is CONTEXT_INFO_BELOW &&
+                    Helper2.okToUse(fShells[LAYOUT_CONTEXT_INFO_POPUP])) {
+                // Stack proposal selector beneath the tip box.
+                Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                Shell parent= fShells[LAYOUT_CONTEXT_INFO_POPUP];
+                shell.setLocation(getStackedLocation(shell, parent));
+            } else if (fContextType !is LAYOUT_CONTEXT_SELECTOR ||
+                        !Helper2.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR])) {
+                // There are no other presentations to be concerned with,
+                // so place the proposal selector beneath the cursor line.
+                Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                shell.setLocation(getBelowLocation(shell, offset));
+            } else {
+                switch (fProposalPopupOrientation) {
+                    case PROPOSAL_REMOVE: {
+                        // Remove the tip selector and place the
+                        // proposal selector beneath the cursor line.
+                        fShells[LAYOUT_CONTEXT_SELECTOR].dispose();
+                        Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                        shell.setLocation(getBelowLocation(shell, offset));
+                        break;
+                    }
+                    case PROPOSAL_OVERLAY: {
+                        // Overlay the tip selector with the proposal selector.
+                        Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                        shell.setLocation(getBelowLocation(shell, offset));
+                        break;
+                    }
+                    case PROPOSAL_STACKED: {
+                        // Stack the proposal selector beneath the tip selector.
+                        Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                        Shell parent= fShells[LAYOUT_CONTEXT_SELECTOR];
+                        shell.setLocation(getStackedLocation(shell, parent));
+                        break;
+                    }
+                }
+            }
+        }
+
+        protected void layoutContextSelector(int offset) {
+            // Always place the context selector beneath the cursor line.
+            Shell shell= fShells[LAYOUT_CONTEXT_SELECTOR];
+            shell.setLocation(getBelowLocation(shell, offset));
+
+            if (Helper2.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
+                switch (fProposalPopupOrientation) {
+                    case PROPOSAL_REMOVE:
+                        // Remove the proposal selector.
+                        fShells[LAYOUT_PROPOSAL_SELECTOR].dispose();
+                        break;
+
+                    case PROPOSAL_OVERLAY:
+                        // The proposal selector has been overlaid by the tip selector.
+                        break;
+
+                    case PROPOSAL_STACKED: {
+                        // Stack the proposal selector beneath the tip selector.
+                        shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                        Shell parent= fShells[LAYOUT_CONTEXT_SELECTOR];
+                        shell.setLocation(getStackedLocation(shell, parent));
+                        break;
+                    }
+                }
+            }
+        }
+
+        protected void layoutContextInfoPopup(int offset) {
+            switch (fContextInfoPopupOrientation) {
+                case CONTEXT_INFO_ABOVE: {
+                    // Place the popup above the cursor line.
+                    Shell shell= fShells[LAYOUT_CONTEXT_INFO_POPUP];
+                    shell.setLocation(getAboveLocation(shell, offset));
+                    break;
+                }
+                case CONTEXT_INFO_BELOW: {
+                    // Place the popup beneath the cursor line.
+                    Shell parent= fShells[LAYOUT_CONTEXT_INFO_POPUP];
+                    parent.setLocation(getBelowLocation(parent, offset));
+                    if (Helper2.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
+                        // Stack the proposal selector beneath the context info popup.
+                        Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                        shell.setLocation(getStackedLocation(shell, parent));
+                    }
+                    break;
+                }
+            }
+        }
+
+        protected void shiftHorizontalLocation(Point location, Rectangle shellBounds, Rectangle displayBounds) {
+            if (location.x + shellBounds.width > displayBounds.width)
+                location.x= displayBounds.width - shellBounds.width;
+
+            if (location.x < displayBounds.x)
+                location.x= displayBounds.x;
+        }
+
+        protected void shiftVerticalLocation(Point location, Rectangle shellBounds, Rectangle displayBounds) {
+            if (location.y + shellBounds.height > displayBounds.height)
+                location.y= displayBounds.height - shellBounds.height;
+
+            if (location.y < displayBounds.y)
+                location.y= displayBounds.y;
+        }
+
+        protected Point getAboveLocation(Shell shell, int offset) {
+            StyledText text= fViewer.getTextWidget();
+            Point location= text.getLocationAtOffset(offset);
+            location= text.toDisplay(location);
+
+            Rectangle shellBounds= shell.getBounds();
+            Rectangle displayBounds= shell.getDisplay().getClientArea();
+
+            location.y=location.y - shellBounds.height;
+
+            shiftHorizontalLocation(location, shellBounds, displayBounds);
+            shiftVerticalLocation(location, shellBounds, displayBounds);
+
+            return location;
+        }
+
+        protected Point getBelowLocation(Shell shell, int offset) {
+            StyledText text= fViewer.getTextWidget();
+            Point location= text.getLocationAtOffset(offset);
+            if (location.x < 0) location.x= 0;
+            if (location.y < 0) location.y= 0;
+            location= text.toDisplay(location);
+
+            Rectangle shellBounds= shell.getBounds();
+            Rectangle displayBounds= shell.getDisplay().getClientArea();
+
+            location.y= location.y + text.getLineHeight(offset);
+            shiftHorizontalLocation(location, shellBounds, displayBounds);
+            shiftVerticalLocation(location, shellBounds, displayBounds);
+
+            return location;
+        }
+
+        protected Point getStackedLocation(Shell shell, Shell parent) {
+            Point p= parent.getLocation();
+            Point size= parent.getSize();
+            p.x += size.x / 4;
+            p.y += size.y;
+
+            p= parent.toDisplay(p);
+
+            Rectangle shellBounds= shell.getBounds();
+            Rectangle displayBounds= shell.getDisplay().getClientArea();
+            shiftHorizontalLocation(p, shellBounds, displayBounds);
+            shiftVerticalLocation(p, shellBounds, displayBounds);
+
+            return p;
+        }
+
+        protected void adjustListeners(int type) {
+            switch (type) {
+                case LAYOUT_PROPOSAL_SELECTOR:
+                    if (fContextType is LAYOUT_CONTEXT_SELECTOR &&
+                            Helper2.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR]))
+                        // Disable event notification to the tip selector.
+                        removeContentAssistListener(cast(IContentAssistListener2) fPopups[LAYOUT_CONTEXT_SELECTOR], CONTEXT_SELECTOR);
+                    break;
+                case LAYOUT_CONTEXT_SELECTOR:
+                    if (Helper2.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR]))
+                        // Disable event notification to the proposal selector.
+                        removeContentAssistListener(cast(IContentAssistListener2) fPopups[LAYOUT_PROPOSAL_SELECTOR], PROPOSAL_SELECTOR);
+                    break;
+                case LAYOUT_CONTEXT_INFO_POPUP:
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Internal key listener and event consumer.
+     */
+    class InternalListener : VerifyKeyListener, IEventConsumer {
+
+        /**
+         * Verifies key events by notifying the registered listeners.
+         * Each listener is allowed to indicate that the event has been
+         * handled and should not be further processed.
+         *
+         * @param e the verify event
+         * @see VerifyKeyListener#verifyKey(dwt.events.VerifyEvent)
+         */
+        public void verifyKey(VerifyEvent e) {
+            IContentAssistListener2[] listeners= arraycast!(IContentAssistListener2)( fListeners.clone());
+            for (int i= 0; i < listeners.length; i++) {
+                if (listeners[i] !is null) {
+                    if (!listeners[i].verifyKey(e) || !e.doit)
+                        return;
+                }
+            }
+        }
+
+        /*
+         * @see IEventConsumer#processEvent
+         */
+        public void processEvent(VerifyEvent event) {
+
+            installKeyListener();
+
+            IContentAssistListener2[] listeners= arraycast!(IContentAssistListener2)(fListeners.clone());
+            for (int i= 0; i < listeners.length; i++) {
+                if (listeners[i] !is null) {
+                    listeners[i].processEvent(event);
+                    if (!event.doit)
+                        return;
+                }
+            }
+        }
+    }
+
+
+    // Content-Assist Listener types
+    final static int CONTEXT_SELECTOR= 0;
+    final static int PROPOSAL_SELECTOR= 1;
+    final static int CONTEXT_INFO_POPUP= 2;
+
+    /**
+     * The popup priority: &gt; info pop-ups, &lt; standard content assist.
+     * Default value: <code>10</code>.
+     *
+     * @since 3.0
+     */
+    public static const int WIDGET_PRIORITY= 10;
+
+
+    private static const int DEFAULT_AUTO_ACTIVATION_DELAY= 500;
+
+    private IInformationControlCreator fInformationControlCreator;
+    private int fAutoActivationDelay= DEFAULT_AUTO_ACTIVATION_DELAY;
+    private bool fIsAutoActivated= false;
+    private bool fIsAutoInserting= false;
+    private int fProposalPopupOrientation= PROPOSAL_OVERLAY;
+    private int fContextInfoPopupOrientation= CONTEXT_INFO_ABOVE;
+    private Map fProcessors;
+    private String fPartitioning;
+
+    private Color fContextInfoPopupBackground;
+    private Color fContextInfoPopupForeground;
+    private Color fContextSelectorBackground;
+    private Color fContextSelectorForeground;
+
+    private ITextViewer fViewer;
+    private String fLastErrorMessage;
+
+    private Closer fCloser;
+    private LayoutManager fLayoutManager;
+    private AutoAssistListener fAutoAssistListener;
+    private InternalListener fInternalListener;
+    private CompletionProposalPopup2 fProposalPopup;
+    private ContextInformationPopup2 fContextInfoPopup;
+
+    private bool fKeyListenerHooked= false;
+    private IContentAssistListener2[] fListeners= new IContentAssistListener2[4];
+    private int fCompletionPosition;
+    private String[] fProposalStrings;
+    private ICompletionProposal[] fProposals;
+    private const List fProposalListeners= new ArrayList();
+
+    /**
+     * Tells whether colored label support is enabled.
+     * @since 3.4
+     */
+    private bool fIsColoredLabelsSupportEnabled= false;
+
+
+    /**
+     * Creates a new content assistant. The content assistant is not automatically activated,
+     * overlays the completion proposals with context information list if necessary, and
+     * shows the context information above the location at which it was activated. If auto
+     * activation will be enabled, without further configuration steps, this content assistant
+     * is activated after a 500 ms delay. It uses the default partitioning.
+     */
+    public this() {
+        setContextInformationPopupOrientation(CONTEXT_INFO_ABOVE);
+        setInformationControlCreator(getInformationControlCreator());
+
+//      JavaTextTools textTools= JavaPlugin.getDefault().getJavaTextTools();
+//      IColorManager manager= textTools.getColorManager();
+//
+//      IPreferenceStore store=  JavaPlugin.getDefault().getPreferenceStore();
+//
+//      Color c= getColor(store, PreferenceConstants.CODEASSIST_PROPOSALS_FOREGROUND, manager);
+//      setProposalSelectorForeground(c);
+//
+//      c= getColor(store, PreferenceConstants.CODEASSIST_PROPOSALS_BACKGROUND, manager);
+//      setProposalSelectorBackground(c);
+    }
+
+    /**
+     * Creates an <code>IInformationControlCreator</code> to be used to display context information.
+     *
+     * @return an <code>IInformationControlCreator</code> to be used to display context information
+     */
+    private IInformationControlCreator getInformationControlCreator() {
+        return new class()  IInformationControlCreator {
+            public IInformationControl createInformationControl(Shell parent) {
+                return new DefaultInformationControl(parent, false);
+            }
+        };
+    }
+
+    /**
+     * Sets the document partitioning this content assistant is using.
+     *
+     * @param partitioning the document partitioning for this content assistant
+     */
+    public void setDocumentPartitioning(String partitioning) {
+        Assert.isNotNull(partitioning);
+        fPartitioning= partitioning;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistantExtension#getDocumentPartitioning()
+     * @since 3.0
+     */
+    public String getDocumentPartitioning() {
+        return fPartitioning;
+    }
+
+    /**
+     * Registers a given content assist processor for a particular content type.
+     * If there is already a processor registered for this type, the new processor
+     * is registered instead of the old one.
+     *
+     * @param processor the content assist processor to register, or <code>null</code> to remove an existing one
+     * @param contentType the content type under which to register
+     */
+     public void setContentAssistProcessor(IContentAssistProcessor processor, String contentType) {
+
+        Assert.isNotNull(contentType);
+
+        if (fProcessors is null)
+            fProcessors= new HashMap();
+
+        if (processor is null)
+            fProcessors.remove(contentType);
+        else
+            fProcessors.put(contentType, processor);
+    }
+
+    /*
+     * @see IContentAssistant#getContentAssistProcessor
+     */
+    public IContentAssistProcessor getContentAssistProcessor(String contentType) {
+        if (fProcessors is null)
+            return null;
+
+        return cast(IContentAssistProcessor) fProcessors.get(contentType);
+    }
+
+    /**
+     * Enables the content assistant's auto activation mode.
+     *
+     * @param enabled indicates whether auto activation is enabled or not
+     */
+    public void enableAutoActivation(bool enabled) {
+        fIsAutoActivated= enabled;
+        manageAutoActivation(fIsAutoActivated);
+    }
+
+    /**
+     * Enables the content assistant's auto insertion mode. If enabled,
+     * the content assistant inserts a proposal automatically if it is
+     * the only proposal. In the case of ambiguities, the user must
+     * make the choice.
+     *
+     * @param enabled indicates whether auto insertion is enabled or not
+     * @since 2.0
+     */
+    public void enableAutoInsert(bool enabled) {
+        fIsAutoInserting= enabled;
+    }
+
+    /**
+     * Returns whether this content assistant is in the auto insertion
+     * mode or not.
+     *
+     * @return <code>true</code> if in auto insertion mode
+     * @since 2.0
+     */
+    bool isAutoInserting() {
+        return fIsAutoInserting;
+    }
+
+    /**
+     * Installs and uninstall the listeners needed for auto-activation.
+     * @param start <code>true</code> if listeners must be installed,
+     *  <code>false</code> if they must be removed
+     * @since 2.0
+     */
+    private void manageAutoActivation(bool start) {
+        if (start) {
+
+            if (fViewer !is null && fAutoAssistListener is null) {
+                fAutoAssistListener= new AutoAssistListener();
+                if ( cast(ITextViewerExtension)fViewer ) {
+                    ITextViewerExtension extension= cast(ITextViewerExtension) fViewer;
+                    extension.appendVerifyKeyListener(fAutoAssistListener);
+                } else {
+                    StyledText textWidget= fViewer.getTextWidget();
+                    if (Helper2.okToUse(textWidget))
+                        textWidget.addVerifyKeyListener(fAutoAssistListener);
+                }
+            }
+
+        } else if (fAutoAssistListener !is null) {
+
+            if ( cast(ITextViewerExtension)fViewer ) {
+                ITextViewerExtension extension= cast(ITextViewerExtension) fViewer;
+                extension.removeVerifyKeyListener(fAutoAssistListener);
+            } else {
+                StyledText textWidget= fViewer.getTextWidget();
+                if (Helper2.okToUse(textWidget))
+                    textWidget.removeVerifyKeyListener(fAutoAssistListener);
+            }
+
+            fAutoAssistListener= null;
+        }
+    }
+
+    /**
+     * Sets the delay after which the content assistant is automatically invoked
+     * if the cursor is behind an auto activation character.
+     *
+     * @param delay the auto activation delay
+     */
+    public void setAutoActivationDelay(int delay) {
+        fAutoActivationDelay= delay;
+    }
+
+    /**
+     * Sets the proposal pop-ups' orientation.
+     * The following values may be used:
+     * <ul>
+     *   <li>PROPOSAL_OVERLAY<p>
+     *     proposal popup windows should overlay each other
+     *   </li>
+     *   <li>PROPOSAL_REMOVE<p>
+     *     any currently shown proposal popup should be closed
+     *   </li>
+     *   <li>PROPOSAL_STACKED<p>
+     *     proposal popup windows should be vertical stacked, with no overlap,
+     *     beneath the line containing the current cursor location
+     *   </li>
+     * </ul>
+     *
+     * @param orientation the popup's orientation
+     */
+    public void setProposalPopupOrientation(int orientation) {
+        fProposalPopupOrientation= orientation;
+    }
+
+    /**
+     * Sets the context information popup's orientation.
+     * The following values may be used:
+     * <ul>
+     *   <li>CONTEXT_ABOVE<p>
+     *     context information popup should always appear above the line containing
+     *     the current cursor location
+     *   </li>
+     *   <li>CONTEXT_BELOW<p>
+     *     context information popup should always appear below the line containing
+     *     the current cursor location
+     *   </li>
+     * </ul>
+     *
+     * @param orientation the popup's orientation
+     */
+    public void setContextInformationPopupOrientation(int orientation) {
+        fContextInfoPopupOrientation= orientation;
+    }
+
+    /**
+     * Sets the context information popup's background color.
+     *
+     * @param background the background color
+     */
+    public void setContextInformationPopupBackground(Color background) {
+        fContextInfoPopupBackground= background;
+    }
+
+    /**
+     * Returns the background of the context information popup.
+     *
+     * @return the background of the context information popup
+     * @since 2.0
+     */
+    Color getContextInformationPopupBackground() {
+        return fContextInfoPopupBackground;
+    }
+
+    /**
+     * Sets the context information popup's foreground color.
+     *
+     * @param foreground the foreground color
+     * @since 2.0
+     */
+    public void setContextInformationPopupForeground(Color foreground) {
+        fContextInfoPopupForeground= foreground;
+    }
+
+    /**
+     * Returns the foreground of the context information popup.
+     *
+     * @return the foreground of the context information popup
+     * @since 2.0
+     */
+    Color getContextInformationPopupForeground() {
+        return fContextInfoPopupForeground;
+    }
+
+    /**
+     * Sets the context selector's background color.
+     *
+     * @param background the background color
+     * @since 2.0
+     */
+    public void setContextSelectorBackground(Color background) {
+        fContextSelectorBackground= background;
+    }
+
+    /**
+     * Returns the background of the context selector.
+     *
+     * @return the background of the context selector
+     * @since 2.0
+     */
+    Color getContextSelectorBackground() {
+        return fContextSelectorBackground;
+    }
+
+    /**
+     * Sets the context selector's foreground color.
+     *
+     * @param foreground the foreground color
+     * @since 2.0
+     */
+    public void setContextSelectorForeground(Color foreground) {
+        fContextSelectorForeground= foreground;
+    }
+
+    /**
+     * Returns the foreground of the context selector.
+     *
+     * @return the foreground of the context selector
+     * @since 2.0
+     */
+    Color getContextSelectorForeground() {
+        return fContextSelectorForeground;
+    }
+
+    /**
+     * Sets the information control creator for the additional information control.
+     *
+     * @param creator the information control creator for the additional information control
+     * @since 2.0
+     */
+    public void setInformationControlCreator(IInformationControlCreator creator) {
+        fInformationControlCreator= creator;
+    }
+
+    /*
+     * @see IContentAssist#install
+     */
+    public void install(ITextViewer textViewer) {
+        Assert.isNotNull(textViewer);
+
+        fViewer= textViewer;
+
+        fLayoutManager= new LayoutManager();
+        fInternalListener= new InternalListener();
+
+        AdditionalInfoController2 controller= null;
+        if (fInformationControlCreator !is null) {
+            int delay= fAutoActivationDelay;
+            if (delay is 0)
+                delay= DEFAULT_AUTO_ACTIVATION_DELAY;
+            delay= Math.round(delay * 1.5f);
+            controller= new AdditionalInfoController2(fInformationControlCreator, delay);
+        }
+        fContextInfoPopup= new ContextInformationPopup2(this, fViewer);
+        fProposalPopup= new CompletionProposalPopup2(this, fViewer, controller);
+
+        manageAutoActivation(fIsAutoActivated);
+    }
+
+    /*
+     * @see IContentAssist#uninstall
+     */
+    public void uninstall() {
+
+        if (fProposalPopup !is null)
+            fProposalPopup.hide();
+
+        if (fContextInfoPopup !is null)
+            fContextInfoPopup.hide();
+
+        manageAutoActivation(false);
+
+        if (fCloser !is null) {
+            fCloser.uninstall();
+            fCloser= null;
+        }
+
+        fViewer= null;
+    }
+
+    /**
+     * Adds the given shell of the specified type to the layout.
+     * Valid types are defined by <code>LayoutManager</code>.
+     *
+     * @param popup a content assist popup
+     * @param shell the shell of the content-assist popup
+     * @param type the type of popup
+     * @param visibleOffset the offset at which to layout the popup relative to the offset of the viewer's visible region
+     * @since 2.0
+     */
+    void addToLayout(Object popup, Shell shell, int type, int visibleOffset) {
+        fLayoutManager.add(popup, shell, type, visibleOffset);
+    }
+
+    /**
+     * Layouts the registered popup of the given type relative to the
+     * given offset. The offset is relative to the offset of the viewer's visible region.
+     * Valid types are defined by <code>LayoutManager</code>.
+     *
+     * @param type the type of popup to layout
+     * @param visibleOffset the offset at which to layout relative to the offset of the viewer's visible region
+     * @since 2.0
+     */
+    void layout(int type, int visibleOffset) {
+        fLayoutManager.layout(type, visibleOffset);
+    }
+
+    /**
+     * Notifies the controller that a popup has lost focus.
+     *
+     * @param e the focus event
+     */
+    void popupFocusLost(FocusEvent e) {
+        fCloser.focusLost(e);
+    }
+
+    /**
+     * Returns the offset of the selection relative to the offset of the visible region.
+     *
+     * @return the offset of the selection relative to the offset of the visible region
+     * @since 2.0
+     */
+    int getSelectionOffset() {
+        StyledText text= fViewer.getTextWidget();
+        return text.getSelectionRange().x;
+    }
+
+    /**
+     * Returns whether the widget token could be acquired.
+     * The following are valid listener types:
+     * <ul>
+     *   <li>AUTO_ASSIST
+     *   <li>CONTEXT_SELECTOR
+     *   <li>PROPOSAL_SELECTOR
+     *   <li>CONTEXT_INFO_POPUP
+     * <ul>
+     * @param type the listener type for which to acquire
+     * @return <code>true</code> if the widget token could be acquired
+     * @since 2.0
+     */
+    private bool acquireWidgetToken(int type) {
+        switch (type) {
+            case CONTEXT_SELECTOR:
+            case PROPOSAL_SELECTOR:
+                if ( cast(IWidgetTokenOwner)fViewer ) {
+                    IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fViewer;
+                    return owner.requestWidgetToken(this);
+                } else if ( cast(IWidgetTokenOwnerExtension)fViewer )  {
+                    IWidgetTokenOwnerExtension extension= cast(IWidgetTokenOwnerExtension) fViewer;
+                    return extension.requestWidgetToken(this, WIDGET_PRIORITY);
+                }
+        }
+        return true;
+    }
+
+    /**
+     * Registers a content assist listener.
+     * The following are valid listener types:
+     * <ul>
+     *   <li>AUTO_ASSIST
+     *   <li>CONTEXT_SELECTOR
+     *   <li>PROPOSAL_SELECTOR
+     *   <li>CONTEXT_INFO_POPUP
+     * <ul>
+     * Returns whether the listener could be added successfully. A listener
+     * can not be added if the widget token could not be acquired.
+     *
+     * @param listener the listener to register
+     * @param type the type of listener
+     * @return <code>true</code> if the listener could be added
+     */
+    bool addContentAssistListener(IContentAssistListener2 listener, int type) {
+
+        if (acquireWidgetToken(type)) {
+
+            fListeners[type]= listener;
+
+            if (getNumberOfListeners() is 1) {
+                fCloser= new Closer();
+                fCloser.install();
+                fViewer.setEventConsumer(fInternalListener);
+                installKeyListener();
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Installs a key listener on the text viewer's widget.
+     */
+    private void installKeyListener() {
+        if (!fKeyListenerHooked) {
+            StyledText text= fViewer.getTextWidget();
+            if (Helper2.okToUse(text)) {
+
+                if ( cast(ITextViewerExtension)fViewer ) {
+                    ITextViewerExtension e= cast(ITextViewerExtension) fViewer;
+                    e.prependVerifyKeyListener(fInternalListener);
+                } else {
+                    text.addVerifyKeyListener(fInternalListener);
+                }
+
+                fKeyListenerHooked= true;
+            }
+        }
+    }
+
+    /**
+     * Releases the previously acquired widget token if the token
+     * is no longer necessary.
+     * The following are valid listener types:
+     * <ul>
+     *   <li>AUTO_ASSIST
+     *   <li>CONTEXT_SELECTOR
+     *   <li>PROPOSAL_SELECTOR
+     *   <li>CONTEXT_INFO_POPUP
+     * <ul>
+     *
+     * @param type the listener type
+     * @since 2.0
+     */
+    private void releaseWidgetToken(int type) {
+        if (fListeners[CONTEXT_SELECTOR] is null && fListeners[PROPOSAL_SELECTOR] is null) {
+            if ( cast(IWidgetTokenOwner)fViewer ) {
+                IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fViewer;
+                owner.releaseWidgetToken(this);
+            }
+        }
+    }
+
+    /**
+     * Unregisters a content assist listener.
+     *
+     * @param listener the listener to unregister
+     * @param type the type of listener
+     *
+     * @see #addContentAssistListener
+     */
+    void removeContentAssistListener(IContentAssistListener2 listener, int type) {
+        fListeners[type]= null;
+
+        if (getNumberOfListeners() is 0) {
+
+            if (fCloser !is null) {
+                fCloser.uninstall();
+                fCloser= null;
+            }
+
+            uninstallKeyListener();
+            fViewer.setEventConsumer(null);
+        }
+
+        releaseWidgetToken(type);
+    }
+
+    /**
+     * Uninstall the key listener from the text viewer's widget.
+     */
+    private void uninstallKeyListener() {
+        if (fKeyListenerHooked) {
+            StyledText text= fViewer.getTextWidget();
+            if (Helper2.okToUse(text)) {
+
+                if ( cast(ITextViewerExtension)fViewer ) {
+                    ITextViewerExtension e= cast(ITextViewerExtension) fViewer;
+                    e.removeVerifyKeyListener(fInternalListener);
+                } else {
+                    text.removeVerifyKeyListener(fInternalListener);
+                }
+
+                fKeyListenerHooked= false;
+            }
+        }
+    }
+
+    /**
+     * Returns the number of listeners.
+     *
+     * @return the number of listeners
+     * @since 2.0
+     */
+    private int getNumberOfListeners() {
+        int count= 0;
+        for (int i= 0; i <= CONTEXT_INFO_POPUP; i++) {
+            if (fListeners[i] !is null)
+                ++ count;
+        }
+        return count;
+    }
+
+    /*
+     * @see IContentAssist#showPossibleCompletions
+     */
+    public String showPossibleCompletions() {
+        return fProposalPopup.showProposals(false);
+    }
+
+    /**
+     * Hides the proposal popup.
+     */
+    public void hidePossibleCompletions() {
+        if (fProposalPopup !is null)
+            fProposalPopup.hide();
+    }
+
+    /**
+     * Hides any open pop-ups.
+     */
+    protected void hide() {
+        if (fProposalPopup !is null)
+            fProposalPopup.hide();
+        if (fContextInfoPopup !is null)
+            fContextInfoPopup.hide();
+    }
+    package void hide_package() {
+        hide();
+    }
+
+    /**
+     * Callback to signal this content assistant that the presentation of the possible completions has been stopped.
+     * @since 2.1
+     */
+    protected void possibleCompletionsClosed() {
+    }
+    package void possibleCompletionsClosed_package(){
+        possibleCompletionsClosed();
+    }
+    /*
+     * @see IContentAssist#showContextInformation
+     */
+    public String showContextInformation() {
+        return fContextInfoPopup.showContextProposals(false);
+    }
+
+
+    /**
+     * Callback to signal this content assistant that the presentation of the context information has been stopped.
+     * @since 2.1
+     */
+    protected void contextInformationClosed() {
+    }
+    package void contextInformationClosed_package() {
+        contextInformationClosed();
+    }
+
+    /**
+     * Requests that the specified context information to be shown.
+     *
+     * @param contextInformation the context information to be shown
+     * @param position the position to which the context information refers to
+     * @since 2.0
+     */
+    void showContextInformation(IContextInformation contextInformation, int position) {
+        fContextInfoPopup.showContextInformation(contextInformation, position);
+    }
+
+    /**
+     * Returns the current content assist error message.
+     *
+     * @return an error message or <code>null</code> if no error has occurred
+     */
+    String getErrorMessage() {
+        return fLastErrorMessage;
+    }
+
+    /**
+     * Returns the content assist processor for the content
+     * type of the specified document position.
+     *
+     * @param viewer the text viewer
+     * @param offset a offset within the document
+     * @return a content-assist processor or <code>null</code> if none exists
+     */
+    private IContentAssistProcessor getProcessor(ITextViewer viewer, int offset) {
+        try {
+            String type= TextUtilities.getContentType(viewer.getDocument(), getDocumentPartitioning(), offset, true);
+            return getContentAssistProcessor(type);
+        } catch (BadLocationException x) {
+        }
+        return null;
+    }
+
+    /**
+     * Returns an array of completion proposals computed based on
+     * the specified document position. The position is used to
+     * determine the appropriate content assist processor to invoke.
+     *
+     * @param viewer the viewer for which to compute the proposals
+     * @param position a document position
+     * @return an array of completion proposals
+     *
+     * @see IContentAssistProcessor#computeCompletionProposals
+     */
+    ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int position) {
+        if (fProposals !is null) {
+            return fProposals;
+        } else if (fProposalStrings !is null) {
+            ICompletionProposal[] result= new ICompletionProposal[fProposalStrings.length];
+            for (int i= 0; i < fProposalStrings.length; i++) {
+                result[i]= new CompletionProposal(fProposalStrings[i], position, fProposalStrings[i].length(), fProposalStrings[i].length());
+            }
+            return result;
+        } else return null;
+    }
+
+    /**
+     * Returns an array of context information objects computed based
+     * on the specified document position. The position is used to determine
+     * the appropriate content assist processor to invoke.
+     *
+     * @param viewer the viewer for which to compute the context information
+     * @param position a document position
+     * @return an array of context information objects
+     *
+     * @see IContentAssistProcessor#computeContextInformation
+     */
+    IContextInformation[] computeContextInformation(ITextViewer viewer, int position) {
+        fLastErrorMessage= null;
+
+        IContextInformation[] result= null;
+
+        IContentAssistProcessor p= getProcessor(viewer, position);
+        if (p !is null) {
+            result= p.computeContextInformation(viewer, position);
+            fLastErrorMessage= p.getErrorMessage();
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns the context information validator that should be used to
+     * determine when the currently displayed context information should
+     * be dismissed. The position is used to determine the appropriate
+     * content assist processor to invoke.
+     *
+     * @param textViewer the text viewer
+     * @param offset a document offset
+     * @return an validator
+     *
+     * @see IContentAssistProcessor#getContextInformationValidator
+     */
+    IContextInformationValidator getContextInformationValidator(ITextViewer textViewer, int offset) {
+        IContentAssistProcessor p= getProcessor(textViewer, offset);
+        return p !is null ? p.getContextInformationValidator() : null;
+    }
+
+    /**
+     * Returns the context information presenter that should be used to
+     * display context information. The position is used to determine the appropriate
+     * content assist processor to invoke.
+     *
+     * @param textViewer the text viewer
+     * @param offset a document offset
+     * @return a presenter
+     * @since 2.0
+     */
+    IContextInformationPresenter getContextInformationPresenter(ITextViewer textViewer, int offset) {
+        IContextInformationValidator validator= getContextInformationValidator(textViewer, offset);
+        if ( cast(IContextInformationPresenter)validator )
+            return cast(IContextInformationPresenter) validator;
+        return null;
+    }
+
+    /**
+     * Returns the characters which when typed by the user should automatically
+     * initiate proposing completions. The position is used to determine the
+     * appropriate content assist processor to invoke.
+     *
+     * @param textViewer the text viewer
+     * @param offset a document offset
+     * @return the auto activation characters
+     *
+     * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters
+     */
+    private char[] getCompletionProposalAutoActivationCharacters(ITextViewer textViewer, int offset) {
+        IContentAssistProcessor p= getProcessor(textViewer, offset);
+        return p !is null ? p.getCompletionProposalAutoActivationCharacters() : null;
+    }
+
+    /**
+     * Returns the characters which when typed by the user should automatically
+     * initiate the presentation of context information. The position is used
+     * to determine the appropriate content assist processor to invoke.
+     *
+     * @param textViewer the text viewer
+     * @param offset a document offset
+     * @return the auto activation characters
+     *
+     * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters
+     */
+    private char[] getContextInformationAutoActivationCharacters(ITextViewer textViewer, int offset) {
+        IContentAssistProcessor p= getProcessor(textViewer, offset);
+        return p !is null ? p.getContextInformationAutoActivationCharacters() : null;
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeper#requestWidgetToken(IWidgetTokenOwner)
+     * @since 2.0
+     */
+    public bool requestWidgetToken(IWidgetTokenOwner owner) {
+        hidePossibleCompletions();
+        return true;
+    }
+
+    /**
+     * @param completionPosition
+     */
+    public void setCompletionPosition(int completionPosition) {
+        fCompletionPosition= completionPosition;
+    }
+
+    /**
+     * @return the completion position
+     */
+    public int getCompletionPosition() {
+        return fCompletionPosition;
+    }
+
+    /**
+     * @param proposals
+     */
+    public void setCompletions(String[] proposals) {
+        fProposalStrings= proposals;
+    }
+
+    /**
+     * @param proposals
+     */
+    public void setCompletions(ICompletionProposal[] proposals) {
+        fProposals= proposals;
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeperExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner, int)
+     * @since 3.0
+     */
+    public bool requestWidgetToken(IWidgetTokenOwner owner, int priority) {
+        if (priority > WIDGET_PRIORITY) {
+            hidePossibleCompletions();
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeperExtension#setFocus(dwtx.jface.text.IWidgetTokenOwner)
+     * @since 3.0
+     */
+    public bool setFocus(IWidgetTokenOwner owner) {
+        if (fProposalPopup !is null) {
+            fProposalPopup.setFocus();
+            return fProposalPopup.hasFocus();
+        }
+        return false;
+    }
+
+    /**
+     * Returns whether any popups controlled by the receiver have the input focus.
+     *
+     * @return <code>true</code> if any of the managed popups have the focus, <code>false</code> otherwise
+     */
+    public bool hasFocus() {
+        return (fProposalPopup !is null && fProposalPopup.hasFocus())
+                || (fContextInfoPopup !is null && fContextInfoPopup.hasFocus());
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistantExtension#completePrefix()
+     */
+    public String completePrefix() {
+        return null;
+    }
+
+    /**
+     * @param proposal
+     */
+    public void fireProposalChosen(ICompletionProposal proposal) {
+        List list= new ArrayList(fProposalListeners);
+        for (Iterator it= list.iterator(); it.hasNext();) {
+            IProposalListener listener= cast(IProposalListener) it.next();
+            listener.proposalChosen(proposal);
+        }
+
+    }
+
+    /**
+     * @param listener
+     */
+    public void removeProposalListener(IProposalListener listener) {
+        fProposalListeners.remove(listener);
+    }
+
+    /**
+     * @param listener
+     */
+    public void addProposalListener(IProposalListener listener) {
+        fProposalListeners.add(listener);
+    }
+
+    /**
+     * Tells whether the support for colored labels is enabled.
+     *
+     * @return <code>true</code> if the support for colored labels is enabled, <code>false</code> otherwise
+     * @since 3.4
+     */
+    bool isColoredLabelsSupportEnabled() {
+        return fIsColoredLabelsSupportEnabled;
+    }
+
+    /**
+     * Enables the support for colored labels in the proposal popup.
+     * <p>Completion proposals can implement {@link ICompletionProposalExtension6}
+     * to provide colored proposal labels.</p>
+     *
+     * @param isEnabled if <code>true</code> the support for colored labels is enabled in the proposal popup
+     * @since 3.4
+     */
+    public void enableColoredLabels(bool isEnabled) {
+        fIsColoredLabelsSupportEnabled= isEnabled;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/link/contentassist/ContextInformationPopup2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,647 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2;
+
+import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport
+import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport
+import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport
+import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+import dwt.DWT;
+import dwt.custom.BusyIndicator;
+import dwt.custom.StyledText;
+import dwt.events.KeyEvent;
+import dwt.events.SelectionEvent;
+import dwt.events.SelectionListener;
+import dwt.events.VerifyEvent;
+import dwt.graphics.Color;
+import dwt.graphics.Point;
+import dwt.layout.GridData;
+import dwt.layout.GridLayout;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Shell;
+import dwt.widgets.Table;
+import dwt.widgets.TableItem;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.TextPresentation;
+import dwtx.jface.text.contentassist.IContextInformation;
+import dwtx.jface.text.contentassist.IContextInformationExtension;
+import dwtx.jface.text.contentassist.IContextInformationPresenter;
+import dwtx.jface.text.contentassist.IContextInformationValidator;
+
+
+/**
+ * This class is used to present context information to the user.
+ * If multiple contexts are valid at the current cursor location,
+ * a list is presented from which the user may choose one context.
+ * Once the user makes their choice, or if there was only a single
+ * possible context, the context information is shown in a tooltip like popup. <p>
+ * If the tooltip is visible and the user wants to see context information of
+ * a context embedded into the one for which context information is displayed,
+ * context information for the embedded context is shown. As soon as the
+ * cursor leaves the embedded context area, the context information for
+ * the embedding context is shown again.
+ *
+ * @see IContextInformation
+ * @see IContextInformationValidator
+ */
+class ContextInformationPopup2 : IContentAssistListener2 {
+
+
+
+    /**
+     * Represents the state necessary for embedding contexts.
+     * @since 2.0
+     */
+    static class ContextFrame {
+        public int fBeginOffset;
+        public int fOffset;
+        public int fVisibleOffset;
+        public IContextInformation fInformation;
+        public IContextInformationValidator fValidator;
+        public IContextInformationPresenter fPresenter;
+    }
+
+    private ITextViewer fViewer;
+    private ContentAssistant2 fContentAssistant;
+
+    private PopupCloser2 fPopupCloser;
+    private Shell fContextSelectorShell;
+    private Table fContextSelectorTable;
+    private IContextInformation[] fContextSelectorInput;
+    private String fLineDelimiter= null;
+
+    private Shell fContextInfoPopup;
+    private StyledText fContextInfoText;
+    private TextPresentation fTextPresentation;
+
+    private Stack fContextFrameStack;
+
+
+    /**
+     * Creates a new context information popup.
+     *
+     * @param contentAssistant the content assist for computing the context information
+     * @param viewer the viewer on top of which the context information is shown
+     */
+    public this(ContentAssistant2 contentAssistant, ITextViewer viewer) {
+        fPopupCloser= new PopupCloser2();
+        fContextFrameStack= new Stack();
+        fContentAssistant= contentAssistant;
+        fViewer= viewer;
+    }
+
+    /**
+     * Shows all possible contexts for the given cursor position of the viewer.
+     *
+     * @param autoActivated <code>true</code>  if auto activated
+     * @return  a potential error message or <code>null</code> in case of no error
+     */
+    public String showContextProposals(bool autoActivated) {
+        final StyledText styledText= fViewer.getTextWidget();
+        BusyIndicator.showWhile(styledText.getDisplay(), dgRunnable( (bool autoActivated_, StyledText styledText_ ) {
+            int position= fViewer.getSelectedRange().x;
+
+            IContextInformation[] contexts= computeContextInformation(position);
+            int count = (contexts is null ? 0 : contexts.length);
+            if (count is 1) {
+
+                // Show context information directly
+                internalShowContextInfo(contexts[0], position);
+
+            } else if (count > 0) {
+                // Precise context must be selected
+
+                if (fLineDelimiter is null)
+                    fLineDelimiter= styledText_.getLineDelimiter();
+
+                createContextSelector();
+                setContexts(contexts);
+                displayContextSelector();
+                hideContextInfoPopup();
+
+            } else if (!autoActivated_) {
+                styledText_.getDisplay().beep();
+            }
+        }, autoActivated, styledText ));
+
+        return getErrorMessage();
+    }
+
+    /**
+     * Displays the given context information for the given offset.
+     *
+     * @param info the context information
+     * @param position the offset
+     * @since 2.0
+     */
+    public void showContextInformation(IContextInformation info, int position) {
+        Control control= fViewer.getTextWidget();
+        BusyIndicator.showWhile(control.getDisplay(), dgRunnable( (IContextInformation info_, int position_) {
+            internalShowContextInfo(info_, position_);
+            hideContextSelector();
+        }, info, position));
+    }
+
+    /**
+     * Displays the given context information for the given offset.
+     *
+     * @param information the context information
+     * @param offset the offset
+     * @since 2.0
+     */
+
+    private void internalShowContextInfo(IContextInformation information, int offset) {
+
+        IContextInformationValidator validator= fContentAssistant.getContextInformationValidator(fViewer, offset);
+
+        if (validator !is null) {
+            ContextFrame current= new ContextFrame();
+            current.fInformation= information;
+            current.fBeginOffset= ( cast(IContextInformationExtension)information ) ? (cast(IContextInformationExtension) information).getContextInformationPosition() : offset;
+            if (current.fBeginOffset is -1) current.fBeginOffset= offset;
+            current.fOffset= offset;
+            current.fVisibleOffset= fViewer.getTextWidget().getSelectionRange().x - (offset - current.fBeginOffset);
+            current.fValidator= validator;
+            current.fPresenter= fContentAssistant.getContextInformationPresenter(fViewer, offset);
+
+            fContextFrameStack.push(current);
+
+            internalShowContextFrame(current, fContextFrameStack.size() is 1);
+        }
+    }
+
+    /**
+     * Shows the given context frame.
+     *
+     * @param frame the frane to display
+     * @param initial <code>true</code> if this is the first frame to be displayed
+     * @since 2.0
+     */
+    private void internalShowContextFrame(ContextFrame frame, bool initial) {
+
+        frame.fValidator.install(frame.fInformation, fViewer, frame.fOffset);
+
+        if (frame.fPresenter !is null) {
+            if (fTextPresentation is null)
+                fTextPresentation= new TextPresentation();
+            frame.fPresenter.install(frame.fInformation, fViewer, frame.fBeginOffset);
+            frame.fPresenter.updatePresentation(frame.fOffset, fTextPresentation);
+        }
+
+        createContextInfoPopup();
+
+        fContextInfoText.setText(frame.fInformation.getInformationDisplayString());
+        if (fTextPresentation !is null)
+            TextPresentation.applyTextPresentation(fTextPresentation, fContextInfoText);
+        resize();
+
+        if (initial) {
+            if (fContentAssistant.addContentAssistListener(this, ContentAssistant2.CONTEXT_INFO_POPUP)) {
+                fContentAssistant.addToLayout(this, fContextInfoPopup, ContentAssistant2.LayoutManager.LAYOUT_CONTEXT_INFO_POPUP, frame.fVisibleOffset);
+                fContextInfoPopup.setVisible(true);
+            }
+        } else {
+            fContentAssistant.layout(ContentAssistant2.LayoutManager.LAYOUT_CONTEXT_INFO_POPUP, frame.fVisibleOffset);
+        }
+    }
+
+    /**
+     * Computes all possible context information for the given offset.
+     *
+     * @param position the offset
+     * @return all possible context information for the given offset
+     * @since 2.0
+     */
+    private IContextInformation[] computeContextInformation(int position) {
+        return fContentAssistant.computeContextInformation(fViewer, position);
+    }
+
+    /**
+     *Returns the error message generated while computing context information.
+     *
+     * @return the error message
+     */
+    private String getErrorMessage() {
+        return fContentAssistant.getErrorMessage();
+    }
+
+    /**
+     * Creates the context information popup. This is the tooltip like overlay window.
+     */
+    private void createContextInfoPopup() {
+        if (Helper2.okToUse(fContextInfoPopup))
+            return;
+
+        Control control= fViewer.getTextWidget();
+        Display display= control.getDisplay();
+
+        fContextInfoPopup= new Shell(control.getShell(), DWT.NO_TRIM | DWT.ON_TOP);
+        fContextInfoPopup.setBackground(display.getSystemColor(DWT.COLOR_BLACK));
+
+        fContextInfoText= new StyledText(fContextInfoPopup, DWT.MULTI | DWT.READ_ONLY);
+
+        Color c= fContentAssistant.getContextInformationPopupBackground();
+        if (c is null)
+            c= display.getSystemColor(DWT.COLOR_INFO_BACKGROUND);
+        fContextInfoText.setBackground(c);
+
+        c= fContentAssistant.getContextInformationPopupForeground();
+        if (c is null)
+            c= display.getSystemColor(DWT.COLOR_INFO_FOREGROUND);
+        fContextInfoText.setForeground(c);
+    }
+
+    /**
+     * Resizes the context information popup.
+     * @since 2.0
+     */
+    private void resize() {
+        Point size= fContextInfoText.computeSize(DWT.DEFAULT, DWT.DEFAULT, true);
+        size.x += 3;
+        fContextInfoText.setSize(size);
+        fContextInfoText.setLocation(1,1);
+        size.x += 2;
+        size.y += 2;
+        fContextInfoPopup.setSize(size);
+    }
+
+    /**
+     *Hides the context information popup.
+     */
+    private void hideContextInfoPopup() {
+
+        if (Helper2.okToUse(fContextInfoPopup)) {
+
+            int size= fContextFrameStack.size();
+            if (size > 0) {
+                fContextFrameStack.pop();
+                -- size;
+            }
+
+            if (size > 0) {
+                ContextFrame current= cast(ContextFrame) fContextFrameStack.peek();
+                internalShowContextFrame(current, false);
+            } else {
+
+                fContentAssistant.removeContentAssistListener(this, ContentAssistant2.CONTEXT_INFO_POPUP);
+
+                fContextInfoPopup.setVisible(false);
+                fContextInfoPopup.dispose();
+                fContextInfoPopup= null;
+
+                if (fTextPresentation !is null) {
+                    fTextPresentation.clear();
+                    fTextPresentation= null;
+                }
+            }
+        }
+
+        if (fContextInfoPopup is null)
+            fContentAssistant.contextInformationClosed_package();
+    }
+
+    /**
+     * Creates the context selector in case the user has the choice between multiple valid contexts
+     * at a given offset.
+     */
+    private void createContextSelector() {
+        if (Helper2.okToUse(fContextSelectorShell))
+            return;
+
+        Control control= fViewer.getTextWidget();
+        fContextSelectorShell= new Shell(control.getShell(), DWT.NO_TRIM | DWT.ON_TOP);
+        GridLayout layout= new GridLayout();
+        layout.marginWidth= 0;
+        layout.marginHeight= 0;
+        fContextSelectorShell.setLayout(layout);
+        fContextSelectorShell.setBackground(control.getDisplay().getSystemColor(DWT.COLOR_BLACK));
+
+
+        fContextSelectorTable= new Table(fContextSelectorShell, DWT.H_SCROLL | DWT.V_SCROLL);
+        fContextSelectorTable.setLocation(1, 1);
+        GridData gd= new GridData(GridData.FILL_BOTH);
+        gd.heightHint= fContextSelectorTable.getItemHeight() * 10;
+        gd.widthHint= 300;
+        fContextSelectorTable.setLayoutData(gd);
+
+        fContextSelectorShell.pack(true);
+
+        Color c= fContentAssistant.getContextSelectorBackground();
+        if (c is null)
+            c= control.getDisplay().getSystemColor(DWT.COLOR_INFO_BACKGROUND);
+        fContextSelectorTable.setBackground(c);
+
+        c= fContentAssistant.getContextSelectorForeground();
+        if (c is null)
+            c= control.getDisplay().getSystemColor(DWT.COLOR_INFO_FOREGROUND);
+        fContextSelectorTable.setForeground(c);
+
+        fContextSelectorTable.addSelectionListener(new class()  SelectionListener {
+            public void widgetSelected(SelectionEvent e) {
+            }
+
+            public void widgetDefaultSelected(SelectionEvent e) {
+                insertSelectedContext();
+                hideContextSelector();
+            }
+        });
+
+        fPopupCloser.install(fContentAssistant, fContextSelectorTable);
+
+        fContextSelectorTable.setHeaderVisible(false);
+        fContentAssistant.addToLayout(this, fContextSelectorShell, ContentAssistant2.LayoutManager.LAYOUT_CONTEXT_SELECTOR, fContentAssistant.getSelectionOffset());
+    }
+
+    /**
+     * Causes the context information of the context selected in the context selector
+     * to be displayed in the context information popup.
+     */
+    private void insertSelectedContext() {
+        int i= fContextSelectorTable.getSelectionIndex();
+
+        if (i < 0 || i >= fContextSelectorInput.length)
+            return;
+
+        int position= fViewer.getSelectedRange().x;
+        internalShowContextInfo(fContextSelectorInput[i], position);
+    }
+
+    /**
+     * Sets the contexts in the context selector to the given set.
+     *
+     * @param contexts the possible contexts
+     */
+    private void setContexts(IContextInformation[] contexts) {
+        if (Helper2.okToUse(fContextSelectorTable)) {
+
+            fContextSelectorInput= contexts;
+
+            fContextSelectorTable.setRedraw(false);
+            fContextSelectorTable.removeAll();
+
+            TableItem item;
+            IContextInformation t;
+            for (int i= 0; i < contexts.length; i++) {
+                t= contexts[i];
+                item= new TableItem(fContextSelectorTable, DWT.NULL);
+                if (t.getImage() !is null)
+                    item.setImage(t.getImage());
+                item.setText(t.getContextDisplayString());
+            }
+
+            fContextSelectorTable.select(0);
+            fContextSelectorTable.setRedraw(true);
+        }
+    }
+
+    /**
+     * Displays the context selector.
+     */
+    private void displayContextSelector() {
+        if (fContentAssistant.addContentAssistListener(this, ContentAssistant2.CONTEXT_SELECTOR))
+            fContextSelectorShell.setVisible(true);
+    }
+
+    /**
+     * Hodes the context selector.
+     */
+    private void hideContextSelector() {
+        if (Helper2.okToUse(fContextSelectorShell)) {
+            fContentAssistant.removeContentAssistListener(this, ContentAssistant2.CONTEXT_SELECTOR);
+
+            fPopupCloser.uninstall();
+            fContextSelectorShell.setVisible(false);
+            fContextSelectorShell.dispose();
+            fContextSelectorShell= null;
+        }
+
+        if (!Helper2.okToUse(fContextInfoPopup))
+            fContentAssistant.contextInformationClosed_package();
+    }
+
+    /**
+     *Returns whether the context selector has the focus.
+     *
+     * @return <code>true</code> if teh context selector has the focus
+     */
+    public bool hasFocus() {
+        if (Helper2.okToUse(fContextSelectorShell))
+            return (fContextSelectorShell.isFocusControl() || fContextSelectorTable.isFocusControl());
+
+        return false;
+    }
+
+    /**
+     * Hides context selector and context information popup.
+     */
+    public void hide() {
+        hideContextSelector();
+        hideContextInfoPopup();
+    }
+
+    /**
+     * Returns whether this context information popup is active. I.e., either
+     * a context selector or context information is displayed.
+     *
+     * @return <code>true</code> if the context selector is active
+     */
+    public bool isActive() {
+        return (Helper2.okToUse(fContextInfoPopup) || Helper2.okToUse(fContextSelectorShell));
+    }
+
+    /*
+     * @see IContentAssistListener#verifyKey(VerifyEvent)
+     */
+    public bool verifyKey(VerifyEvent e) {
+        if (Helper2.okToUse(fContextSelectorShell))
+            return contextSelectorKeyPressed(e);
+        if (Helper2.okToUse(fContextInfoPopup))
+            return contextInfoPopupKeyPressed(e);
+        return true;
+    }
+
+    /**
+     * Processes a key stroke in the context selector.
+     *
+     * @param e the verify event describing the key stroke
+     * @return <code>true</code> if processing can be stopped
+     */
+    private bool contextSelectorKeyPressed(VerifyEvent e) {
+
+        char key= e.character;
+        if (key is 0) {
+
+            int change;
+            int visibleRows= (fContextSelectorTable.getSize().y / fContextSelectorTable.getItemHeight()) - 1;
+            int selection= fContextSelectorTable.getSelectionIndex();
+
+            switch (e.keyCode) {
+
+                case DWT.ARROW_UP:
+                    change= (fContextSelectorTable.getSelectionIndex() > 0 ? -1 : 0);
+                    break;
+
+                case DWT.ARROW_DOWN:
+                    change= (fContextSelectorTable.getSelectionIndex() < fContextSelectorTable.getItemCount() - 1 ? 1 : 0);
+                    break;
+
+                case DWT.PAGE_DOWN :
+                    change= visibleRows;
+                    if (selection + change >= fContextSelectorTable.getItemCount())
+                        change= fContextSelectorTable.getItemCount() - selection;
+                    break;
+
+                case DWT.PAGE_UP :
+                    change= -visibleRows;
+                    if (selection + change < 0)
+                        change= -selection;
+                    break;
+
+                case DWT.HOME :
+                    change= -selection;
+                    break;
+
+                case DWT.END :
+                    change= fContextSelectorTable.getItemCount() - selection;
+                    break;
+
+                default:
+                    if (e.keyCode !is DWT.MOD1 && e.keyCode !is DWT.MOD2 && e.keyCode !is DWT.MOD3 && e.keyCode !is DWT.MOD4)
+                        hideContextSelector();
+                    return true;
+            }
+
+            fContextSelectorTable.setSelection(selection + change);
+            fContextSelectorTable.showSelection();
+            e.doit= false;
+            return false;
+
+        } else if ('\t' is key) {
+            // switch focus to selector shell
+            e.doit= false;
+            fContextSelectorShell.setFocus();
+            return false;
+        } else if (key is DWT.ESC) {
+            e.doit= false;
+            hideContextSelector();
+        }
+
+        return true;
+    }
+
+    /**
+     * Processes a key stroke while the info popup is up.
+     *
+     * @param e the verify event describing the key stroke
+     * @return <code>true</code> if processing can be stopped
+     */
+    private bool contextInfoPopupKeyPressed(KeyEvent e) {
+
+        char key= e.character;
+        if (key is 0) {
+
+            switch (e.keyCode) {
+                case DWT.ARROW_LEFT:
+                case DWT.ARROW_RIGHT:
+                    validateContextInformation();
+                    break;
+                default:
+                    if (e.keyCode !is DWT.MOD1 && e.keyCode !is DWT.MOD2 && e.keyCode !is DWT.MOD3 && e.keyCode !is DWT.MOD4)
+                        hideContextInfoPopup();
+                    break;
+            }
+
+        } else if (key is DWT.ESC) {
+            e.doit= false;
+            hideContextInfoPopup();
+        } else {
+            validateContextInformation();
+        }
+        return true;
+    }
+
+    /*
+     * @see IEventConsumer#processEvent(VerifyEvent)
+     */
+    public void processEvent(VerifyEvent event) {
+        if (Helper2.okToUse(fContextSelectorShell))
+            contextSelectorProcessEvent(event);
+        if (Helper2.okToUse(fContextInfoPopup))
+            contextInfoPopupProcessEvent(event);
+    }
+
+    /**
+     * Processes a key stroke in the context selector.
+     *
+     * @param e the verify event describing the key stroke
+     */
+    private void contextSelectorProcessEvent(VerifyEvent e) {
+
+        if (e.start is e.end && e.text !is null && e.text.equals(fLineDelimiter)) {
+            e.doit= false;
+            insertSelectedContext();
+        }
+
+        hideContextSelector();
+    }
+
+    /**
+     * Processes a key stroke while the info popup is up.
+     *
+     * @param e the verify event describing the key stroke
+     */
+    private void contextInfoPopupProcessEvent(VerifyEvent e) {
+        if (e.start !is e.end && (e.text is null || e.text.length() is 0))
+            validateContextInformation();
+    }
+
+    /**
+     * Validates the context information for the viewer's actual cursor position.
+     */
+    private void validateContextInformation() {
+        /*
+         * Post the code in the event queue in order to ensure that the
+         * action described by this verify key event has already beed executed.
+         * Otherwise, we'd validate the context information based on the
+         * pre-key-stroke state.
+         */
+        fContextInfoPopup.getDisplay().asyncExec(dgRunnable( (ContextFrame fFrame_) {
+
+            ContextFrame fFrame= fFrame_;
+
+            if (Helper2.okToUse(fContextInfoPopup) && fFrame is fContextFrameStack.peek()) {
+                int offset= fViewer.getSelectedRange().x;
+                if (fFrame.fValidator is null || !fFrame.fValidator.isContextInformationValid(offset)) {
+                    hideContextInfoPopup();
+                } else if (fFrame.fPresenter !is null && fFrame.fPresenter.updatePresentation(offset, fTextPresentation)) {
+                    TextPresentation.applyTextPresentation(fTextPresentation, fContextInfoText);
+                    resize();
+                }
+            }
+        }, cast(ContextFrame) fContextFrameStack.peek()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/link/contentassist/Helper2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.link.contentassist.Helper2;
+
+import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport
+import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport
+import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport
+import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.widgets.Widget;
+
+
+/**
+ * Helper class for testing widget state.
+ */
+class Helper2 {
+
+    /**
+     * Returns whether the widget is <code>null</code> or disposed.
+     *
+     * @param widget the widget to check
+     * @return <code>true</code> if the widget is neither <code>null</code> nor disposed
+     */
+    public static bool okToUse(Widget widget) {
+        return (widget !is null && !widget.isDisposed());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/link/contentassist/IContentAssistListener2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.link.contentassist.IContentAssistListener2;
+
+import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport
+import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport
+import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport
+import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+
+import dwt.events.VerifyEvent;
+import dwtx.jface.text.IEventConsumer;
+
+
+
+/**
+ * An interface whereby listeners can not only receive key events,
+ * but can also consume them to prevent subsequent listeners from
+ * processing the event.
+ */
+interface IContentAssistListener2 : IEventConsumer {
+
+    /**
+     * Verifies the key event.
+     *
+     * @param event the key event
+     * @return <code>true</code> if processing should be continued by additional listeners
+     * @see dwt.custom.VerifyKeyListener#verifyKey(VerifyEvent)
+     */
+    public bool verifyKey(VerifyEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/link/contentassist/IProposalListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.link.contentassist.IProposalListener;
+
+import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport
+import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport
+import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.contentassist.ICompletionProposal;
+
+
+/**
+ *
+ */
+public interface IProposalListener {
+
+    /**
+     * @param proposal
+     */
+    void proposalChosen(ICompletionProposal proposal);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/link/contentassist/LineBreakingReader.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.link.contentassist.LineBreakingReader;
+
+import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport
+import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport
+import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.PopupCloser2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport
+
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.BufferedReader;
+import dwtx.dwtxhelper.mangoicu.UBreakIterator;
+
+import dwt.graphics.GC;
+
+/*
+ * Not a real reader. Could change if requested
+ */
+public class LineBreakingReader {
+
+    private BufferedReader fReader;
+    private GC fGC;
+    private int fMaxWidth;
+
+    private String fLine;
+    private int fOffset;
+
+    private UBreakIterator fLineBreakIterator;
+    private bool fBreakWords;
+
+    /**
+     * Creates a reader that breaks an input text to fit in a given width.
+     *
+     * @param reader Reader of the input text
+     * @param gc The graphic context that defines the currently used font sizes
+     * @param maxLineWidth The max width (pixels) where the text has to fit in
+     */
+    public this(Reader reader, GC gc, int maxLineWidth) {
+        fReader= new BufferedReader(reader);
+        fGC= gc;
+        fMaxWidth= maxLineWidth;
+        fOffset= 0;
+        fLine= null;
+        fLineBreakIterator= UBreakIterator.openLineIterator( ULocale.Default);
+        fBreakWords= true;
+    }
+
+    public bool isFormattedLine() {
+        return fLine !is null;
+    }
+
+    /**
+     * Reads the next line. The lengths of the line will not exceed the given maximum
+     * width.
+     *
+     * @return the next line
+     * @throws IOException
+     */
+    public String readLine()  {
+        if (fLine is null) {
+            String line= fReader.readLine();
+            if (line is null)
+                return null;
+
+            int lineLen= fGC.textExtent(line).x;
+            if (lineLen < fMaxWidth) {
+                return line;
+            }
+            fLine= line;
+            fLineBreakIterator.setText(line);
+            fOffset= 0;
+        }
+        int breakOffset= findNextBreakOffset(fOffset);
+        String res;
+        if (breakOffset !is UBreakIterator.DONE) {
+            res= fLine.substring(fOffset, breakOffset);
+            fOffset= findWordBegin(breakOffset);
+            if (fOffset is fLine.length()) {
+                fLine= null;
+            }
+        } else {
+            res= fLine.substring(fOffset);
+            fLine= null;
+        }
+        return res;
+    }
+
+    private int findNextBreakOffset(int currOffset) {
+        int currWidth= 0;
+        int nextOffset= fLineBreakIterator.following(currOffset);
+        while (nextOffset !is UBreakIterator.DONE) {
+            String word= fLine.substring(currOffset, nextOffset);
+            int wordWidth= fGC.textExtent(word).x;
+            int nextWidth= wordWidth + currWidth;
+            if (nextWidth > fMaxWidth) {
+                if (currWidth > 0)
+                    return currOffset;
+
+                if (!fBreakWords)
+                    return nextOffset;
+
+                // need to fit into fMaxWidth
+                int length= word.length();
+                while (length >= 0) {
+                    length--;
+                    word= word.substring(0, length);
+                    wordWidth= fGC.textExtent(word).x;
+                    if (wordWidth + currWidth < fMaxWidth)
+                        return currOffset + length;
+                }
+                return nextOffset;
+            }
+            currWidth= nextWidth;
+            currOffset= nextOffset;
+            nextOffset= fLineBreakIterator.next();
+        }
+        return nextOffset;
+    }
+
+    private int findWordBegin(int idx) {
+        while (idx < fLine.length() && Character.isWhitespace(fLine.charAt(idx))) {
+            idx++;
+        }
+        return idx;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/link/contentassist/PopupCloser2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.link.contentassist.PopupCloser2;
+
+import dwtx.jface.internal.text.link.contentassist.IProposalListener; // packageimport
+import dwtx.jface.internal.text.link.contentassist.LineBreakingReader; // packageimport
+import dwtx.jface.internal.text.link.contentassist.CompletionProposalPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContextInformationPopup2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistMessages; // packageimport
+import dwtx.jface.internal.text.link.contentassist.Helper2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.IContentAssistListener2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.ContentAssistant2; // packageimport
+import dwtx.jface.internal.text.link.contentassist.AdditionalInfoController2; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwt.events.FocusEvent;
+import dwt.events.FocusListener;
+import dwt.events.SelectionEvent;
+import dwt.events.SelectionListener;
+import dwt.events.ShellAdapter;
+import dwt.events.ShellEvent;
+import dwt.widgets.Display;
+import dwt.widgets.ScrollBar;
+import dwt.widgets.Shell;
+import dwt.widgets.Table;
+
+
+/**
+ * A generic closer class used to monitor various
+ * interface events in order to determine whether
+ * a content assistant should be terminated and all
+ * associated windows be closed.
+ */
+class PopupCloser2 : ShellAdapter , FocusListener, SelectionListener {
+
+    /** The content assistant to be monitored */
+    private ContentAssistant2 fContentAssistant;
+    /** The table of a selector popup opened by the content assistant */
+    private Table fTable;
+    /** The scrollbar of the table for the selector popup */
+    private ScrollBar fScrollbar;
+    /** Indicates whether the scrollbar thumb has been grabbed. */
+    private bool fScrollbarClicked= false;
+    /** The shell on which some listeners are registered. */
+    private Shell fShell;
+
+
+    /**
+     * Installs this closer on the given table opened by the given content assistant.
+     *
+     * @param contentAssistant the content assistant
+     * @param table the table to be tracked
+     */
+    public void install(ContentAssistant2 contentAssistant, Table table) {
+        fContentAssistant= contentAssistant;
+        fTable= table;
+        if (Helper2.okToUse(fTable)) {
+            Shell shell= fTable.getShell();
+            if (Helper2.okToUse(shell)) {
+                fShell= shell;
+                fShell.addShellListener(this);
+            }
+            fTable.addFocusListener(this);
+            fScrollbar= fTable.getVerticalBar();
+            if (fScrollbar !is null)
+                fScrollbar.addSelectionListener(this);
+        }
+    }
+
+    /**
+     * Uninstalls this closer if previously installed.
+     */
+    public void uninstall() {
+        fContentAssistant= null;
+        if (Helper2.okToUse(fShell))
+            fShell.removeShellListener(this);
+        fShell= null;
+        if (Helper2.okToUse(fScrollbar))
+            fScrollbar.removeSelectionListener(this);
+        if (Helper2.okToUse(fTable))
+            fTable.removeFocusListener(this);
+    }
+
+    /*
+     * @see dwt.events.SelectionListener#widgetSelected(dwt.events.SelectionEvent)
+     */
+    public void widgetSelected(SelectionEvent e) {
+        fScrollbarClicked= true;
+    }
+
+    /*
+     * @see dwt.events.SelectionListener#widgetDefaultSelected(dwt.events.SelectionEvent)
+     */
+    public void widgetDefaultSelected(SelectionEvent e) {
+        fScrollbarClicked= true;
+    }
+
+    /*
+     * @see dwt.events.FocusListener#focusGained(dwt.events.FocusEvent)
+     */
+    public void focusGained(FocusEvent e) {
+    }
+
+    /*
+     * @see dwt.events.FocusListener#focusLost(dwt.events.FocusEvent)
+     */
+    public void focusLost(FocusEvent e) {
+        fScrollbarClicked= false;
+        Display d= fTable.getDisplay();
+        d.asyncExec(dgRunnable((FocusEvent e_) {
+            if (Helper2.okToUse(fTable) && !fTable.isFocusControl() && !fScrollbarClicked && fContentAssistant !is null)
+                fContentAssistant.popupFocusLost(e_);
+        }, e ));
+    }
+
+    /*
+     * @see dwt.events.ShellAdapter#shellDeactivated(dwt.events.ShellEvent)
+     * @since 3.1
+     */
+    public void shellDeactivated(ShellEvent e) {
+        if (fContentAssistant !is null)
+            fContentAssistant.hide_package();
+    }
+
+
+    /*
+     * @see dwt.events.ShellAdapter#shellClosed(dwt.events.ShellEvent)
+     * @since 3.1
+     */
+    public void shellClosed(ShellEvent e) {
+        if (fContentAssistant !is null)
+            fContentAssistant.hide_package();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/revisions/ChangeRegion.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.revisions.ChangeRegion;
+
+import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport
+import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport
+import dwtx.jface.internal.text.revisions.Hunk; // packageimport
+import dwtx.jface.internal.text.revisions.Colors; // packageimport
+import dwtx.jface.internal.text.revisions.Range; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.text.convert.Format;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.revisions.Revision;
+import dwtx.jface.text.source.ILineRange;
+import dwtx.jface.text.source.LineRange;
+
+/**
+ * A change region describes a contiguous range of lines that was changed in the same revision of a
+ * document. Once it is adjusted to diff information, the originally contiguous range may be split
+ * into several ranges or even be empty.
+ *
+ * @since 3.2
+ */
+public final class ChangeRegion {
+    private const Revision fRevision;
+    private const ILineRange fLines;
+    private const List fAdjusted;
+
+    /**
+     * Creates a new change region for the given revision and line range.
+     *
+     * @param revision the revision of the new region
+     * @param lines the line range of the new region
+     * @throws IndexOutOfBoundsException if the line range is not well-formed
+     */
+    public this(Revision revision, ILineRange lines)  {
+        fAdjusted= new LinkedList();
+        Assert.isLegal(revision !is null);
+        Assert.isLegal(lines !is null);
+        fLines= Range.copy(lines);
+        fRevision=revision;
+        clearDiff();
+    }
+
+    /**
+     * Returns the revision that this region belongs to.
+     *
+     * @return the revision that this region belongs to
+     */
+    public Revision getRevision() {
+        return fRevision;
+    }
+
+    /**
+     * Returns the original (before applying diff information) line range of this change region.
+     *
+     * @return the original (before applying diff information) line range of this change region
+     */
+    public ILineRange getOriginalRange() {
+        return fLines;
+    }
+
+    /**
+     * Returns the list of {@link ILineRange}s of this change region for which the revision
+     * information is still valid.
+     *
+     * @return the list of adjusted line ranges
+     */
+    public List getAdjustedRanges() {
+        return fAdjusted;
+    }
+
+    /**
+     * Returns the line coverage of the adjusted ranges, an empty range if the coverage is empty.
+     *
+     * @return the line coverage of the adjusted ranges
+     */
+    public ILineRange getAdjustedCoverage() {
+        if (fAdjusted.isEmpty())
+            return new LineRange(fLines.getStartLine(), 0);
+
+        Range first= cast(Range) fAdjusted.get(0);
+        Range last= cast(Range) fAdjusted.get(fAdjusted.size() - 1);
+
+        return Range.createAbsolute(first.start(), last.end());
+    }
+
+    /**
+     * Clears any adjusted ranges, restoring the original range.
+     */
+    public void clearDiff() {
+        fAdjusted.clear();
+        fAdjusted.add(Range.copy(fLines));
+    }
+
+    /**
+     * Adjusts this change region to a diff hunk. This will change the adjusted ranges.
+     *
+     * @param hunk the diff hunk to adjust to
+     */
+    public void adjustTo(Hunk hunk) {
+        for (ListIterator it= fAdjusted.listIterator(); it.hasNext();) {
+            Range range= cast(Range) it.next();
+
+            // do we need a split?
+            int unchanged= getUnchanged(hunk, range.start());
+            if (unchanged > 0) {
+                if (unchanged >= range.length())
+                    continue;
+                range= range.split(unchanged);
+                it.add(range);
+                it.previous(); it.next(); // needed so we can remove below
+            }
+
+            int line= range.start();
+            Assert.isTrue(hunk.line <= line);
+
+            // by how much do we shrink?
+            int overlap= getOverlap(hunk, line);
+            if (overlap >= range.length()) {
+                it.remove();
+                continue;
+            }
+
+            // by how much do we move?
+            range.moveBy(hunk.delta + overlap);
+            range.resizeBy(-overlap);
+        }
+
+    }
+
+    private int getUnchanged(Hunk hunk, int line) {
+        return Math.max(0, hunk.line - line);
+    }
+
+    /*
+     * Returns the number of lines after line that the hunk reports as changed.
+     */
+    private int getOverlap(Hunk hunk, int line) {
+
+        int deltaLine= hunk.line + hunk.changed;
+        if (hunk.delta >= 0) {
+            if (deltaLine <= line)
+                return 0;
+            return deltaLine - line;
+        }
+
+        // hunk.delta < 0
+        int hunkEnd= deltaLine - hunk.delta;
+        int cutCount= hunkEnd - line;
+        return Math.max(0, cutCount);
+    }
+
+    /*
+     * @see java.lang.Object#toString()
+     */
+    public override String toString() {
+        return Format("ChangeRegion [{},[{}+{})]", fRevision.toString(), fLines.getStartLine(), fLines.getNumberOfLines() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/revisions/Colors.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.revisions.Colors;
+
+import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport
+import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport
+import dwtx.jface.internal.text.revisions.Hunk; // packageimport
+import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport
+import dwtx.jface.internal.text.revisions.Range; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwt.DWT;
+import dwt.graphics.RGB;
+import dwtx.core.runtime.Assert;
+
+/**
+ * Utility for color operations.
+ *
+ * @since 3.3
+ */
+public final class Colors {
+    /*
+     * Implementation note: Color computation assumes sRGB, which is probably not true, and does not
+     * always give good results. CIE based algorithms would be better, see
+     * http://www.w3.org/TR/PNG-ColorAppendix.html and http://en.wikipedia.org/wiki/Lab_color_space
+     */
+
+    /**
+     * Returns the human-perceived brightness of a color as float in [0.0, 1.0]. The used RGB
+     * weights come from http://www.poynton.com/notes/colour_and_gamma/ColorFAQ.html#RTFToC9.
+     *
+     * @param rgb the color
+     * @return the gray-scale value
+     */
+    public static float brightness(RGB rgb) {
+        return Math.min(1f, (0.2126f * rgb.red + 0.7152f * rgb.green + 0.0722f * rgb.blue + 0.5f) / 255f);
+    }
+
+    /**
+     * Normalizes a color in its perceived brightness. Yellows are darkened, while blues and reds
+     * are lightened. Depending on the hue, the brightness range within the RGB gamut may be
+     * different, outside values are clipped. Note that this is an approximation; the returned RGB
+     * is not guaranteed to have the requested {@link #brightness(RGB) brightness}.
+     *
+     * @param color the color to normalize
+     * @param brightness the requested brightness, in [0,&nbsp;1]
+     * @return a normalized version of <code>color</code>
+     * @see #brightness(RGB)
+     */
+    public static RGB adjustBrightness(RGB color, float brightness_) {
+        float[] hsi= toHSI(color);
+        float psychoFactor= brightness_ - brightness(color);
+        float weight= 0.5f; // found by trial and error
+        hsi[2]= Math.max(0, Math.min(1.0f, hsi[2] + psychoFactor * weight));
+        color= fromHSI(hsi);
+        return color;
+    }
+
+    /**
+     * Converts an {@link RGB} to an <a href="http://en.wikipedia.org/wiki/HSL_color_space">HSI</a>
+     * triplet.
+     *
+     * @param color the color to convert
+     * @return the HSI float array of length 3
+     */
+    private static float[] toHSI(RGB color) {
+        float r = color.red / 255f;
+        float g = color.green / 255f;
+        float b = color.blue / 255f;
+        float max = Math.max(Math.max(r, g), b);
+        float min = Math.min(Math.min(r, g), b);
+        float delta = max - min;
+        float maxPlusMin= max + min;
+        float intensity = maxPlusMin / 2;
+        float saturation= intensity < 0.5 ? delta / maxPlusMin : delta / (2 - maxPlusMin);
+
+        float hue = 0;
+        if (delta !is 0) {
+            if (r is max) {
+                hue = (g  - b) / delta;
+            } else {
+                if (g is max) {
+                    hue = 2 + (b - r) / delta;
+                } else {
+                    hue = 4 + (r - g) / delta;
+                }
+            }
+            hue *= 60;
+            if (hue < 0) hue += 360;
+        }
+        return [hue, saturation, intensity];
+    }
+
+    /**
+     * Converts a <a href="http://en.wikipedia.org/wiki/HSL_color_space">HSI</a> triplet to an RGB.
+     *
+     * @param hsi the HSI values
+     * @return the RGB corresponding to the HSI spec
+     */
+    private static RGB fromHSI(float[] hsi) {
+        float r, g, b;
+        float hue= hsi[0];
+        float saturation= hsi[1];
+        float intensity= hsi[2];
+        if (saturation is 0) {
+            r = g = b = intensity;
+        } else {
+            float temp2= intensity < 0.5f ? intensity * (1.0f + saturation) : (intensity + saturation) - (intensity * saturation);
+            float temp1= 2f * intensity - temp2;
+            if (hue is 360) hue = 0;
+            hue /= 360;
+
+            r= hue2RGB(temp1, temp2, hue + 1f/3f);
+            g= hue2RGB(temp1, temp2, hue);
+            b= hue2RGB(temp1, temp2, hue - 1f/3f);
+        }
+
+        int red = cast(int)(r * 255 + 0.5);
+        int green = cast(int)(g * 255 + 0.5);
+        int blue = cast(int)(b * 255 + 0.5);
+        return new RGB(red, green, blue);
+    }
+
+    private static float hue2RGB(float t1, float t2, float hue) {
+        if (hue < 0)
+            hue += 1;
+        else if (hue > 1)
+            hue -= 1;
+        if (6f * hue < 1)
+            return t1 +(t2 - t1) * 6f * hue;
+        if (2f * hue < 1)
+            return t2;
+        if (3f * hue < 2)
+            return t1 + (t2 - t1) * (2f/3f - hue) * 6f;
+        return t1;
+    }
+
+    /**
+     * Returns an RGB that lies between the given foreground and background
+     * colors using the given mixing factor. A <code>factor</code> of 1.0 will produce a
+     * color equal to <code>fg</code>, while a <code>factor</code> of 0.0 will produce one
+     * equal to <code>bg</code>.
+     * @param bg the background color
+     * @param fg the foreground color
+     * @param factor the mixing factor, must be in [0,&nbsp;1]
+     *
+     * @return the interpolated color
+     */
+    public static RGB blend(RGB bg, RGB fg, float factor) {
+        Assert.isLegal(bg !is null);
+        Assert.isLegal(fg !is null);
+        Assert.isLegal(factor >= 0f && factor <= 1f);
+
+        float complement= 1f - factor;
+        return new RGB(
+                cast(int) (complement * bg.red + factor * fg.red),
+                cast(int) (complement * bg.green + factor * fg.green),
+                cast(int) (complement * bg.blue + factor * fg.blue)
+        );
+    }
+
+    /**
+     * Returns an array of colors in a smooth palette from <code>start</code> to <code>end</code>.
+     * <p>
+     * The returned array has size <code>steps</code>, and the color at index 0 is <code>start</code>, the color
+     * at index <code>steps&nbsp;-&nbsp;1</code> is <code>end</code>.
+     *
+     * @param start the start color of the palette
+     * @param end the end color of the palette
+     * @param steps the requested size, must be &gt; 0
+     * @return an array of <code>steps</code> colors in the palette from <code>start</code> to <code>end</code>
+     */
+    public static RGB[] palette(RGB start, RGB end, int steps) {
+        Assert.isLegal(start !is null);
+        Assert.isLegal(end !is null);
+        Assert.isLegal(steps > 0);
+
+        if (steps is 1)
+            return [ start ];
+
+        float step= 1.0f / (steps - 1);
+        RGB[] gradient= new RGB[steps];
+        for (int i= 0; i < steps; i++)
+            gradient[i]= blend(start, end, step * i);
+
+        return gradient;
+    }
+
+    /**
+     * Returns an array of colors with hues evenly distributed on the hue wheel defined by the <a
+     * href="http://en.wikipedia.org/wiki/HSV_color_space">HSB color space</a>. The returned array
+     * has size <code>steps</code>. The distance <var>d</var> between two successive colors is
+     * in [120&#176;,&nbsp;180&#176;].
+     * <p>
+     * The color at a given <code>index</code> has the hue returned by
+     * {@linkplain #computeHue(int) computeHue(index)}; i.e. the computed hues are not equidistant,
+     * but adaptively distributed on the color wheel.
+     * </p>
+     * <p>
+     * The first six colors returned correspond to the following {@link DWT} color constants:
+     * {@link DWT#COLOR_RED red}, {@link DWT#COLOR_GREEN green}, {@link DWT#COLOR_BLUE blue},
+     * {@link DWT#COLOR_YELLOW yellow}, {@link DWT#COLOR_CYAN cyan},
+     * {@link DWT#COLOR_MAGENTA magenta}.
+     * </p>
+     *
+     * @param steps the requested size, must be &gt;= 2
+     * @return an array of <code>steps</code> colors evenly distributed on the color wheel
+     */
+    public static RGB[] rainbow(int steps) {
+        Assert.isLegal(steps >= 2);
+
+        RGB[] rainbow= new RGB[steps];
+        for (int i= 0; i < steps; i++)
+            rainbow[i]= new RGB(computeHue(i), 1f, 1f);
+
+        return rainbow;
+    }
+
+    /**
+     * Returns an indexed hue in [0&#176;,&nbsp;360&#176;), distributing the hues evenly on the hue wheel
+     * defined by the <a href="http://en.wikipedia.org/wiki/HSV_color_space">HSB (or HSV) color
+     * space</a>. The distance <var>d</var> between two successive colors is in [120&#176;,&nbsp;180&#176;].
+     * <p>
+     * The first six colors returned correspond to the following {@link DWT} color constants:
+     * {@link DWT#COLOR_RED red}, {@link DWT#COLOR_GREEN green}, {@link DWT#COLOR_BLUE blue},
+     * {@link DWT#COLOR_YELLOW yellow}, {@link DWT#COLOR_CYAN cyan},
+     * {@link DWT#COLOR_MAGENTA magenta}.
+     * </p>
+     *
+     * @param index the index of the color, must be &gt;= 0
+     * @return a color hue in [0&#176;,&nbsp;360&#176;)
+     * @see RGB#RGB(float, float, float)
+     */
+    public static float computeHue(int index) {
+        Assert.isLegal(index >= 0);
+        /*
+         * Base 3 gives a nice partitioning for RGB colors with red, green, blue being the colors
+         * 0,1,2, and yellow, cyan, magenta colors 3,4,5.
+         */
+        final int base= 3;
+        final float range= 360f;
+
+        // partition the baseRange by using the least significant bit to select one half of the
+        // partitioning
+        int baseIndex= index / base;
+        float baseRange= range / base;
+        float baseOffset= 0f;
+        while (baseIndex > 0) {
+            baseRange /= 2;
+            int lsb= baseIndex % 2;
+            baseOffset += lsb * baseRange;
+            baseIndex >>= 1;
+        }
+
+        final int baseMod= index % base;
+        final float hue= baseOffset + baseMod * range / base;
+        Assert.isTrue(hue >= 0 && hue < 360);
+        return hue;
+    }
+
+    private this() {
+        // not instantiatable
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/revisions/Hunk.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.revisions.Hunk;
+
+import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport
+import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport
+import dwtx.jface.internal.text.revisions.Colors; // packageimport
+import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport
+import dwtx.jface.internal.text.revisions.Range; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport
+
+import dwt.dwthelper.utils;
+import tango.text.convert.Format;
+
+import dwtx.core.runtime.Assert;
+
+/**
+ * A hunk describes a contiguous range of changed, added or deleted lines. <code>Hunk</code>s are separated by
+ * one or more unchanged lines.
+ *
+ * @since 3.3
+ */
+public final class Hunk {
+    /**
+     * The line at which the hunk starts in the current document. Must be in
+     * <code>[0, numberOfLines]</code> &ndash; note the inclusive end; there may be a hunk with
+     * <code>line is numberOfLines</code> to describe deleted lines at then end of the document.
+     */
+    public const int line;
+    /**
+     * The difference in lines compared to the corresponding line range in the original. Positive
+     * for added lines, negative for deleted lines.
+     */
+    public const int delta;
+    /** The number of changed lines in this hunk, must be &gt;= 0. */
+    public const int changed;
+
+    /**
+     * Creates a new hunk.
+     *
+     * @param line the line at which the hunk starts, must be &gt;= 0
+     * @param delta the difference in lines compared to the original
+     * @param changed the number of changed lines in this hunk, must be &gt;= 0
+     */
+    public this(int line, int delta, int changed) {
+        Assert.isLegal(line >= 0);
+        Assert.isLegal(changed >= 0);
+        this.line= line;
+        this.delta= delta;
+        this.changed= changed;
+    }
+
+    /*
+     * @see java.lang.Object#toString()
+     */
+    public override String toString() {
+        return Format("Hunk [{}>{}{}{}]", line, changed, delta < 0 ? "-" : "+", Math.abs(delta) ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
+    }
+
+    /*
+     * @see java.lang.Object#hashCode()
+     */
+    public override hash_t toHash() {
+        final int prime= 31;
+        int result= 1;
+        result= prime * result + changed;
+        result= prime * result + delta;
+        result= prime * result + line;
+        return result;
+    }
+
+    /*
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public override int opEquals(Object obj) {
+        if (obj is this)
+            return true;
+        if ( Hunk other= cast(Hunk)obj ) {
+            return other.line is this.line && other.delta is this.delta && other.changed is this.changed;
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/revisions/HunkComputer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.revisions.HunkComputer;
+
+import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport
+import dwtx.jface.internal.text.revisions.Hunk; // packageimport
+import dwtx.jface.internal.text.revisions.Colors; // packageimport
+import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport
+import dwtx.jface.internal.text.revisions.Range; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.jface.text.source.ILineDiffInfo;
+import dwtx.jface.text.source.ILineDiffer;
+
+
+/**
+ * Computes the diff hunks from an {@link ILineDiffer}.
+ *
+ * @since 3.3
+ */
+public final class HunkComputer {
+    /**
+     * Converts the line-based information of {@link ILineDiffer} into {@link Hunk}s, grouping
+     * contiguous blocks of lines that are changed (added, deleted).
+     *
+     * @param differ the line differ to query
+     * @param lines the number of lines to query
+     * @return the corresponding {@link Hunk} information
+     */
+    public static Hunk[] computeHunks(ILineDiffer differ, int lines) {
+        List hunks= new ArrayList(lines);
+
+        int added= 0;
+        int changed= 0;
+        ILineDiffInfo info= null;
+        for (int line= 0; line < lines; line++) {
+            info= differ.getLineInfo(line);
+            if (info is null)
+                continue;
+
+            int changeType= info.getChangeType();
+            switch (changeType) {
+                case ILineDiffInfo.ADDED:
+                    added++;
+                    continue;
+                case ILineDiffInfo.CHANGED:
+                    changed++;
+                    continue;
+                case ILineDiffInfo.UNCHANGED:
+                    added -= info.getRemovedLinesAbove();
+                    if (added !is 0 || changed !is 0) {
+                        hunks.add(new Hunk(line - changed - Math.max(0, added), added, changed));
+                        added= 0;
+                        changed= 0;
+                    }
+            }
+        }
+
+        // last hunk
+        if (info !is null) {
+            added -= info.getRemovedLinesBelow();
+            if (added !is 0 || changed !is 0) {
+                hunks.add(new Hunk(lines - changed, added, changed));
+                added= 0;
+                changed= 0;
+            }
+        }
+
+        return arraycast!(Hunk)( hunks.toArray());
+    }
+    private this() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/revisions/LineIndexOutOfBoundsException.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException;
+
+import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport
+import dwtx.jface.internal.text.revisions.Hunk; // packageimport
+import dwtx.jface.internal.text.revisions.Colors; // packageimport
+import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport
+import dwtx.jface.internal.text.revisions.Range; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Thrown to indicate that an attempt to create or modify a {@link Range} failed because it would
+ * have resulted in an illegal range. A range is illegal if its length is &lt;= 0 or if its start
+ * line is &lt; 0.
+ *
+ * @since 3.2
+ */
+public final class LineIndexOutOfBoundsException : IndexOutOfBoundsException {
+    private static const long serialVersionUID= 1L;
+
+    /**
+     * Constructs an <code>LineIndexOutOfBoundsException</code> with no detail message.
+     */
+    public this() {
+        super();
+    }
+
+    /**
+     * Constructs an <code>LineIndexOutOfBoundsException</code> with the specified detail message.
+     *
+     * @param s the detail message.
+     */
+    public this(String s) {
+        super(s);
+    }
+
+    /**
+     * Constructs a new <code>LineIndexOutOfBoundsException</code>
+     * object with an argument indicating the illegal index.
+     *
+     * @param index the illegal index.
+     */
+    public this(int index) {
+        super("Line index out of range: " ~ Integer.toString(index)); //$NON-NLS-1$
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/revisions/Range.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,280 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.revisions.Range;
+
+import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport
+import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport
+import dwtx.jface.internal.text.revisions.Hunk; // packageimport
+import dwtx.jface.internal.text.revisions.Colors; // packageimport
+import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport
+
+import dwt.dwthelper.utils;
+import tango.text.convert.Format;
+
+import dwtx.jface.text.source.ILineRange;
+
+/**
+ * A variable {@link dwtx.jface.text.source.ILineRange} with the following invariant:
+ * <ul>
+ * <li>{@link #start() start} &gt;= 0
+ * <li>{@link #length() length} &gt; 0, i.e. a range cannot be empty
+ * </ul>
+ * <p>
+ * Attempts to create or modify a <code>Range</code> such that this invariant would be violated
+ * result in a {@link LineIndexOutOfBoundsException} being
+ * thrown.
+ * </p>
+ *
+ * @since 3.2
+ */
+public final class Range : ILineRange, Cloneable {
+    /**
+     * Creates a new range with the same start and length as the passed line range.
+     *
+     * @param range the range to copy
+     * @return a <code>Range</code> with the same start and length as <code>range</code>
+     * @throws LineIndexOutOfBoundsException if the passed {@link ILineRange} does not adhere to the
+     *         contract of {@link Range}
+     */
+    public static Range copy(ILineRange range)  {
+        return createRelative(range.getStartLine(), range.getNumberOfLines());
+    }
+
+    /**
+     * Creates a new range equal to the passed line range.
+     *
+     * @param range the range to copy
+     * @return a <code>Range</code> equal to <code>range</code>
+     */
+    public static Range copy(Range range) {
+        return createRelative(range.start(), range.length());
+    }
+
+    /**
+     * Creates a new range with the given start offset and length.
+     *
+     * @param start the first line of the new range, must be &gt;= 0
+     * @param length the number of lines included in the new range, must be &gt; 0
+     * @return a <code>Range</code> with the given start and length
+     * @throws LineIndexOutOfBoundsException if the parameters violate the invariant of
+     *         {@link Range}
+     */
+    public static Range createRelative(int start, int length)  {
+        return new Range(start, length);
+    }
+
+    /**
+     * Creates a new range with the given start and end offsets.
+     *
+     * @param start the first line of the new range, must be &gt;= 0
+     * @param end the first line not in the range any more (exclusive), must be &gt; <code>start</code>
+     * @return a <code>Range</code> with the given start and end offsets
+     * @throws LineIndexOutOfBoundsException if the parameters violate the invariant of
+     *         {@link Range}
+     */
+    public static Range createAbsolute(int start, int end) {
+        return new Range(start, end - start);
+    }
+
+    private int fStart;
+    private int fLength;
+
+    /*
+     * Private constructor.
+     */
+    private this(int start, int length) {
+        moveTo(start);
+        setLength(length);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ILineRange#getStartLine()
+     */
+    public int getStartLine() {
+        return start();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ILineRange#getNumberOfLines()
+     */
+    public int getNumberOfLines() {
+        return length();
+    }
+
+    /**
+     * Returns the first line contained in this range. Short equivalent of {@link #getStartLine()}.
+     *
+     * @return the first line contained in this range
+     */
+    public int start() {
+        return fStart;
+    }
+
+    /**
+     * Returns the number of lines contained in this range. Short equivalent of {@link #getNumberOfLines()}.
+     *
+     * @return the number of lines contained in this range
+     */
+    public int length() {
+        return fLength;
+    }
+
+    /**
+     * Returns the first line after this range. Equivalent to {@linkplain #start() start} + {@linkplain #length() length}.
+     *
+     * @return the first line after this range
+     */
+    public int end() {
+        return start() + length();
+    }
+
+    /**
+     * Moves the receiver to <code>start</code>, keeping {@link #length()} constant.
+     *
+     * @param start the new start, must be &gt;= 0
+     * @throws LineIndexOutOfBoundsException if <code>start</code> &lt; 0
+     */
+    public void moveTo(int start)  {
+        if (!(start >= 0))
+            throw new LineIndexOutOfBoundsException(Format("Cannot set a negative start: {}", start)); //$NON-NLS-1$
+        fStart= start;
+    }
+
+    /**
+     * Moves this range such that the {@link #end()} is at <code>end</code>, keeping
+     * {@link #length()} constant.
+     *
+     * @param end the new end
+     * @throws LineIndexOutOfBoundsException if <code>end</code> &lt;= {@link #start()}
+     */
+    public void moveEndTo(int end)  {
+        moveTo(end - length());
+    }
+
+    /**
+     * Moves the range by <code>delta</code> lines, keeping {@link #length()} constant. The
+     * resulting start line must be &gt;= 0.
+     *
+     * @param delta the number of lines to shift the range
+     * @throws LineIndexOutOfBoundsException if <code>-delta</code> &gt; {@link #start()}
+     */
+    public void moveBy(int delta)  {
+        moveTo(start() + delta);
+    }
+
+    /**
+     * Moves the start offset to <code>start</code>, keeping {@link #end()} constant.
+     *
+     * @param start the new start, must be &gt;= 0 and &lt; {@link #end()}
+     * @throws LineIndexOutOfBoundsException if <code>start</code> &lt; 0 or &gt;= {@link #end()}
+     */
+    public void setStart(int start)  {
+        int end= end();
+        if (!(start >= 0 && start < end))
+            throw new LineIndexOutOfBoundsException(Format("Cannot set a negative start: {}", start)); //$NON-NLS-1$
+        moveTo(start);
+        setEnd(end);
+    }
+
+    /**
+     * Sets the end of this range, keeping {@link #start()} constant.
+     *
+     * @param end the new end, must be &gt; {@link #start()}
+     * @throws LineIndexOutOfBoundsException if <code>end</code> &lt;= {@link #start()}
+     */
+    public void setEnd(int end)  {
+        setLength(end - start());
+    }
+
+    /**
+     * Sets the length of this range, keeping {@link #start()} constant.
+     *
+     * @param length the new length, must be &gt; 0
+     * @throws LineIndexOutOfBoundsException if <code>length</code> &lt;= 0
+     */
+    public void setLength(int length)  {
+        if (!(length > 0))
+            throw new LineIndexOutOfBoundsException(Format("Cannot set length <= 0: {}", length)); //$NON-NLS-1$
+        fLength= length;
+    }
+
+    /**
+     * Sets the length of this range, keeping {@link #end()} constant.
+     *
+     * @param length the new length, must be &gt; 0 and &lt;= {@link #end()}
+     * @throws LineIndexOutOfBoundsException if <code>length</code> &lt;= 0
+     */
+    public void setLengthAndMove(int length)  {
+        setStart(end() - length);
+    }
+
+    /**
+     * Resizes the range by <code>delta</code> lines, keeping {@link #start()} constant.
+     *
+     * @param delta the number of lines to resize the range
+     * @throws LineIndexOutOfBoundsException if <code>-delta</code> &gt;= {@link #length()}
+     */
+    public void resizeBy(int delta)  {
+        setLength(length() + delta);
+    }
+
+    /**
+     * Resizes the range by <code>delta</code> lines by moving the start offset, {@link #end()} remains unchanged.
+     *
+     * @param delta the number of lines to resize the range
+     * @throws LineIndexOutOfBoundsException if <code>-delta</code> &gt;= {@link #length()}
+     */
+    public void resizeAndMoveBy(int delta)  {
+        setStart(start() + delta);
+    }
+
+    /**
+     * Splits a range off the end of the receiver. The receiver is shortened to only include
+     * <code>remaining</code> lines after the split.
+     *
+     * @param remaining the number of lines to remain in the receiver, must be in [1, {@link #length() length})
+     * @return the split off range
+     * @throws LineIndexOutOfBoundsException if <code>remaining</code>&gt;= {@link #length()} or <code>remaining</code>&ltt;= 0
+     */
+    public Range split(int remaining)  {
+        if (!(remaining < length())) // assert before modification
+            throw new LineIndexOutOfBoundsException(Format("Remaining must be less than length: {}", length())); //$NON-NLS-1$
+
+        int splitLength= length() - remaining;
+        setLength(remaining);
+        return new Range(end(), splitLength);
+    }
+
+    /**
+     * Returns <code>true</code> if the passed range has the same offset and length as the receiver.
+     *
+     * @param range another line range to compare the receiver to
+     * @return <code>true</code> if <code>range</code> has the same offset and length as the receiver
+     */
+    public bool equalRange(ILineRange range) {
+        if (range is this)
+            return true;
+        if (range is null)
+            return false;
+        return range.getStartLine() is start() && range.getNumberOfLines() is length();
+    }
+
+    /*
+     * @see java.lang.Object#clone()
+     */
+    public Object clone() {
+        return Range.copy(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/revisions/RevisionPainter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1607 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.revisions.RevisionPainter;
+
+import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport
+import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport
+import dwtx.jface.internal.text.revisions.Hunk; // packageimport
+import dwtx.jface.internal.text.revisions.Colors; // packageimport
+import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport
+import dwtx.jface.internal.text.revisions.Range; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionSelectionProvider; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.text.convert.Format;
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseMoveListener;
+import dwt.events.MouseTrackListener;
+import dwt.graphics.Color;
+import dwt.graphics.FontMetrics;
+import dwt.graphics.GC;
+import dwt.graphics.Point;
+import dwt.graphics.RGB;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Canvas;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwt.widgets.Shell;
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.ListenerList;
+import dwtx.core.runtime.Platform;
+import dwtx.jface.internal.text.html.BrowserInformationControl;
+import dwtx.jface.internal.text.html.HTMLPrinter;
+import dwtx.jface.resource.JFaceResources;
+import dwtx.jface.text.AbstractReusableInformationControlCreator;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.DefaultInformationControl;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.JFaceTextUtil;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.information.IInformationProviderExtension2;
+import dwtx.jface.text.revisions.IRevisionListener;
+import dwtx.jface.text.revisions.IRevisionRulerColumnExtension;
+import dwtx.jface.text.revisions.Revision;
+import dwtx.jface.text.revisions.RevisionEvent;
+import dwtx.jface.text.revisions.RevisionInformation;
+import dwtx.jface.text.revisions.RevisionRange;
+import dwtx.jface.text.revisions.IRevisionRulerColumnExtension;
+import dwtx.jface.text.source.Annotation;
+import dwtx.jface.text.source.CompositeRuler;
+import dwtx.jface.text.source.IAnnotationHover;
+import dwtx.jface.text.source.IAnnotationHoverExtension;
+import dwtx.jface.text.source.IAnnotationHoverExtension2;
+import dwtx.jface.text.source.IAnnotationModel;
+import dwtx.jface.text.source.IAnnotationModelExtension;
+import dwtx.jface.text.source.IAnnotationModelListener;
+import dwtx.jface.text.source.IChangeRulerColumn;
+import dwtx.jface.text.source.ILineDiffer;
+import dwtx.jface.text.source.ILineRange;
+import dwtx.jface.text.source.ISharedTextColors;
+import dwtx.jface.text.source.ISourceViewer;
+import dwtx.jface.text.source.IVerticalRulerColumn;
+import dwtx.jface.text.source.LineRange;
+
+
+/**
+ * A strategy for painting the live annotate colors onto the vertical ruler column. It also manages
+ * the revision hover.
+ *
+ * @since 3.2
+ */
+public final class RevisionPainter {
+    /** Tells whether this class is in debug mode. */
+    private static bool DEBUG_init = false;
+    private static bool DEBUG_;
+    private static bool DEBUG(){
+        if( !DEBUG_init ){
+            DEBUG_init = true;
+            DEBUG_ = "true".equalsIgnoreCase(Platform.getDebugOption("dwtx.jface.text.source/debug/RevisionRulerColumn")); //$NON-NLS-1$//$NON-NLS-2$
+        }
+        return DEBUG_;
+    }
+
+    // RGBs provided by UI Designer
+    private static RGB BY_DATE_START_COLOR_;
+    private static RGB BY_DATE_START_COLOR(){
+        if( BY_DATE_START_COLOR_ is null ){
+            synchronized(RevisionPainter.classinfo){
+                if( BY_DATE_START_COLOR_ is null ){
+                    BY_DATE_START_COLOR_ = new RGB(199, 134, 57);
+                }
+            }
+        }
+        return BY_DATE_START_COLOR_;
+    }
+    private static RGB BY_DATE_END_COLOR_;
+    private static RGB BY_DATE_END_COLOR(){
+        if( BY_DATE_END_COLOR_ is null ){
+            synchronized(RevisionPainter.classinfo){
+                if( BY_DATE_END_COLOR_ is null ){
+                    BY_DATE_END_COLOR_ = new RGB(241, 225, 206);
+                }
+            }
+        }
+        return BY_DATE_END_COLOR_;
+    }
+
+
+    /**
+     * The annotations created to show a revision in the overview ruler.
+     */
+    private static final class RevisionAnnotation : Annotation {
+        public this(String text) {
+            super("dwtx.ui.workbench.texteditor.revisionAnnotation", false, text); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * The color tool manages revision colors and computes shaded colors based on the relative age
+     * and author of a revision.
+     */
+    private final class ColorTool {
+        /**
+         * The average perceived intensity of a base color. 0 means black, 1 means white. A base
+         * revision color perceived as light such as yellow will be darkened, while colors perceived
+         * as dark such as blue will be lightened up.
+         */
+        private static const float AVERAGE_INTENSITY= 0.5f;
+        /**
+         * The maximum shading in [0, 1] - this is the shade that the most recent revision will
+         * receive.
+         */
+        private static const float MAX_SHADING= 0.7f;
+        /**
+         * The minimum shading in [0, 1] - this is the shade that the oldest revision will receive.
+         */
+        private static const float MIN_SHADING= 0.2f;
+        /**
+         * The shade for the focus boxes.
+         */
+        private static const float FOCUS_COLOR_SHADING= 1f;
+
+
+        /**
+         * A list of {@link Long}, storing the age of each revision in a sorted list.
+         */
+        private List fRevisions;
+        /**
+         * The stored shaded colors.
+         */
+        private const Map fColors;
+        /**
+         * The stored focus colors.
+         */
+        private const Map fFocusColors;
+
+        this(){
+            fColors= new HashMap();
+            fFocusColors= new HashMap();
+        }
+        /**
+         * Sets the revision information, which is needed to compute the relative age of a revision.
+         *
+         * @param info the new revision info, <code>null</code> for none.
+         */
+        public void setInfo(RevisionInformation info) {
+            fRevisions= null;
+            fColors.clear();
+            fFocusColors.clear();
+
+            if (info is null)
+                return;
+            List revisions= new ArrayList();
+            for (Iterator it= info.getRevisions().iterator(); it.hasNext();) {
+                Revision revision= cast(Revision) it.next();
+                revisions.add(new Long(computeAge(revision)));
+            }
+            Collections.sort(revisions);
+            fRevisions= revisions;
+        }
+
+        private RGB adaptColor(Revision revision, bool focus) {
+            RGB rgb;
+            float scale;
+            if (fRenderingMode is IRevisionRulerColumnExtension_AGE) {
+                int index= computeAgeIndex(revision);
+                if (index is -1 || fRevisions.size() is 0) {
+                    rgb= getBackground().getRGB();
+                } else {
+                    // gradient from intense red for most recent to faint yellow for oldest
+                    RGB[] gradient= Colors.palette(BY_DATE_START_COLOR, BY_DATE_END_COLOR, fRevisions.size());
+                    rgb= gradient[gradient.length - index - 1];
+                }
+                scale= 0.99f;
+            } else if (fRenderingMode is IRevisionRulerColumnExtension_AUTHOR) {
+                rgb= revision.getColor();
+                rgb= Colors.adjustBrightness(rgb, AVERAGE_INTENSITY);
+                scale= 0.6f;
+            } else if (fRenderingMode is IRevisionRulerColumnExtension_AUTHOR_SHADED_BY_AGE) {
+                rgb= revision.getColor();
+                rgb= Colors.adjustBrightness(rgb, AVERAGE_INTENSITY);
+                int index= computeAgeIndex(revision);
+                int size= fRevisions.size();
+                // relative age: newest is 0, oldest is 1
+                // if there is only one revision, use an intermediate value to avoid extreme coloring
+                if (index is -1 || size < 2)
+                    scale= 0.5f;
+                else
+                    scale= cast(float) index / (size - 1);
+            } else {
+                Assert.isTrue(false);
+                return null; // dummy
+            }
+            rgb= getShadedColor(rgb, scale, focus);
+            return rgb;
+        }
+
+        private int computeAgeIndex(Revision revision) {
+            long age= computeAge(revision);
+            int index= fRevisions.indexOf(new Long(age));
+            return index;
+        }
+
+        private RGB getShadedColor(RGB color, float scale, bool focus) {
+            Assert.isLegal(scale >= 0.0);
+            Assert.isLegal(scale <= 1.0);
+            RGB background= getBackground().getRGB();
+
+            // normalize to lie within [MIN_SHADING, MAX_SHADING]
+            // use more intense colors if the ruler is narrow (i.e. not showing line numbers)
+            bool makeIntense= getWidth() <= 15;
+            float intensityShift= makeIntense ? 0.3f : 0f;
+            float max= MAX_SHADING + intensityShift;
+            float min= MIN_SHADING + intensityShift;
+            scale= (max - min) * scale + min;
+
+            // focus coloring
+            if (focus) {
+                scale += FOCUS_COLOR_SHADING;
+                if (scale > 1) {
+                    background= new RGB(255 - background.red, 255 - background.green, 255 - background.blue);
+                    scale= 2 - scale;
+                }
+            }
+
+            return Colors.blend(background, color, scale);
+        }
+
+        private long computeAge(Revision revision) {
+            return revision.getDate().getTime();
+        }
+
+        /**
+         * Returns the color for a revision based on relative age and author.
+         *
+         * @param revision the revision
+         * @param focus <code>true</code> to return the focus color
+         * @return the color for a revision
+         */
+        public RGB getColor(Revision revision, bool focus) {
+            Map map= focus ? fFocusColors : fColors;
+            RGB color= cast(RGB) map.get(revision);
+            if (color !is null)
+                return color;
+
+            color= adaptColor(revision, focus);
+            map.put(revision, color);
+            return color;
+        }
+    }
+
+    /**
+     * Handles all the mouse interaction in this line number ruler column.
+     */
+    private class MouseHandler : MouseMoveListener, MouseTrackListener, Listener {
+
+        private RevisionRange fMouseDownRegion;
+
+        private void handleMouseUp(Event e) {
+            if (e.button is 1) {
+                RevisionRange upRegion= fFocusRange;
+                RevisionRange downRegion= fMouseDownRegion;
+                fMouseDownRegion= null;
+
+                if (upRegion is downRegion) {
+                    Revision revision= upRegion is null ? null : upRegion.getRevision();
+                    if (revision is fSelectedRevision)
+                        revision= null; // deselect already selected revision
+                    handleRevisionSelected(revision);
+                }
+            }
+        }
+
+        private void handleMouseDown(Event e) {
+            if (e.button is 3)
+                updateFocusRevision(null); // kill any focus as the ctx menu is going to show
+            if (e.button is 1) {
+                fMouseDownRegion= fFocusRange;
+                postRedraw();
+            }
+        }
+
+        /*
+         * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event)
+         */
+        public void handleEvent(Event event) {
+            switch (event.type) {
+                case DWT.MouseWheel:
+                    handleMouseWheel(event);
+                    break;
+                case DWT.MouseDown:
+                    handleMouseDown(event);
+                    break;
+                case DWT.MouseUp:
+                    handleMouseUp(event);
+                    break;
+                default:
+                    Assert.isLegal(false);
+            }
+        }
+
+        /*
+         * @see dwt.events.MouseTrackListener#mouseEnter(dwt.events.MouseEvent)
+         */
+        public void mouseEnter(MouseEvent e) {
+            updateFocusLine(toDocumentLineNumber(e.y));
+        }
+
+        /*
+         * @see dwt.events.MouseTrackListener#mouseExit(dwt.events.MouseEvent)
+         */
+        public void mouseExit(MouseEvent e) {
+            updateFocusLine(-1);
+        }
+
+        /*
+         * @see dwt.events.MouseTrackListener#mouseHover(dwt.events.MouseEvent)
+         */
+        public void mouseHover(MouseEvent e) {
+        }
+
+        /*
+         * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent)
+         */
+        public void mouseMove(MouseEvent e) {
+            updateFocusLine(toDocumentLineNumber(e.y));
+        }
+    }
+
+    /**
+     * Internal listener class that will update the ruler when the underlying model changes.
+     */
+    private class AnnotationListener : IAnnotationModelListener {
+        /*
+         * @see dwtx.jface.text.source.IAnnotationModelListener#modelChanged(dwtx.jface.text.source.IAnnotationModel)
+         */
+        public void modelChanged(IAnnotationModel model) {
+            clearRangeCache();
+            postRedraw();
+        }
+
+    }
+
+    /**
+     * The information control creator.
+     */
+    private static final class HoverInformationControlCreator : AbstractReusableInformationControlCreator {
+        private bool fIsFocusable;
+
+        public this(bool isFocusable) {
+            fIsFocusable= isFocusable;
+        }
+
+        /*
+         * @see dwtx.jface.internal.text.revisions.AbstractReusableInformationControlCreator#doCreateInformationControl(dwt.widgets.Shell)
+         */
+        protected IInformationControl doCreateInformationControl(Shell parent) {
+            if (BrowserInformationControl.isAvailable(parent)) {
+                return new class(parent, JFaceResources.DIALOG_FONT, fIsFocusable)  BrowserInformationControl {
+                    public this(Shell parent, String symbolicFontName, bool resizable){
+                        super(parent, symbolicFontName,resizable);
+                    }
+                    /*
+                     * @see dwtx.jface.internal.text.html.BrowserInformationControl#setInformation(java.lang.String)
+                     * @since 3.3
+                     */
+                    public void setInformation(String content) {
+                        content= addCSSToHTMLFragment(content);
+                        super.setInformation(content);
+                    }
+
+                    /**
+                     * Adds a HTML header and CSS info if <code>html</code> is only an HTML fragment (has no
+                     * &lt;html&gt; section).
+                     *
+                     * @param html the html / text produced by a revision
+                     * @return modified html
+                     */
+                    private String addCSSToHTMLFragment(String html) {
+                        int max= Math.min(100, html.length());
+                        if (html.substring(0, max).indexOf("<html>") !is -1) //$NON-NLS-1$
+                            // there is already a header
+                            return html;
+
+                        StringBuffer info= new StringBuffer(512 + html.length());
+                        HTMLPrinter.insertPageProlog(info, 0, fgStyleSheet);
+                        info.append(html);
+                        HTMLPrinter.addPageEpilog(info);
+                        return info.toString();
+                    }
+
+                };
+            }
+            return new DefaultInformationControl(parent, fIsFocusable);
+        }
+
+        /*
+         * @see dwtx.jface.text.AbstractReusableInformationControlCreator#canReplace(dwtx.jface.text.IInformationControlCreator)
+         */
+        public bool canReplace(IInformationControlCreator creator) {
+            return creator.classinfo is this.classinfo
+                    && (cast(HoverInformationControlCreator) creator).fIsFocusable is fIsFocusable;
+        }
+    }
+
+    private static final String fgStyleSheet= "/* Font definitions */\n" ~ //$NON-NLS-1$
+        "body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt {font-family: sans-serif; font-size: 9pt }\n" ~ //$NON-NLS-1$
+        "pre                { font-family: monospace; font-size: 9pt }\n" ~ //$NON-NLS-1$
+        "\n" ~ //$NON-NLS-1$
+        "/* Margins */\n" ~ //$NON-NLS-1$
+        "body        { overflow: auto; margin-top: 0; margin-bottom: 4; margin-left: 3; margin-right: 0 }\n" ~ //$NON-NLS-1$
+        "h1           { margin-top: 5; margin-bottom: 1 }   \n" ~ //$NON-NLS-1$
+        "h2           { margin-top: 25; margin-bottom: 3 }\n" ~ //$NON-NLS-1$
+        "h3           { margin-top: 20; margin-bottom: 3 }\n" ~ //$NON-NLS-1$
+        "h4           { margin-top: 20; margin-bottom: 3 }\n" ~ //$NON-NLS-1$
+        "h5           { margin-top: 0; margin-bottom: 0 }\n" ~ //$NON-NLS-1$
+        "p            { margin-top: 10px; margin-bottom: 10px }\n" ~ //$NON-NLS-1$
+        "pre             { margin-left: 6 }\n" ~ //$NON-NLS-1$
+        "ul          { margin-top: 0; margin-bottom: 10 }\n" ~ //$NON-NLS-1$
+        "li          { margin-top: 0; margin-bottom: 0 } \n" ~ //$NON-NLS-1$
+        "li p        { margin-top: 0; margin-bottom: 0 } \n" ~ //$NON-NLS-1$
+        "ol          { margin-top: 0; margin-bottom: 10 }\n" ~ //$NON-NLS-1$
+        "dl          { margin-top: 0; margin-bottom: 10 }\n" ~ //$NON-NLS-1$
+        "dt          { margin-top: 0; margin-bottom: 0; font-weight: bold }\n" ~ //$NON-NLS-1$
+        "dd          { margin-top: 0; margin-bottom: 0 }\n" ~ //$NON-NLS-1$
+        "\n" ~ //$NON-NLS-1$
+        "/* Styles and colors */\n" ~ //$NON-NLS-1$
+        "a:link      { color: #0000FF }\n" ~ //$NON-NLS-1$
+        "a:hover         { color: #000080 }\n" ~ //$NON-NLS-1$
+        "a:visited    { text-decoration: underline }\n" ~ //$NON-NLS-1$
+        "h4           { font-style: italic }\n" ~ //$NON-NLS-1$
+        "strong      { font-weight: bold }\n" ~ //$NON-NLS-1$
+        "em          { font-style: italic }\n" ~ //$NON-NLS-1$
+        "var             { font-style: italic }\n" ~ //$NON-NLS-1$
+        "th          { font-weight: bold }\n" ~ //$NON-NLS-1$
+        ""; //$NON-NLS-1$
+
+    /**
+     * The revision hover displays information about the currently selected revision.
+     */
+    private final class RevisionHover : IAnnotationHover, IAnnotationHoverExtension, IAnnotationHoverExtension2, IInformationProviderExtension2 {
+
+        /*
+         * @see dwtx.jface.text.source.IAnnotationHover#getHoverInfo(dwtx.jface.text.source.ISourceViewer,
+         *      int)
+         */
+        public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+            Object info= getHoverInfo(sourceViewer, getHoverLineRange(sourceViewer, lineNumber), 0);
+            return info is null ? null : info.toString();
+        }
+
+        /*
+         * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverControlCreator()
+         */
+        public IInformationControlCreator getHoverControlCreator() {
+            RevisionInformation revisionInfo= fRevisionInfo;
+            if (revisionInfo !is null) {
+                IInformationControlCreator creator= revisionInfo.getHoverControlCreator();
+                if (creator !is null)
+                    return creator;
+            }
+            return new HoverInformationControlCreator(false);
+        }
+
+        /*
+         * @see dwtx.jface.text.source.IAnnotationHoverExtension#canHandleMouseCursor()
+         */
+        public bool canHandleMouseCursor() {
+            return false;
+        }
+
+        /*
+         * @see dwtx.jface.text.source.IAnnotationHoverExtension2#canHandleMouseWheel()
+         */
+        public bool canHandleMouseWheel() {
+            return true;
+        }
+
+        /*
+         * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverInfo(dwtx.jface.text.source.ISourceViewer,
+         *      dwtx.jface.text.source.ILineRange, int)
+         */
+        public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleNumberOfLines) {
+            RevisionRange range= getRange(lineRange.getStartLine());
+            Object info= range is null ? null : range.getRevision().getHoverInfo();
+            return info;
+        }
+
+        /*
+         * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverLineRange(dwtx.jface.text.source.ISourceViewer,
+         *      int)
+         */
+        public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) {
+            RevisionRange range= getRange(lineNumber);
+            return range is null ? null : new LineRange(lineNumber, 1);
+        }
+
+        /*
+         * @see dwtx.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator()
+         */
+        public IInformationControlCreator getInformationPresenterControlCreator() {
+            RevisionInformation revisionInfo= fRevisionInfo;
+            if (revisionInfo !is null) {
+                IInformationControlCreator creator= revisionInfo.getInformationPresenterControlCreator();
+                if (creator !is null)
+                    return creator;
+            }
+            return new HoverInformationControlCreator(true);
+        }
+    }
+
+    /* Listeners and helpers. */
+
+    /** The shared color provider. */
+    private const ISharedTextColors fSharedColors;
+    /** The color tool. */
+    private const ColorTool fColorTool;
+    /** The mouse handler. */
+    private const MouseHandler fMouseHandler;
+    /** The hover. */
+    private const RevisionHover fHover;
+    /** The annotation listener. */
+    private const AnnotationListener fAnnotationListener;
+    /** The selection provider. */
+    private const RevisionSelectionProvider fRevisionSelectionProvider;
+    /**
+     * The list of revision listeners.
+     * @since 3.3.
+     */
+    private const ListenerList fRevisionListeners;
+
+    /* The context - column and viewer we are connected to. */
+
+    /** The vertical ruler column that delegates painting to this painter. */
+    private const IVerticalRulerColumn fColumn;
+    /** The parent ruler. */
+    private CompositeRuler fParentRuler;
+    /** The column's control, typically a {@link Canvas}, possibly <code>null</code>. */
+    private Control fControl;
+    /** The text viewer that the column is attached to. */
+    private ITextViewer fViewer;
+    /** The viewer's text widget. */
+    private StyledText fWidget;
+
+    /* The models we operate on. */
+
+    /** The revision model object. */
+    private RevisionInformation fRevisionInfo;
+    /** The line differ. */
+    private ILineDiffer fLineDiffer= null;
+    /** The annotation model. */
+    private IAnnotationModel fAnnotationModel= null;
+    /** The background color, possibly <code>null</code>. */
+    private Color fBackground;
+
+    /* Cache. */
+
+    /** The cached list of ranges adapted to quick diff. */
+    private List fRevisionRanges= null;
+    /** The annotations created for the overview ruler temporary display. */
+    private List fAnnotations;
+
+    /* State */
+
+    /** The current focus line, -1 for none. */
+    private int fFocusLine= -1;
+    /** The current focus region, <code>null</code> if none. */
+    private RevisionRange fFocusRange= null;
+    /** The current focus revision, <code>null</code> if none. */
+    private Revision fFocusRevision= null;
+    /**
+     * The currently selected revision, <code>null</code> if none. The difference between
+     * {@link #fFocusRevision} and {@link #fSelectedRevision} may not be obvious: the focus revision
+     * is the one focused by the mouse (by hovering over a block of the revision), while the
+     * selected revision is sticky, i.e. is not removed when the mouse leaves the ruler.
+     *
+     * @since 3.3
+     */
+    private Revision fSelectedRevision= null;
+    /** <code>true</code> if the mouse wheel handler is installed, <code>false</code> otherwise. */
+    private bool fWheelHandlerInstalled= false;
+    /**
+     * The revision rendering mode.
+     */
+    private IRevisionRulerColumnExtension_RenderingMode fRenderingMode;
+    /**
+     * The required with in characters.
+     * @since 3.3
+     */
+    private int fRequiredWidth= -1;
+    /**
+     * The width of the revision field in chars to compute {@link #fAuthorInset} from.
+     * @since 3.3
+     */
+    private int fRevisionIdChars= 0;
+    /**
+     * <code>true</code> to show revision ids, <code>false</code> otherwise.
+     * @since 3.3
+     */
+    private bool fShowRevision= false;
+    /**
+     * <code>true</code> to show the author, <code>false</code> otherwise.
+     * @since 3.3
+     */
+    private bool fShowAuthor= false;
+    /**
+     * The author inset in pixels for when author *and* revision id are shown.
+     * @since 3.3
+     */
+    private int fAuthorInset;
+    /**
+     * The remembered ruler width (as changing the ruler width triggers recomputation of the colors.
+     * @since 3.3
+     */
+    private int fLastWidth= -1;
+
+    /**
+     * Creates a new revision painter for a vertical ruler column.
+     *
+     * @param column the column that will delegate{@link #paint(GC, ILineRange) painting} to the
+     *        newly created painter.
+     * @param sharedColors a shared colors object to store shaded colors in
+     */
+    public this(IVerticalRulerColumn column, ISharedTextColors sharedColors) {
+
+        fColorTool= new ColorTool();
+        fMouseHandler= new MouseHandler();
+        fHover= new RevisionHover();
+        fAnnotationListener= new AnnotationListener();
+        fRevisionSelectionProvider= new RevisionSelectionProvider(this);
+        fRevisionListeners= new ListenerList(ListenerList.IDENTITY);
+        fAnnotations= new ArrayList();
+        fRenderingMode= IRevisionRulerColumnExtension_AUTHOR_SHADED_BY_AGE;
+
+        Assert.isLegal(column !is null);
+        Assert.isLegal(sharedColors !is null);
+        fColumn= column;
+        fSharedColors= sharedColors;
+    }
+
+    /**
+     * Sets the revision information to be drawn and triggers a redraw.
+     *
+     * @param info the revision information to show, <code>null</code> to draw none
+     */
+    public void setRevisionInformation(RevisionInformation info) {
+        if (fRevisionInfo !is info) {
+            fRequiredWidth= -1;
+            fRevisionIdChars= 0;
+            fRevisionInfo= info;
+            clearRangeCache();
+            updateFocusRange(null);
+            handleRevisionSelected(cast(Revision) null);
+            fColorTool.setInfo(info);
+            postRedraw();
+            informListeners();
+        }
+    }
+
+    /**
+     * Changes the rendering mode and triggers redrawing if needed.
+     *
+     * @param renderingMode the rendering mode
+     * @since 3.3
+     */
+    public void setRenderingMode(IRevisionRulerColumnExtension_RenderingMode renderingMode) {
+        Assert.isLegal(renderingMode !is null);
+        if (fRenderingMode !is renderingMode) {
+            fRenderingMode= renderingMode;
+            fColorTool.setInfo(fRevisionInfo);
+            postRedraw();
+        }
+    }
+
+    /**
+     * Sets the background color.
+     *
+     * @param background the background color, <code>null</code> for the platform's list
+     *        background
+     */
+    public void setBackground(Color background) {
+        fBackground= background;
+    }
+
+    /**
+     * Sets the parent ruler - the delegating column must call this method as soon as it creates its
+     * control.
+     *
+     * @param parentRuler the parent ruler
+     */
+    public void setParentRuler(CompositeRuler parentRuler) {
+        fParentRuler= parentRuler;
+    }
+
+    /**
+     * Delegates the painting of the quick diff colors to this painter. The painter will draw the
+     * color boxes onto the passed {@link GC} for all model (document) lines in
+     * <code>visibleModelLines</code>.
+     *
+     * @param gc the {@link GC} to draw onto
+     * @param visibleLines the lines (in document offsets) that are currently (perhaps only
+     *        partially) visible
+     */
+    public void paint(GC gc, ILineRange visibleLines) {
+        connectIfNeeded();
+        if (!isConnected())
+            return;
+
+        // compute the horizontal indent of the author for the case that we show revision
+        // and author
+        if (fShowAuthor && fShowRevision) {
+            char[] string= new char[fRevisionIdChars + 1];
+            Arrays.fill(string, '9');
+            if (string.length > 1) {
+                string[0]= '.';
+                string[1]= ' ';
+            }
+            fAuthorInset= gc.stringExtent(new_String(string)).x;
+        }
+
+        // recompute colors (show intense colors if ruler is narrow)
+        int width= getWidth();
+        if (width !is fLastWidth) {
+            fColorTool.setInfo(fRevisionInfo);
+            fLastWidth= width;
+        }
+
+        // draw change regions
+        List/* <RevisionRange> */ranges= getRanges(visibleLines);
+        for (Iterator it= ranges.iterator(); it.hasNext();) {
+            RevisionRange region= cast(RevisionRange) it.next();
+            paintRange(region, gc);
+        }
+    }
+
+    /**
+     * Ensures that the column is fully instantiated, i.e. has a control, and that the viewer is
+     * visible.
+     */
+    private void connectIfNeeded() {
+        if (isConnected() || fParentRuler is null)
+            return;
+
+        fViewer= fParentRuler.getTextViewer();
+        if (fViewer is null)
+            return;
+
+        fWidget= fViewer.getTextWidget();
+        if (fWidget is null)
+            return;
+
+        fControl= fColumn.getControl();
+        if (fControl is null)
+            return;
+
+        fControl.addMouseTrackListener(fMouseHandler);
+        fControl.addMouseMoveListener(fMouseHandler);
+        fControl.addListener(DWT.MouseUp, fMouseHandler);
+        fControl.addListener(DWT.MouseDown, fMouseHandler);
+        fControl.addDisposeListener(new class()  DisposeListener {
+            /*
+             * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent)
+             */
+            public void widgetDisposed(DisposeEvent e) {
+                handleDispose();
+            }
+        });
+
+        fRevisionSelectionProvider.install(fViewer);
+    }
+
+    /**
+     * Returns <code>true</code> if the column is fully connected.
+     *
+     * @return <code>true</code> if the column is fully connected, false otherwise
+     */
+    private bool isConnected() {
+        return fControl !is null;
+    }
+
+    /**
+     * Sets the annotation model.
+     *
+     * @param model the annotation model, possibly <code>null</code>
+     * @see IVerticalRulerColumn#setModel(IAnnotationModel)
+     */
+    public void setModel(IAnnotationModel model) {
+        IAnnotationModel diffModel;
+        if ( cast(IAnnotationModelExtension)model )
+            diffModel= (cast(IAnnotationModelExtension) model).getAnnotationModel(stringcast(IChangeRulerColumn.QUICK_DIFF_MODEL_ID));
+        else
+            diffModel= model;
+
+        setDiffer(diffModel);
+        setAnnotationModel(model);
+    }
+
+    /**
+     * Sets the annotation model.
+     *
+     * @param model the annotation model.
+     */
+    private void setAnnotationModel(IAnnotationModel model) {
+        if (fAnnotationModel !is model)
+            fAnnotationModel= model;
+    }
+
+    /**
+     * Sets the line differ.
+     *
+     * @param differ the line differ or <code>null</code> if none
+     */
+    private void setDiffer(IAnnotationModel differ) {
+        if ( cast(ILineDiffer)differ  || differ is null) {
+            if ( cast(Object)fLineDiffer !is cast(Object)differ) {
+                if (fLineDiffer !is null)
+                    (cast(IAnnotationModel) fLineDiffer).removeAnnotationModelListener(fAnnotationListener);
+                fLineDiffer= cast(ILineDiffer) differ;
+                if (fLineDiffer !is null)
+                    (cast(IAnnotationModel) fLineDiffer).addAnnotationModelListener(fAnnotationListener);
+            }
+        }
+    }
+
+    /**
+     * Disposes of the painter's resources.
+     */
+    private void handleDispose() {
+        updateFocusLine(-1);
+
+        if (fLineDiffer !is null) {
+            (cast(IAnnotationModel) fLineDiffer).removeAnnotationModelListener(fAnnotationListener);
+            fLineDiffer= null;
+        }
+
+        fRevisionSelectionProvider.uninstall();
+    }
+
+    /**
+     * Paints a single change region onto <code>gc</code>.
+     *
+     * @param range the range to paint
+     * @param gc the {@link GC} to paint on
+     */
+    private void paintRange(RevisionRange range, GC gc) {
+        ILineRange widgetRange= modelLinesToWidgetLines(range);
+        if (widgetRange is null)
+            return;
+
+        Revision revision= range.getRevision();
+        bool drawArmedFocus= range is fMouseHandler.fMouseDownRegion;
+        bool drawSelection= !drawArmedFocus && revision is fSelectedRevision;
+        bool drawFocus= !drawSelection && !drawArmedFocus && revision is fFocusRevision;
+        Rectangle box= computeBoxBounds(widgetRange);
+
+        gc.setBackground(lookupColor(revision, false));
+        if (drawArmedFocus) {
+            Color foreground= gc.getForeground();
+            Color focusColor= lookupColor(revision, true);
+            gc.setForeground(focusColor);
+            gc.fillRectangle(box);
+            gc.drawRectangle(box.x, box.y, box.width - 1, box.height - 1); // highlight box
+            gc.drawRectangle(box.x + 1, box.y + 1, box.width - 3, box.height - 3); // inner highlight box
+            gc.setForeground(foreground);
+        } else if (drawFocus || drawSelection) {
+            Color foreground= gc.getForeground();
+            Color focusColor= lookupColor(revision, true);
+            gc.setForeground(focusColor);
+            gc.fillRectangle(box);
+            gc.drawRectangle(box.x, box.y, box.width - 1, box.height - 1); // highlight box
+            gc.setForeground(foreground);
+        } else {
+            gc.fillRectangle(box);
+        }
+
+        if ((fShowAuthor || fShowRevision)) {
+            int indentation= 1;
+            int baselineBias= getBaselineBias(gc, widgetRange.getStartLine());
+            if (fShowAuthor && fShowRevision) {
+                gc.drawString(revision.getId(), indentation, box.y + baselineBias, true);
+                gc.drawString(revision.getAuthor(), fAuthorInset, box.y + baselineBias, true);
+            } else if (fShowAuthor) {
+                gc.drawString(revision.getAuthor(), indentation, box.y + baselineBias, true);
+            } else if (fShowRevision) {
+                gc.drawString(revision.getId(), indentation, box.y + baselineBias, true);
+            }
+        }
+    }
+
+    /**
+     * Returns the difference between the baseline of the widget and the
+     * baseline as specified by the font for <code>gc</code>. When drawing
+     * line numbers, the returned bias should be added to obtain text lined up
+     * on the correct base line of the text widget.
+     *
+     * @param gc the <code>GC</code> to get the font metrics from
+     * @param widgetLine the widget line
+     * @return the baseline bias to use when drawing text that is lined up with
+     *         <code>fCachedTextWidget</code>
+     * @since 3.3
+     */
+    private int getBaselineBias(GC gc, int widgetLine) {
+        /*
+         * https://bugs.eclipse.org/bugs/show_bug.cgi?id=62951
+         * widget line height may be more than the font height used for the
+         * line numbers, since font styles (bold, italics...) can have larger
+         * font metrics than the simple font used for the numbers.
+         */
+        int offset= fWidget.getOffsetAtLine(widgetLine);
+        int widgetBaseline= fWidget.getBaseline(offset);
+
+        FontMetrics fm = gc.getFontMetrics();
+        int fontBaseline = fm.getAscent() + fm.getLeading();
+        int baselineBias= widgetBaseline - fontBaseline;
+        return Math.max(0, baselineBias);
+    }
+
+    /**
+     * Looks up the color for a certain revision.
+     *
+     * @param revision the revision to get the color for
+     * @param focus <code>true</code> if it is the focus revision
+     * @return the color for the revision
+     */
+    private Color lookupColor(Revision revision, bool focus) {
+        return fSharedColors.getColor(fColorTool.getColor(revision, focus));
+    }
+
+    /**
+     * Returns the revision range that contains the given line, or
+     * <code>null</code> if there is none.
+     *
+     * @param line the line of interest
+     * @return the corresponding <code>RevisionRange</code> or <code>null</code>
+     */
+    private RevisionRange getRange(int line) {
+        List ranges= getRangeCache();
+
+        if (ranges.isEmpty() || line is -1)
+            return null;
+
+        for (Iterator it= ranges.iterator(); it.hasNext();) {
+            RevisionRange range= cast(RevisionRange) it.next();
+            if (contains(range, line))
+                return range;
+        }
+
+        // line may be right after the last region
+        RevisionRange lastRegion= cast(RevisionRange) ranges.get(ranges.size() - 1);
+        if (line is end(lastRegion))
+            return lastRegion;
+        return null;
+    }
+
+    /**
+     * Returns the sublist of all <code>RevisionRange</code>s that intersect with the given lines.
+     *
+     * @param lines the model based lines of interest
+     * @return elementType: RevisionRange
+     */
+    private List getRanges(ILineRange lines) {
+        List ranges= getRangeCache();
+
+        // return the interesting subset
+        int end_= end(lines);
+        int first= -1, last= -1;
+        for (int i= 0; i < ranges.size(); i++) {
+            RevisionRange range= cast(RevisionRange) ranges.get(i);
+            int rangeEnd= end(range);
+            if (first is -1 && rangeEnd > lines.getStartLine())
+                first= i;
+            if (first !is -1 && rangeEnd > end_) {
+                last= i;
+                break;
+            }
+        }
+        if (first is -1)
+            return Collections.EMPTY_LIST;
+        if (last is -1)
+            last= ranges.size() - 1; // bottom index may be one too much
+
+        return ranges.subList(first, last + 1);
+    }
+
+    /**
+     * Gets all change ranges of the revisions in the revision model and adapts them to the current
+     * quick diff information. The list is cached.
+     *
+     * @return the list of all change regions, with diff information applied
+     */
+    private List getRangeCache() {
+        if (fRevisionRanges is null) {
+            if (fRevisionInfo is null) {
+                fRevisionRanges= Collections.EMPTY_LIST;
+            } else {
+                Hunk[] hunks= HunkComputer.computeHunks(fLineDiffer, fViewer.getDocument().getNumberOfLines());
+                fRevisionInfo.applyDiff(hunks);
+                fRevisionRanges= fRevisionInfo.getRanges();
+                updateOverviewAnnotations();
+                informListeners();
+            }
+        }
+
+        return fRevisionRanges;
+    }
+
+    /**
+     * Clears the range cache.
+     *
+     * @since 3.3
+     */
+    private void clearRangeCache() {
+        fRevisionRanges= null;
+    }
+
+    /**
+     * Returns <code>true</code> if <code>range</code> contains <code>line</code>. A line is
+     * not contained in a range if it is the range's exclusive end line.
+     *
+     * @param range the range to check whether it contains <code>line</code>
+     * @param line the line the line
+     * @return <code>true</code> if <code>range</code> contains <code>line</code>,
+     *         <code>false</code> if not
+     */
+    private static bool contains(ILineRange range, int line) {
+        return range.getStartLine() <= line && end(range) > line;
+    }
+
+    /**
+     * Computes the end index of a line range.
+     *
+     * @param range a line range
+     * @return the last line (exclusive) of <code>range</code>
+     */
+    private static int end(ILineRange range) {
+        return range.getStartLine() + range.getNumberOfLines();
+    }
+
+    /**
+     * Returns the visible extent of a document line range in widget lines.
+     *
+     * @param range the document line range
+     * @return the visible extent of <code>range</code> in widget lines
+     */
+    private ILineRange modelLinesToWidgetLines(ILineRange range) {
+        int widgetStartLine= -1;
+        int widgetEndLine= -1;
+        if ( cast(ITextViewerExtension5)fViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) fViewer;
+            int modelEndLine= end(range);
+            for (int modelLine= range.getStartLine(); modelLine < modelEndLine; modelLine++) {
+                int widgetLine= extension.modelLine2WidgetLine(modelLine);
+                if (widgetLine !is -1) {
+                    if (widgetStartLine is -1)
+                        widgetStartLine= widgetLine;
+                    widgetEndLine= widgetLine;
+                }
+            }
+        } else {
+            IRegion region= fViewer.getVisibleRegion();
+            IDocument document= fViewer.getDocument();
+            try {
+                int visibleStartLine= document.getLineOfOffset(region.getOffset());
+                int visibleEndLine= document.getLineOfOffset(region.getOffset() + region.getLength());
+                widgetStartLine= Math.max(0, range.getStartLine() - visibleStartLine);
+                widgetEndLine= Math.min(visibleEndLine, end(range) - 1);
+            } catch (BadLocationException x) {
+                ExceptionPrintStackTrace(x);
+                // ignore and return null
+            }
+        }
+        if (widgetStartLine is -1 || widgetEndLine is -1)
+            return null;
+        return new LineRange(widgetStartLine, widgetEndLine - widgetStartLine + 1);
+    }
+
+    /**
+     * Returns the revision hover.
+     *
+     * @return the revision hover
+     */
+    public IAnnotationHover getHover() {
+        return fHover;
+    }
+
+    /**
+     * Computes and returns the bounds of the rectangle corresponding to a widget line range. The
+     * rectangle is in pixel coordinates relative to the text widget's
+     * {@link StyledText#getClientArea() client area} and has the width of the ruler.
+     *
+     * @param range the widget line range
+     * @return the box bounds corresponding to <code>range</code>
+     */
+    private Rectangle computeBoxBounds(ILineRange range) {
+        int y1= fWidget.getLinePixel(range.getStartLine());
+        int y2= fWidget.getLinePixel(range.getStartLine() + range.getNumberOfLines());
+
+        return new Rectangle(0, y1, getWidth(), y2 - y1 - 1);
+    }
+
+    /**
+     * Shows (or hides) the overview annotations.
+     */
+    private void updateOverviewAnnotations() {
+        if (fAnnotationModel is null)
+            return;
+
+        Revision revision= fFocusRevision !is null ? fFocusRevision : fSelectedRevision;
+
+        Map added= null;
+        if (revision !is null) {
+            added= new HashMap();
+            for (Iterator it= revision.getRegions().iterator(); it.hasNext();) {
+                RevisionRange range= cast(RevisionRange) it.next();
+                try {
+                    IRegion charRegion= toCharRegion(range);
+                    Position position= new Position(charRegion.getOffset(), charRegion.getLength());
+                    Annotation annotation= new RevisionAnnotation(revision.getId());
+                    added.put(annotation, position);
+                } catch (BadLocationException x) {
+                    // ignore - document was changed, show no annotations
+                }
+            }
+        }
+
+        if ( cast(IAnnotationModelExtension)fAnnotationModel ) {
+            IAnnotationModelExtension ext= cast(IAnnotationModelExtension) fAnnotationModel;
+            ext.replaceAnnotations(arraycast!(Annotation)( fAnnotations.toArray()), added);
+        } else {
+            for (Iterator it= fAnnotations.iterator(); it.hasNext();) {
+                Annotation annotation= cast(Annotation) it.next();
+                fAnnotationModel.removeAnnotation(annotation);
+            }
+            if (added !is null) {
+                for (Iterator it= added.entrySet().iterator(); it.hasNext();) {
+                    Map.Entry entry= cast(Map.Entry) it.next();
+                    fAnnotationModel.addAnnotation(cast(Annotation) entry.getKey(), cast(Position) entry.getValue());
+                }
+            }
+        }
+        fAnnotations.clear();
+        if (added !is null)
+            fAnnotations.addAll(added.keySet());
+
+    }
+
+    /**
+     * Returns the character offset based region of a line range.
+     *
+     * @param lines the line range to convert
+     * @return the character offset range corresponding to <code>range</code>
+     * @throws BadLocationException if the line range is not within the document bounds
+     */
+    private IRegion toCharRegion(ILineRange lines)  {
+        IDocument document= fViewer.getDocument();
+        int offset= document.getLineOffset(lines.getStartLine());
+        int nextLine= end(lines);
+        int endOffset;
+        if (nextLine >= document.getNumberOfLines())
+            endOffset= document.getLength();
+        else
+            endOffset= document.getLineOffset(nextLine);
+        return new Region(offset, endOffset - offset);
+    }
+
+    /**
+     * Handles the selection of a revision and informs listeners.
+     *
+     * @param revision the selected revision, <code>null</code> for none
+     */
+    void handleRevisionSelected(Revision revision) {
+        fSelectedRevision= revision;
+        fRevisionSelectionProvider.revisionSelected(revision);
+        updateOverviewAnnotations();
+        postRedraw();
+    }
+
+    /**
+     * Handles the selection of a revision id and informs listeners
+     *
+     * @param id the selected revision id
+     */
+    void handleRevisionSelected(String id) {
+        Assert.isLegal(id !is null);
+        if (fRevisionInfo is null)
+            return;
+
+        for (Iterator it= fRevisionInfo.getRevisions().iterator(); it.hasNext();) {
+            Revision revision= cast(Revision) it.next();
+            if (id.equals(revision.getId())) {
+                handleRevisionSelected(revision);
+                return;
+            }
+        }
+
+        // clear selection if it does not exist
+        handleRevisionSelected(cast(Revision) null);
+    }
+
+    /**
+     * Returns the selection provider.
+     *
+     * @return the selection provider
+     */
+    public RevisionSelectionProvider getRevisionSelectionProvider() {
+        return fRevisionSelectionProvider;
+    }
+
+    /**
+     * Updates the focus line with a new line.
+     *
+     * @param line the new focus line, -1 for no focus
+     */
+    private void updateFocusLine(int line) {
+        if (fFocusLine !is line)
+            onFocusLineChanged(fFocusLine, line);
+    }
+
+    /**
+     * Handles a changing focus line.
+     *
+     * @param previousLine the old focus line (-1 for no focus)
+     * @param nextLine the new focus line (-1 for no focus)
+     */
+    private void onFocusLineChanged(int previousLine, int nextLine) {
+        if (DEBUG)
+            System.out_.println(Format("line: {} > {}", previousLine, nextLine)); //$NON-NLS-1$ //$NON-NLS-2$
+        fFocusLine= nextLine;
+        RevisionRange region= getRange(nextLine);
+        updateFocusRange(region);
+    }
+
+    /**
+     * Updates the focus range.
+     *
+     * @param range the new focus range, <code>null</code> for no focus
+     */
+    private void updateFocusRange(RevisionRange range) {
+        if (range !is fFocusRange)
+            onFocusRangeChanged(fFocusRange, range);
+    }
+
+    /**
+     * Handles a changing focus range.
+     *
+     * @param previousRange the old focus range (<code>null</code> for no focus)
+     * @param nextRange the new focus range (<code>null</code> for no focus)
+     */
+    private void onFocusRangeChanged(RevisionRange previousRange, RevisionRange nextRange) {
+        if (DEBUG)
+            System.out_.println(Format("range: {} > {}", previousRange, nextRange)); //$NON-NLS-1$ //$NON-NLS-2$
+        fFocusRange= nextRange;
+        Revision revision= nextRange is null ? null : nextRange.getRevision();
+        updateFocusRevision(revision);
+    }
+
+    private void updateFocusRevision(Revision revision) {
+        if (fFocusRevision !is revision)
+            onFocusRevisionChanged(fFocusRevision, revision);
+    }
+
+    /**
+     * Handles a changing focus revision.
+     *
+     * @param previousRevision the old focus revision (<code>null</code> for no focus)
+     * @param nextRevision the new focus revision (<code>null</code> for no focus)
+     */
+    private void onFocusRevisionChanged(Revision previousRevision, Revision nextRevision) {
+        if (DEBUG)
+            System.out_.println(Format("revision: {} > {}", previousRevision, nextRevision)); //$NON-NLS-1$ //$NON-NLS-2$
+        fFocusRevision= nextRevision;
+        uninstallWheelHandler();
+        installWheelHandler();
+        updateOverviewAnnotations();
+        redraw(); // pick up new highlights
+    }
+
+    /**
+     * Uninstalls the mouse wheel handler.
+     */
+    private void uninstallWheelHandler() {
+        fControl.removeListener(DWT.MouseWheel, cast(Listener)fMouseHandler);
+        fWheelHandlerInstalled= false;
+    }
+
+    /**
+     * Installs the mouse wheel handler.
+     */
+    private void installWheelHandler() {
+        if (fFocusRevision !is null && !fWheelHandlerInstalled) {
+            //FIXME: does not work on Windows, because Canvas cannot get focus and therefore does not send out mouse wheel events:
+            //https://bugs.eclipse.org/bugs/show_bug.cgi?id=81189
+            //see also https://bugs.eclipse.org/bugs/show_bug.cgi?id=75766
+            fControl.addListener(DWT.MouseWheel, fMouseHandler);
+            fWheelHandlerInstalled= true;
+        }
+    }
+
+    /**
+     * Handles a mouse wheel event.
+     *
+     * @param event the mouse wheel event
+     */
+    private void handleMouseWheel(Event event) {
+        bool up= event.count > 0;
+        int documentHoverLine= fFocusLine;
+
+        ILineRange nextWidgetRange= null;
+        ILineRange last= null;
+        List ranges= fFocusRevision.getRegions();
+        if (up) {
+            for (Iterator it= ranges.iterator(); it.hasNext();) {
+                RevisionRange range= cast(RevisionRange) it.next();
+                ILineRange widgetRange= modelLinesToWidgetLines(range);
+                if (contains(range, documentHoverLine)) {
+                    nextWidgetRange= last;
+                    break;
+                }
+                if (widgetRange !is null)
+                    last= widgetRange;
+            }
+        } else {
+            for (ListIterator it= ranges.listIterator(ranges.size()); it.hasPrevious();) {
+                RevisionRange range= cast(RevisionRange) it.previous();
+                ILineRange widgetRange= modelLinesToWidgetLines(range);
+                if (contains(range, documentHoverLine)) {
+                    nextWidgetRange= last;
+                    break;
+                }
+                if (widgetRange !is null)
+                    last= widgetRange;
+            }
+        }
+
+        if (nextWidgetRange is null)
+            return;
+
+        int widgetCurrentFocusLine= modelLinesToWidgetLines(new LineRange(documentHoverLine, 1)).getStartLine();
+        int widgetNextFocusLine= nextWidgetRange.getStartLine();
+        int newTopPixel= fWidget.getTopPixel() + JFaceTextUtil.computeLineHeight(fWidget, widgetCurrentFocusLine, widgetNextFocusLine, widgetNextFocusLine - widgetCurrentFocusLine);
+        fWidget.setTopPixel(newTopPixel);
+        if (newTopPixel < 0) {
+            Point cursorLocation= fWidget.getDisplay().getCursorLocation();
+            cursorLocation.y+= newTopPixel;
+            fWidget.getDisplay().setCursorLocation(cursorLocation);
+        } else {
+            int topPixel= fWidget.getTopPixel();
+            if (topPixel < newTopPixel) {
+                Point cursorLocation= fWidget.getDisplay().getCursorLocation();
+                cursorLocation.y+= newTopPixel - topPixel;
+                fWidget.getDisplay().setCursorLocation(cursorLocation);
+            }
+        }
+        updateFocusLine(toDocumentLineNumber(fWidget.toControl(fWidget.getDisplay().getCursorLocation()).y));
+        immediateUpdate();
+    }
+
+    /**
+     * Triggers a redraw in the display thread.
+     */
+    private final void postRedraw() {
+        if (isConnected() && !fControl.isDisposed()) {
+            Display d= fControl.getDisplay();
+            if (d !is null) {
+                d.asyncExec(new class()  Runnable {
+                    public void run() {
+                        redraw();
+                    }
+                });
+            }
+        }
+    }
+
+    /**
+     * Translates a y coordinate in the pixel coordinates of the column's control to a document line
+     * number.
+     *
+     * @param y the y coordinate
+     * @return the corresponding document line, -1 for no line
+     * @see CompositeRuler#toDocumentLineNumber(int)
+     */
+    private int toDocumentLineNumber(int y) {
+        return fParentRuler.toDocumentLineNumber(y);
+    }
+
+    /**
+     * Triggers redrawing of the column.
+     */
+    private void redraw() {
+        fColumn.redraw();
+    }
+
+    /**
+     * Triggers immediate redrawing of the entire column - use with care.
+     */
+    private void immediateUpdate() {
+        fParentRuler.immediateUpdate();
+    }
+
+    /**
+     * Returns the width of the column.
+     *
+     * @return the width of the column
+     */
+    private int getWidth() {
+        return fColumn.getWidth();
+    }
+
+    /**
+     * Returns the System background color for list widgets.
+     *
+     * @return the System background color for list widgets
+     */
+    private Color getBackground() {
+        if (fBackground is null)
+            return fWidget.getDisplay().getSystemColor(DWT.COLOR_LIST_BACKGROUND);
+        return fBackground;
+    }
+
+    /**
+     * Sets the hover later returned by {@link #getHover()}.
+     *
+     * @param hover the hover
+     */
+    public void setHover(IAnnotationHover hover) {
+        // TODO ignore for now - must make revision hover settable from outside
+    }
+
+    /**
+     * Returns <code>true</code> if the receiver can provide a hover for a certain document line.
+     *
+     * @param activeLine the document line of interest
+     * @return <code>true</code> if the receiver can provide a hover
+     */
+    public bool hasHover(int activeLine) {
+        return cast(ISourceViewer)fViewer && fHover.getHoverLineRange(cast(ISourceViewer) fViewer, activeLine) !is null;
+    }
+
+    /**
+     * Returns the revision at a certain document offset, or <code>null</code> for none.
+     *
+     * @param offset the document offset
+     * @return the revision at offset, or <code>null</code> for none
+     */
+    Revision getRevision(int offset) {
+        IDocument document= fViewer.getDocument();
+        int line;
+        try {
+            line= document.getLineOfOffset(offset);
+        } catch (BadLocationException x) {
+            return null;
+        }
+        if (line !is -1) {
+            RevisionRange range= getRange(line);
+            if (range !is null)
+                return range.getRevision();
+        }
+        return null;
+    }
+
+    /**
+     * Returns <code>true</code> if a revision model has been set, <code>false</code> otherwise.
+     *
+     * @return <code>true</code> if a revision model has been set, <code>false</code> otherwise
+     */
+    public bool hasInformation() {
+        return fRevisionInfo !is null;
+    }
+
+    /**
+     * Returns the width in chars required to display information.
+     *
+     * @return the width in chars required to display information
+     * @since 3.3
+     */
+    public int getRequiredWidth() {
+        if (fRequiredWidth is -1) {
+            if (hasInformation() && (fShowRevision || fShowAuthor)) {
+                int revisionWidth= 0;
+                int authorWidth= 0;
+                for (Iterator it= fRevisionInfo.getRevisions().iterator(); it.hasNext();) {
+                    Revision revision= cast(Revision) it.next();
+                    revisionWidth= Math.max(revisionWidth, revision.getId().length());
+                    authorWidth= Math.max(authorWidth, revision.getAuthor().length());
+                }
+                fRevisionIdChars= revisionWidth + 1;
+                if (fShowAuthor && fShowRevision)
+                    fRequiredWidth= revisionWidth + authorWidth + 2;
+                else if (fShowAuthor)
+                    fRequiredWidth= authorWidth + 1;
+                else
+                    fRequiredWidth= revisionWidth + 1;
+            } else {
+                fRequiredWidth= 0;
+            }
+        }
+        return fRequiredWidth;
+    }
+
+    /**
+     * Enables showing the revision id.
+     *
+     * @param show <code>true</code> to show the revision, <code>false</code> to hide it
+     */
+    public void showRevisionId(bool show) {
+        if (fShowRevision !is show) {
+            fRequiredWidth= -1;
+            fRevisionIdChars= 0;
+            fShowRevision= show;
+            postRedraw();
+        }
+    }
+
+    /**
+     * Enables showing the revision author.
+     *
+     * @param show <code>true</code> to show the author, <code>false</code> to hide it
+     */
+    public void showRevisionAuthor(bool show) {
+        if (fShowAuthor !is show) {
+            fRequiredWidth= -1;
+            fRevisionIdChars= 0;
+            fShowAuthor= show;
+            postRedraw();
+        }
+    }
+
+    /**
+     * Adds a revision listener.
+     *
+     * @param listener the listener
+     * @since 3.3
+     */
+    public void addRevisionListener(IRevisionListener listener) {
+        fRevisionListeners.add(cast(Object)listener);
+    }
+
+    /**
+     * Removes a revision listener.
+     *
+     * @param listener the listener
+     * @since 3.3
+     */
+    public void removeRevisionListener(IRevisionListener listener) {
+        fRevisionListeners.remove(cast(Object)listener);
+    }
+
+    /**
+     * Informs the revision listeners about a change.
+     *
+     * @since 3.3
+     */
+    private void informListeners() {
+        if (fRevisionInfo is null || fRevisionListeners.isEmpty())
+            return;
+
+        RevisionEvent event= new RevisionEvent(fRevisionInfo);
+        Object[] listeners= fRevisionListeners.getListeners();
+        for (int i= 0; i < listeners.length; i++) {
+            IRevisionListener listener= cast(IRevisionListener) listeners[i];
+            listener.revisionInformationChanged(event);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/revisions/RevisionSelectionProvider.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.revisions.RevisionSelectionProvider;
+
+import dwtx.jface.internal.text.revisions.HunkComputer; // packageimport
+import dwtx.jface.internal.text.revisions.LineIndexOutOfBoundsException; // packageimport
+import dwtx.jface.internal.text.revisions.Hunk; // packageimport
+import dwtx.jface.internal.text.revisions.Colors; // packageimport
+import dwtx.jface.internal.text.revisions.ChangeRegion; // packageimport
+import dwtx.jface.internal.text.revisions.Range; // packageimport
+import dwtx.jface.internal.text.revisions.RevisionPainter; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwtx.core.runtime.ListenerList;
+import dwtx.jface.text.ITextSelection;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.revisions.Revision;
+import dwtx.jface.viewers.IPostSelectionProvider;
+import dwtx.jface.viewers.ISelection;
+import dwtx.jface.viewers.ISelectionChangedListener;
+import dwtx.jface.viewers.ISelectionProvider;
+import dwtx.jface.viewers.IStructuredSelection;
+import dwtx.jface.viewers.SelectionChangedEvent;
+import dwtx.jface.viewers.StructuredSelection;
+
+/**
+ * A selection provider for annotate revisions. Selections of a revision can currently happen in
+ * following ways - note that this list may be changed in the future:
+ * <ul>
+ * <li>when the user clicks the revision ruler with the mouse</li>
+ * <li>when the caret is moved to a revision's line (only on post-selection)</li>
+ * </ul>
+ * <p>
+ * Calling {@link #setSelection(ISelection)} will set the current sticky revision on the ruler.
+ * </p>
+ *
+ * @since 3.2
+ */
+public final class RevisionSelectionProvider : ISelectionProvider {
+
+    /**
+     * Post selection listener on the viewer that remembers the selection provider it is registered
+     * with.
+     */
+    private final class PostSelectionListener : ISelectionChangedListener {
+        private const IPostSelectionProvider fPostProvider;
+
+        public this(IPostSelectionProvider postProvider) {
+            postProvider.addPostSelectionChangedListener(this);
+            fPostProvider= postProvider;
+        }
+
+        public void selectionChanged(SelectionChangedEvent event) {
+            ISelection selection= event.getSelection();
+            if ( cast(ITextSelection)selection ) {
+                ITextSelection ts= cast(ITextSelection) selection;
+                int offset= ts.getOffset();
+                setSelectedRevision(fPainter.getRevision(offset));
+            }
+
+        }
+
+        public void dispose() {
+            fPostProvider.removePostSelectionChangedListener(this);
+        }
+    }
+
+    private const RevisionPainter fPainter;
+    private const ListenerList fListeners;
+
+    /**
+     * The text viewer once we are installed, <code>null</code> if not installed.
+     */
+    private ITextViewer fViewer;
+    /**
+     * The selection listener on the viewer, or <code>null</code>.
+     */
+    private PostSelectionListener fSelectionListener;
+    /**
+     * The last selection, or <code>null</code>.
+     */
+    private Revision fSelection;
+    /**
+     * Incoming selection changes are ignored while sending out events.
+     *
+     * @since 3.3
+     */
+    private bool fIgnoreEvents= false;
+
+    /**
+     * Creates a new selection provider.
+     *
+     * @param painter the painter that the created provider interacts with
+     */
+    this(RevisionPainter painter) {
+        fListeners= new ListenerList();
+        fPainter= painter;
+    }
+
+    /*
+     * @see dwtx.jface.viewers.ISelectionProvider#addSelectionChangedListener(dwtx.jface.viewers.ISelectionChangedListener)
+     */
+    public void addSelectionChangedListener(ISelectionChangedListener listener) {
+        fListeners.add(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.viewers.ISelectionProvider#removeSelectionChangedListener(dwtx.jface.viewers.ISelectionChangedListener)
+     */
+    public void removeSelectionChangedListener(ISelectionChangedListener listener) {
+        fListeners.remove(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.viewers.ISelectionProvider#getSelection()
+     */
+    public ISelection getSelection() {
+        if (fSelection is null)
+            return StructuredSelection.EMPTY;
+        return new StructuredSelection(fSelection);
+    }
+
+    /*
+     * @see dwtx.jface.viewers.ISelectionProvider#setSelection(dwtx.jface.viewers.ISelection)
+     */
+    public void setSelection(ISelection selection) {
+        if (fIgnoreEvents)
+            return;
+        if ( cast(IStructuredSelection)selection ) {
+            Object first= (cast(IStructuredSelection) selection).getFirstElement();
+            if ( cast(Revision)first )
+                fPainter.handleRevisionSelected(cast(Revision) first);
+            else if ( auto str = cast(ArrayWrapperString)first )
+                fPainter.handleRevisionSelected(str.array);
+            else if (selection.isEmpty())
+                fPainter.handleRevisionSelected(cast(Revision) null);
+        }
+    }
+
+    /**
+     * Installs the selection provider on the viewer.
+     *
+     * @param viewer the viewer on which we listen to for post selection events
+     */
+    void install(ITextViewer viewer) {
+        uninstall();
+        fViewer= viewer;
+        if (fViewer !is null) {
+            ISelectionProvider provider= fViewer.getSelectionProvider();
+            if ( cast(IPostSelectionProvider)provider ) {
+                IPostSelectionProvider postProvider= cast(IPostSelectionProvider) provider;
+                fSelectionListener= new PostSelectionListener(postProvider);
+            }
+        }
+    }
+
+    /**
+     * Uninstalls the selection provider.
+     */
+    void uninstall() {
+        fViewer= null;
+        if (fSelectionListener !is null) {
+            fSelectionListener.dispose();
+            fSelectionListener= null;
+        }
+    }
+
+    /**
+     * Private protocol used by {@link RevisionPainter} to signal selection of a revision.
+     *
+     * @param revision the selected revision, or <code>null</code> for none
+     */
+    void revisionSelected(Revision revision) {
+        setSelectedRevision(revision);
+    }
+
+    /**
+     * Updates the currently selected revision and sends out an event if it changed.
+     *
+     * @param revision the newly selected revision or <code>null</code> for none
+     */
+    private void setSelectedRevision(Revision revision) {
+        if (revision !is fSelection) {
+            fSelection= revision;
+            fireSelectionEvent();
+        }
+    }
+
+    private void fireSelectionEvent() {
+        fIgnoreEvents= true;
+        try {
+            ISelection selection= getSelection();
+            SelectionChangedEvent event= new SelectionChangedEvent(this, selection);
+
+            Object[] listeners= fListeners.getListeners();
+            for (int i= 0; i < listeners.length; i++)
+                (cast(ISelectionChangedListener) listeners[i]).selectionChanged(event);
+        } finally {
+            fIgnoreEvents= false;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/internal/text/source/DiffPainter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,539 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.internal.text.source.DiffPainter;
+
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.graphics.Color;
+import dwt.graphics.GC;
+import dwt.graphics.RGB;
+import dwt.widgets.Canvas;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.JFaceTextUtil;
+import dwtx.jface.text.source.CompositeRuler;
+import dwtx.jface.text.source.IAnnotationHover;
+import dwtx.jface.text.source.IAnnotationModel;
+import dwtx.jface.text.source.IAnnotationModelExtension;
+import dwtx.jface.text.source.IAnnotationModelListener;
+import dwtx.jface.text.source.IChangeRulerColumn;
+import dwtx.jface.text.source.ILineDiffInfo;
+import dwtx.jface.text.source.ILineDiffer;
+import dwtx.jface.text.source.ILineDifferExtension2;
+import dwtx.jface.text.source.ILineRange;
+import dwtx.jface.text.source.ISharedTextColors;
+import dwtx.jface.text.source.IVerticalRulerColumn;
+
+
+/**
+ * A strategy for painting the quick diff colors onto the vertical ruler column. It also manages the
+ * quick diff hover.
+ *
+ * @since 3.2
+ */
+public final class DiffPainter {
+    /**
+     * Internal listener class that will update the ruler when the underlying model changes.
+     */
+    private class AnnotationListener : IAnnotationModelListener {
+        /*
+         * @see dwtx.jface.text.source.IAnnotationModelListener#modelChanged(dwtx.jface.text.source.IAnnotationModel)
+         */
+        public void modelChanged(IAnnotationModel model) {
+            postRedraw();
+        }
+    }
+
+    /** The vertical ruler column that delegates painting to this painter. */
+    private const IVerticalRulerColumn fColumn;
+    /** The parent ruler. */
+    private CompositeRuler fParentRuler;
+    /** The column's control, typically a {@link Canvas}, possibly <code>null</code>. */
+    private Control fControl;
+    /** The text viewer that the column is attached to. */
+    private ITextViewer fViewer;
+    /** The viewer's text widget. */
+    private StyledText fWidget;
+    /** The line differ extracted from the annotation model. */
+    private ILineDiffer fLineDiffer= null;
+    /** Color for changed lines */
+    private Color fAddedColor;
+    /** Color for added lines */
+    private Color fChangedColor;
+    /** Color for the deleted line indicator */
+    private Color fDeletedColor;
+    /** The background color. */
+    private Color fBackground;
+    /** The ruler's hover */
+    private IAnnotationHover fHover;
+    /** The internal listener */
+    private const AnnotationListener fAnnotationListener;
+    /** The shared color provider, possibly <code>null</code>. */
+    private const ISharedTextColors fSharedColors;
+
+    /**
+     * Creates a new diff painter for a vertical ruler column.
+     *
+     * @param column the column that will delegate{@link #paint(GC, ILineRange) painting} to the
+     *        newly created painter.
+     * @param sharedColors a shared colors object to store shaded colors in, may be
+     *        <code>null</code>
+     */
+    public this(IVerticalRulerColumn column, ISharedTextColors sharedColors) {
+        fAnnotationListener= new AnnotationListener();
+        Assert.isLegal(column !is null);
+        fColumn= column;
+        fSharedColors= sharedColors;
+    }
+
+    /**
+     * Sets the parent ruler - the delegating column must call this method as soon as it creates its
+     * control.
+     *
+     * @param parentRuler the parent ruler
+     */
+    public void setParentRuler(CompositeRuler parentRuler) {
+        fParentRuler= parentRuler;
+    }
+
+    /**
+     * Sets the quick diff hover later returned by {@link #getHover()}.
+     *
+     * @param hover the hover
+     */
+    public void setHover(IAnnotationHover hover) {
+        fHover= hover;
+    }
+
+    /**
+     * Returns the quick diff hover set by {@link #setHover(IAnnotationHover)}.
+     *
+     * @return the quick diff hover set by {@link #setHover(IAnnotationHover)}
+     */
+    public IAnnotationHover getHover() {
+        return fHover;
+    }
+
+    /**
+     * Sets the background color.
+     *
+     * @param background the background color, <code>null</code> to use the platform's list background
+     */
+    public void setBackground(Color background) {
+        fBackground= background;
+    }
+
+    /**
+     * Delegates the painting of the quick diff colors to this painter. The painter will draw the
+     * color boxes onto the passed {@link GC} for all model (document) lines in
+     * <code>visibleModelLines</code>.
+     *
+     * @param gc the {@link GC} to draw onto
+     * @param visibleModelLines the lines (in document offsets) that are currently (perhaps only
+     *        partially) visible
+     */
+    public void paint(GC gc, ILineRange visibleModelLines) {
+        connectIfNeeded();
+        if (!isConnected())
+            return;
+
+        // draw diff info
+        final int lastLine= end(visibleModelLines);
+        final int width= getWidth();
+        final Color deletionColor= getDeletionColor();
+        for (int line= visibleModelLines.getStartLine(); line < lastLine; line++) {
+            paintLine(line, gc, width, deletionColor);
+        }
+    }
+
+    /**
+     * Ensures that the column is fully instantiated, i.e. has a control, and that the viewer is
+     * visible.
+     */
+    private void connectIfNeeded() {
+        if (isConnected() || fParentRuler is null)
+            return;
+
+        fViewer= fParentRuler.getTextViewer();
+        if (fViewer is null)
+            return;
+
+        fWidget= fViewer.getTextWidget();
+        if (fWidget is null)
+            return;
+
+        fControl= fColumn.getControl();
+        if (fControl is null)
+            return;
+
+        fControl.addDisposeListener(new class()  DisposeListener {
+            /*
+             * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent)
+             */
+            public void widgetDisposed(DisposeEvent e) {
+                handleDispose();
+            }
+        });
+    }
+
+    /**
+     * Returns <code>true</code> if the column is fully connected.
+     *
+     * @return <code>true</code> if the column is fully connected, false otherwise
+     */
+    private bool isConnected() {
+        return fControl !is null;
+    }
+
+    /**
+     * Disposes of this painter and releases any resources.
+     */
+    private void handleDispose() {
+        if (fLineDiffer !is null) {
+            (cast(IAnnotationModel) fLineDiffer).removeAnnotationModelListener(fAnnotationListener);
+            fLineDiffer= null;
+        }
+    }
+
+    /**
+     * Paints a single model line onto <code>gc</code>.
+     *
+     * @param line the model line to paint
+     * @param gc the {@link GC} to paint onto
+     * @param width the width of the column
+     * @param deletionColor the background color used to indicate deletions
+     */
+    private void paintLine(int line, GC gc, int width, Color deletionColor) {
+        int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fViewer, line);
+        if (widgetLine is -1)
+            return;
+
+        ILineDiffInfo info= getDiffInfo(line);
+
+        if (info !is null) {
+            int y= fWidget.getLinePixel(widgetLine);
+            int lineHeight= fWidget.getLineHeight(fWidget.getOffsetAtLine(widgetLine));
+
+            // draw background color if special
+            if (hasSpecialColor(info)) {
+                gc.setBackground(getColor(info));
+                gc.fillRectangle(0, y, width, lineHeight);
+            }
+
+            /* Deletion Indicator: Simply a horizontal line */
+            int delBefore= info.getRemovedLinesAbove();
+            int delBelow= info.getRemovedLinesBelow();
+            if (delBefore > 0 || delBelow > 0) {
+                gc.setForeground(deletionColor);
+                if (delBefore > 0)
+                    gc.drawLine(0, y, width, y);
+                if (delBelow > 0)
+                    gc.drawLine(0, y + lineHeight - 1, width, y + lineHeight - 1);
+            }
+        }
+    }
+
+    /**
+     * Returns whether the line background differs from the default.
+     *
+     * @param info the info being queried
+     * @return <code>true</code> if <code>info</code> describes either a changed or an added
+     *         line.
+     */
+    private bool hasSpecialColor(ILineDiffInfo info) {
+        return info.getChangeType() is ILineDiffInfo.ADDED || info.getChangeType() is ILineDiffInfo.CHANGED;
+    }
+
+    /**
+     * Retrieves the <code>ILineDiffInfo</code> for <code>line</code> from the model. There are
+     * optimizations for direct access and sequential access patterns.
+     *
+     * @param line the line we want the info for.
+     * @return the <code>ILineDiffInfo</code> for <code>line</code>, or <code>null</code>.
+     */
+    private ILineDiffInfo getDiffInfo(int line) {
+        if (fLineDiffer !is null)
+            return fLineDiffer.getLineInfo(line);
+
+        return null;
+    }
+
+    /**
+     * Returns the color for deleted lines.
+     *
+     * @return the color to be used for the deletion indicator
+     */
+    private Color getDeletionColor() {
+        return fDeletedColor is null ? getBackground() : fDeletedColor;
+    }
+
+    /**
+     * Returns the color for the given line diff info.
+     *
+     * @param info the <code>ILineDiffInfo</code> being queried
+     * @return the correct background color for the line type being described by <code>info</code>
+     */
+    private Color getColor(ILineDiffInfo info) {
+        Assert.isTrue(info !is null && info.getChangeType() !is ILineDiffInfo.UNCHANGED);
+        Color ret= null;
+        switch (info.getChangeType()) {
+            case ILineDiffInfo.CHANGED:
+                ret= getShadedColor(fChangedColor);
+                break;
+            case ILineDiffInfo.ADDED:
+                ret= getShadedColor(fAddedColor);
+                break;
+        }
+        return ret is null ? getBackground() : ret;
+    }
+
+    /**
+     * Sets the background color for changed lines.
+     *
+     * @param color the new color to be used for the changed lines background
+     * @return the shaded color
+     */
+    private Color getShadedColor(Color color) {
+        if (color is null)
+            return null;
+
+        if (fSharedColors is null)
+            return color;
+
+        RGB baseRGB= color.getRGB();
+        RGB background= getBackground().getRGB();
+
+        bool darkBase= isDark(baseRGB);
+        bool darkBackground= isDark(background);
+        if (darkBase && darkBackground)
+            background= new RGB(255, 255, 255);
+        else if (!darkBase && !darkBackground)
+            background= new RGB(0, 0, 0);
+
+        return fSharedColors.getColor(interpolate(baseRGB, background, 0.6));
+    }
+
+    /**
+     * Sets the annotation model.
+     *
+     * @param model the annotation model, possibly <code>null</code>
+     * @see IVerticalRulerColumn#setModel(IAnnotationModel)
+     */
+    public void setModel(IAnnotationModel model) {
+        IAnnotationModel newModel;
+        if ( cast(IAnnotationModelExtension)model )
+            newModel= (cast(IAnnotationModelExtension) model).getAnnotationModel(stringcast(IChangeRulerColumn.QUICK_DIFF_MODEL_ID));
+        else
+            newModel= model;
+
+        setDiffer(newModel);
+    }
+
+    /**
+     * Sets the line differ.
+     *
+     * @param differ the line differ
+     */
+    private void setDiffer(IAnnotationModel differ) {
+        if ( cast(ILineDiffer)differ ) {
+            if ( cast(Object)fLineDiffer !is cast(Object)differ) {
+                if (fLineDiffer !is null)
+                    (cast(IAnnotationModel) fLineDiffer).removeAnnotationModelListener(fAnnotationListener);
+                fLineDiffer= cast(ILineDiffer) differ;
+                if (fLineDiffer !is null)
+                    (cast(IAnnotationModel) fLineDiffer).addAnnotationModelListener(fAnnotationListener);
+            }
+        }
+    }
+
+    /**
+     * Triggers a redraw in the display thread.
+     */
+    private final void postRedraw() {
+        if (isConnected() && !fControl.isDisposed()) {
+            Display d= fControl.getDisplay();
+            if (d !is null) {
+                d.asyncExec(new class()  Runnable {
+                    public void run() {
+                        redraw();
+                    }
+                });
+            }
+        }
+    }
+
+    /**
+     * Triggers redrawing of the column.
+     */
+    private void redraw() {
+        fColumn.redraw();
+    }
+
+    /**
+     * Returns the width of the column.
+     *
+     * @return the width of the column
+     */
+    private int getWidth() {
+        return fColumn.getWidth();
+    }
+
+    /**
+     * Computes the end index of a line range.
+     *
+     * @param range a line range
+     * @return the last line (exclusive) of <code>range</code>
+     */
+    private static int end(ILineRange range) {
+        return range.getStartLine() + range.getNumberOfLines();
+    }
+
+    /**
+     * Returns the System background color for list widgets or the set background.
+     *
+     * @return the System background color for list widgets
+     */
+    private Color getBackground() {
+        if (fBackground is null)
+            return fWidget.getDisplay().getSystemColor(DWT.COLOR_LIST_BACKGROUND);
+        return fBackground;
+    }
+
+    /**
+     * Sets the color for added lines.
+     *
+     * @param addedColor the color for added lines
+     * @see dwtx.jface.text.source.IChangeRulerColumn#setAddedColor(dwt.graphics.Color)
+     */
+    public void setAddedColor(Color addedColor) {
+        fAddedColor= addedColor;
+    }
+
+    /**
+     * Sets the color for changed lines.
+     *
+     * @param changedColor the color for changed lines
+     * @see dwtx.jface.text.source.IChangeRulerColumn#setChangedColor(dwt.graphics.Color)
+     */
+    public void setChangedColor(Color changedColor) {
+        fChangedColor= changedColor;
+    }
+
+    /**
+     * Sets the color for deleted lines.
+     *
+     * @param deletedColor the color for deleted lines
+     * @see dwtx.jface.text.source.IChangeRulerColumn#setDeletedColor(dwt.graphics.Color)
+     */
+    public void setDeletedColor(Color deletedColor) {
+        fDeletedColor= deletedColor;
+    }
+
+    /**
+     * Returns <code>true</code> if the receiver can provide a hover for a certain document line.
+     *
+     * @param activeLine the document line of interest
+     * @return <code>true</code> if the receiver can provide a hover
+     */
+    public bool hasHover(int activeLine) {
+        return true;
+    }
+
+    /**
+     * Returns the display character for the accessibility mode for a certain model line.
+     *
+     * @param line the document line of interest
+     * @return the display character for <code>line</code>
+     */
+    public String getDisplayCharacter(int line) {
+        return getDisplayCharacter(getDiffInfo(line));
+    }
+
+    /**
+     * Returns the character to display in character display mode for the given
+     * <code>ILineDiffInfo</code>
+     *
+     * @param info the <code>ILineDiffInfo</code> being queried
+     * @return the character indication for <code>info</code>
+     */
+    private String getDisplayCharacter(ILineDiffInfo info) {
+        if (info is null)
+            return " "; //$NON-NLS-1$
+        switch (info.getChangeType()) {
+            case ILineDiffInfo.CHANGED:
+                return "~"; //$NON-NLS-1$
+            case ILineDiffInfo.ADDED:
+                return "+"; //$NON-NLS-1$
+        }
+        return " "; //$NON-NLS-1$
+    }
+
+    /**
+     * Returns a specification of a color that lies between the given foreground and background
+     * color using the given scale factor.
+     *
+     * @param fg the foreground color
+     * @param bg the background color
+     * @param scale the scale factor
+     * @return the interpolated color
+     */
+    private static RGB interpolate(RGB fg, RGB bg, double scale) {
+        return new RGB(cast(int) ((1.0 - scale) * fg.red + scale * bg.red), cast(int) ((1.0 - scale) * fg.green + scale * bg.green), cast(int) ((1.0 - scale) * fg.blue + scale * bg.blue));
+    }
+
+    /**
+     * Returns the grey value in which the given color would be drawn in grey-scale.
+     *
+     * @param rgb the color
+     * @return the grey-scale value
+     */
+    private static double greyLevel(RGB rgb) {
+        if (rgb.red is rgb.green && rgb.green is rgb.blue)
+            return rgb.red;
+        return (0.299 * rgb.red + 0.587 * rgb.green + 0.114 * rgb.blue + 0.5);
+    }
+
+    /**
+     * Returns whether the given color is dark or light depending on the colors grey-scale level.
+     *
+     * @param rgb the color
+     * @return <code>true</code> if the color is dark, <code>false</code> if it is light
+     */
+    private static bool isDark(RGB rgb) {
+        return greyLevel(rgb) > 128;
+    }
+
+    /**
+     * Returns <code>true</code> if diff information is being displayed, <code>false</code> otherwise.
+     *
+     * @return <code>true</code> if diff information is being displayed, <code>false</code> otherwise
+     * @since 3.3
+     */
+    public bool hasInformation() {
+        if ( cast(ILineDifferExtension2)fLineDiffer )
+            return !(cast(ILineDifferExtension2) fLineDiffer).isSuspended();
+        return fLineDiffer !is null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/AbstractDocument.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1927 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.AbstractDocument;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import dwtx.dwtxhelper.regex;
+import tango.text.convert.Format;
+
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.ListenerList;
+
+
+/**
+ * Abstract default implementation of <code>IDocument</code> and its extension
+ * interfaces {@link dwtx.jface.text.IDocumentExtension},
+ * {@link dwtx.jface.text.IDocumentExtension2},
+ * {@link dwtx.jface.text.IDocumentExtension3},
+ * {@link dwtx.jface.text.IDocumentExtension4}, as well as
+ * {@link dwtx.jface.text.IRepairableDocument}.
+ * <p>
+ *
+ * An <code>AbstractDocument</code> supports the following implementation
+ * plug-ins:
+ * <ul>
+ * <li>a text store implementing {@link dwtx.jface.text.ITextStore} for
+ *     storing and managing the document's content,</li>
+ * <li>a line tracker implementing {@link dwtx.jface.text.ILineTracker}
+ *     to map character positions to line numbers and vice versa</li>
+ * </ul>
+ * The document can dynamically change the text store when switching between
+ * sequential rewrite mode and normal mode.
+ * <p>
+ *
+ * This class must be subclassed. Subclasses must configure which implementation
+ * plug-ins the document instance should use. Subclasses are not intended to
+ * overwrite existing methods.
+ *
+ * @see dwtx.jface.text.ITextStore
+ * @see dwtx.jface.text.ILineTracker
+ */
+public abstract class AbstractDocument : IDocument, IDocumentExtension, IDocumentExtension2, IDocumentExtension3, IDocumentExtension4, IRepairableDocument, IRepairableDocumentExtension {
+
+    /**
+     * Tells whether this class is in debug mode.
+     * @since 3.1
+     */
+    private static const bool DEBUG= false;
+
+
+    /**
+     * Inner class to bundle a registered post notification replace operation together with its
+     * owner.
+     *
+     * @since 2.0
+     */
+    static private class RegisteredReplace {
+        /** The owner of this replace operation. */
+        IDocumentListener fOwner;
+        /** The replace operation */
+        IDocumentExtension.IReplace fReplace;
+
+        /**
+         * Creates a new bundle object.
+         * @param owner the document listener owning the replace operation
+         * @param replace the replace operation
+         */
+        this(IDocumentListener owner, IDocumentExtension.IReplace replace) {
+            fOwner= owner;
+            fReplace= replace;
+        }
+    }
+
+
+    /** The document's text store */
+    private ITextStore   fStore;
+    /** The document's line tracker */
+    private ILineTracker fTracker;
+    /** The registered document listeners */
+    private ListenerList fDocumentListeners;
+    /** The registered pre-notified document listeners */
+    private ListenerList fPrenotifiedDocumentListeners;
+    /** The registered document partitioning listeners */
+    private ListenerList fDocumentPartitioningListeners;
+    /** All positions managed by the document ordered by their start positions. */
+    private Map fPositions;
+    /**
+     * All positions managed by the document ordered by there end positions.
+     * @since 3.4
+     */
+    private Map fEndPositions;
+    /** All registered document position updaters */
+    private List fPositionUpdaters;
+    /**
+     * The list of post notification changes
+     * @since 2.0
+     */
+    private List fPostNotificationChanges;
+    /**
+     * The reentrance count for post notification changes.
+     * @since 2.0
+     */
+    private int fReentranceCount= 0;
+    /**
+     * Indicates whether post notification change processing has been stopped.
+     * @since 2.0
+     */
+    private int fStoppedCount= 0;
+    /**
+     * Indicates whether the registration of post notification changes should be ignored.
+     * @since 2.1
+     */
+    private bool fAcceptPostNotificationReplaces= true;
+    /**
+     * Indicates whether the notification of listeners has been stopped.
+     * @since 2.1
+     */
+    private int fStoppedListenerNotification= 0;
+    /**
+     * The document event to be sent after listener notification has been resumed.
+     * @since 2.1
+     */
+    private DocumentEvent fDeferredDocumentEvent;
+    /**
+     * The registered document partitioners.
+     * @since 3.0
+     */
+    private Map fDocumentPartitioners;
+    /**
+     * The partitioning changed event.
+     * @since 3.0
+     */
+    private DocumentPartitioningChangedEvent fDocumentPartitioningChangedEvent;
+    /**
+     * The find/replace document adapter.
+     * @since 3.0
+     */
+    private FindReplaceDocumentAdapter fFindReplaceDocumentAdapter;
+    /**
+     * The active document rewrite session.
+     * @since 3.1
+     */
+    private DocumentRewriteSession fDocumentRewriteSession;
+    /**
+     * The registered document rewrite session listeners.
+     * @since 3.1
+     */
+    private List fDocumentRewriteSessionListeners;
+    /**
+     * The current modification stamp.
+     * @since 3.1
+     */
+    private long fModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+    /**
+     * Keeps track of next modification stamp.
+     * @since 3.1.1
+     */
+    private long fNextModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+    /**
+     * This document's default line delimiter.
+     * @since 3.1
+     */
+    private String fInitialLineDelimiter;
+
+
+    /**
+     * The default constructor does not perform any configuration
+     * but leaves it to the clients who must first initialize the
+     * implementation plug-ins and then call <code>completeInitialization</code>.
+     * Results in the construction of an empty document.
+     */
+    protected this() {
+        fModificationStamp= getNextModificationStamp();
+    }
+
+
+    /**
+     * Returns the document's text store. Assumes that the
+     * document has been initialized with a text store.
+     *
+     * @return the document's text store
+     */
+    protected ITextStore getStore() {
+        Assert.isNotNull(cast(Object)fStore);
+        return fStore;
+    }
+
+    /**
+     * Returns the document's line tracker. Assumes that the
+     * document has been initialized with a line tracker.
+     *
+     * @return the document's line tracker
+     */
+    protected ILineTracker getTracker() {
+        Assert.isNotNull(cast(Object)fTracker);
+        return fTracker;
+    }
+
+    /**
+     * Returns the document's document listeners.
+     *
+     * @return the document's document listeners
+     */
+    protected List getDocumentListeners() {
+        return Arrays.asList(fDocumentListeners.getListeners());
+    }
+
+    /**
+     * Returns the document's partitioning listeners.
+     *
+     * @return the document's partitioning listeners
+     */
+    protected List getDocumentPartitioningListeners() {
+        return Arrays.asList(fDocumentPartitioningListeners.getListeners());
+    }
+
+    /**
+     * Returns all positions managed by the document grouped by category.
+     *
+     * @return the document's positions
+     */
+    protected Map getDocumentManagedPositions() {
+        return fPositions;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getDocumentPartitioner()
+     */
+    public IDocumentPartitioner getDocumentPartitioner() {
+        return getDocumentPartitioner(DEFAULT_PARTITIONING);
+    }
+
+
+
+    //--- implementation configuration interface ------------
+
+    /**
+     * Sets the document's text store.
+     * Must be called at the beginning of the constructor.
+     *
+     * @param store the document's text store
+     */
+    protected void setTextStore(ITextStore store) {
+        fStore= store;
+    }
+
+    /**
+     * Sets the document's line tracker.
+     * Must be called at the beginning of the constructor.
+     *
+     * @param tracker the document's line tracker
+     */
+    protected void setLineTracker(ILineTracker tracker) {
+        fTracker= tracker;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#setDocumentPartitioner(dwtx.jface.text.IDocumentPartitioner)
+     */
+    public void setDocumentPartitioner(IDocumentPartitioner partitioner) {
+        setDocumentPartitioner(DEFAULT_PARTITIONING, partitioner);
+    }
+
+    /**
+     * Initializes document listeners, positions, and position updaters.
+     * Must be called inside the constructor after the implementation plug-ins
+     * have been set.
+     */
+    protected void completeInitialization() {
+
+        fPositions= new HashMap();
+        fEndPositions= new HashMap();
+        fPositionUpdaters= new ArrayList();
+        fDocumentListeners= new ListenerList(ListenerList.IDENTITY);
+        fPrenotifiedDocumentListeners= new ListenerList(ListenerList.IDENTITY);
+        fDocumentPartitioningListeners= new ListenerList(ListenerList.IDENTITY);
+        fDocumentRewriteSessionListeners= new ArrayList();
+
+        addPositionCategory(DEFAULT_CATEGORY);
+        addPositionUpdater(new DefaultPositionUpdater(DEFAULT_CATEGORY));
+    }
+
+
+    //-------------------------------------------------------
+
+    /*
+     * @see dwtx.jface.text.IDocument#addDocumentListener(dwtx.jface.text.IDocumentListener)
+     */
+    public void addDocumentListener(IDocumentListener listener) {
+        Assert.isNotNull(cast(Object)listener);
+        fDocumentListeners.add(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#removeDocumentListener(dwtx.jface.text.IDocumentListener)
+     */
+    public void removeDocumentListener(IDocumentListener listener) {
+        Assert.isNotNull(cast(Object)listener);
+        fDocumentListeners.remove(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#addPrenotifiedDocumentListener(dwtx.jface.text.IDocumentListener)
+     */
+    public void addPrenotifiedDocumentListener(IDocumentListener listener) {
+        Assert.isNotNull(cast(Object)listener);
+        fPrenotifiedDocumentListeners.add(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#removePrenotifiedDocumentListener(dwtx.jface.text.IDocumentListener)
+     */
+    public void removePrenotifiedDocumentListener(IDocumentListener listener) {
+        Assert.isNotNull(cast(Object)listener);
+        fPrenotifiedDocumentListeners.remove(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#addDocumentPartitioningListener(dwtx.jface.text.IDocumentPartitioningListener)
+     */
+    public void addDocumentPartitioningListener(IDocumentPartitioningListener listener) {
+        Assert.isNotNull(cast(Object)listener);
+        fDocumentPartitioningListeners.add(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#removeDocumentPartitioningListener(dwtx.jface.text.IDocumentPartitioningListener)
+     */
+    public void removeDocumentPartitioningListener(IDocumentPartitioningListener listener) {
+        Assert.isNotNull(cast(Object)listener);
+        fDocumentPartitioningListeners.remove(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#addPosition(java.lang.String, dwtx.jface.text.Position)
+     */
+    public void addPosition(String category, Position position)  {
+
+        if ((0 > position.offset) || (0 > position.length) || (position.offset + position.length > getLength()))
+            throw new BadLocationException();
+
+        if (category is null)
+            throw new BadPositionCategoryException();
+
+        List list= cast(List) fPositions.get(category);
+        if (list is null)
+            throw new BadPositionCategoryException();
+        list.add(computeIndexInPositionList(list, position.offset), position);
+
+        List endPositions= cast(List) fEndPositions.get(category);
+        if (endPositions is null)
+            throw new BadPositionCategoryException();
+        endPositions.add(computeIndexInPositionList(endPositions, position.offset + position.length - 1, false), position);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#addPosition(dwtx.jface.text.Position)
+     */
+    public void addPosition(Position position)  {
+        try {
+            addPosition(DEFAULT_CATEGORY, position);
+        } catch (BadPositionCategoryException e) {
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#addPositionCategory(java.lang.String)
+     */
+    public void addPositionCategory(String category) {
+
+        if (category is null)
+            return;
+
+        if (!containsPositionCategory(category)) {
+            fPositions.put(category, new ArrayList());
+            fEndPositions.put(category, new ArrayList());
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#addPositionUpdater(dwtx.jface.text.IPositionUpdater)
+     */
+    public void addPositionUpdater(IPositionUpdater updater) {
+        insertPositionUpdater(updater, fPositionUpdaters.size());
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#containsPosition(java.lang.String, int, int)
+     */
+    public bool containsPosition(String category, int offset, int length) {
+
+        if (category is null)
+            return false;
+
+        List list= cast(List) fPositions.get(category);
+        if (list is null)
+            return false;
+
+        int size= list.size();
+        if (size is 0)
+            return false;
+
+        int index= computeIndexInPositionList(list, offset);
+        if (index < size) {
+            Position p= cast(Position) list.get(index);
+            while (p !is null && p.offset is offset) {
+                if (p.length is length)
+                    return true;
+                ++ index;
+                p= (index < size) ? cast(Position) list.get(index) : null;
+            }
+        }
+
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#containsPositionCategory(java.lang.String)
+     */
+    public bool containsPositionCategory(String category) {
+        if (category !is null)
+            return fPositions.containsKey(category);
+        return false;
+    }
+
+
+    /**
+     * Computes the index in the list of positions at which a position with the given
+     * offset would be inserted. The position is supposed to become the first in this list
+     * of all positions with the same offset.
+     *
+     * @param positions the list in which the index is computed
+     * @param offset the offset for which the index is computed
+     * @return the computed index
+     *
+     * @see IDocument#computeIndexInCategory(String, int)
+     * @deprecated As of 3.4, replaced by {@link #computeIndexInPositionList(List, int, bool)}
+     */
+    protected int computeIndexInPositionList(List positions, int offset) {
+        return computeIndexInPositionList(positions, offset, true);
+    }
+
+    /**
+     * Computes the index in the list of positions at which a position with the given
+     * position would be inserted. The position to insert is supposed to become the first
+     * in this list of all positions with the same position.
+     *
+     * @param positions the list in which the index is computed
+     * @param offset the offset for which the index is computed
+     * @param orderedByOffset <code>true</code> if ordered by offset, false if ordered by end position
+     * @return the computed index
+     * @since 3.4
+     */
+    protected int computeIndexInPositionList(List positions, int offset, bool orderedByOffset) {
+        if (positions.size() is 0)
+            return 0;
+
+        int left= 0;
+        int right= positions.size() -1;
+        int mid= 0;
+        Position p= null;
+
+        while (left < right) {
+
+            mid= (left + right) / 2;
+
+            p= cast(Position) positions.get(mid);
+            int pOffset= getOffset(orderedByOffset, p);
+            if (offset < pOffset) {
+                if (left is mid)
+                    right= left;
+                else
+                    right= mid -1;
+            } else if (offset > pOffset) {
+                if (right is mid)
+                    left= right;
+                else
+                    left= mid  +1;
+            } else if (offset is pOffset) {
+                left= right= mid;
+            }
+
+        }
+
+        int pos= left;
+        p= cast(Position) positions.get(pos);
+        int pPosition= getOffset(orderedByOffset, p);
+        if (offset > pPosition) {
+            // append to the end
+            pos++;
+        } else {
+            // entry will become the first of all entries with the same offset
+            do {
+                --pos;
+                if (pos < 0)
+                    break;
+                p= cast(Position) positions.get(pos);
+                pPosition= getOffset(orderedByOffset, p);
+            } while (offset is pPosition);
+            ++pos;
+        }
+
+        Assert.isTrue(0 <= pos && pos <= positions.size());
+
+        return pos;
+    }
+
+    /*
+     * @since 3.4
+     */
+    private int getOffset(bool orderedByOffset, Position position) {
+        if (orderedByOffset || position.getLength() is 0)
+            return position.getOffset();
+        return position.getOffset() + position.getLength() - 1;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#computeIndexInCategory(java.lang.String, int)
+     */
+    public int computeIndexInCategory(String category, int offset)  {
+
+        if (0 > offset || offset > getLength())
+            throw new BadLocationException();
+
+        List c= cast(List) fPositions.get(category);
+        if (c is null)
+            throw new BadPositionCategoryException();
+
+        return computeIndexInPositionList(c, offset);
+    }
+
+    /**
+     * Fires the document partitioning changed notification to all registered
+     * document partitioning listeners. Uses a robust iterator.
+     *
+     * @deprecated as of 2.0. Use <code>fireDocumentPartitioningChanged(IRegion)</code> instead.
+     */
+    protected void fireDocumentPartitioningChanged() {
+        if (fDocumentPartitioningListeners is null)
+            return;
+
+        Object[] listeners= fDocumentPartitioningListeners.getListeners();
+        for (int i= 0; i < listeners.length; i++)
+            (cast(IDocumentPartitioningListener)listeners[i]).documentPartitioningChanged(this);
+    }
+
+    /**
+     * Fires the document partitioning changed notification to all registered
+     * document partitioning listeners. Uses a robust iterator.
+     *
+     * @param region the region in which partitioning has changed
+     *
+     * @see IDocumentPartitioningListenerExtension
+     * @since 2.0
+     * @deprecated as of 3.0. Use
+     *             <code>fireDocumentPartitioningChanged(DocumentPartitioningChangedEvent)</code>
+     *             instead.
+     */
+    protected void fireDocumentPartitioningChanged(IRegion region) {
+        if (fDocumentPartitioningListeners is null)
+            return;
+
+        Object[] listeners= fDocumentPartitioningListeners.getListeners();
+        for (int i= 0; i < listeners.length; i++) {
+            IDocumentPartitioningListener l= cast(IDocumentPartitioningListener)listeners[i];
+            if ( cast(IDocumentPartitioningListenerExtension)l )
+                (cast(IDocumentPartitioningListenerExtension) l).documentPartitioningChanged(this, region);
+            else
+                l.documentPartitioningChanged(this);
+        }
+    }
+
+    /**
+     * Fires the document partitioning changed notification to all registered
+     * document partitioning listeners. Uses a robust iterator.
+     *
+     * @param event the document partitioning changed event
+     *
+     * @see IDocumentPartitioningListenerExtension2
+     * @since 3.0
+     */
+    protected void fireDocumentPartitioningChanged(DocumentPartitioningChangedEvent event) {
+        if (fDocumentPartitioningListeners is null)
+            return;
+
+        Object[] listeners= fDocumentPartitioningListeners.getListeners();
+        for (int i= 0; i < listeners.length; i++) {
+            IDocumentPartitioningListener l= cast(IDocumentPartitioningListener)listeners[i];
+            if ( cast(IDocumentPartitioningListenerExtension2)l ) {
+                IDocumentPartitioningListenerExtension2 extension2= cast(IDocumentPartitioningListenerExtension2) l;
+                extension2.documentPartitioningChanged(event);
+            } else if ( cast(IDocumentPartitioningListenerExtension)l ) {
+                IDocumentPartitioningListenerExtension extension= cast(IDocumentPartitioningListenerExtension) l;
+                extension.documentPartitioningChanged(this, event.getCoverage());
+            } else {
+                l.documentPartitioningChanged(this);
+            }
+        }
+    }
+
+    /**
+     * Fires the given document event to all registers document listeners informing them
+     * about the forthcoming document manipulation. Uses a robust iterator.
+     *
+     * @param event the event to be sent out
+     */
+    protected void fireDocumentAboutToBeChanged(DocumentEvent event) {
+
+        // IDocumentExtension
+        if (fReentranceCount is 0)
+            flushPostNotificationChanges();
+
+        if (fDocumentPartitioners !is null) {
+            Iterator e= fDocumentPartitioners.values().iterator();
+            while (e.hasNext()) {
+                IDocumentPartitioner p= cast(IDocumentPartitioner) e.next();
+                if ( cast(IDocumentPartitionerExtension3)p ) {
+                    IDocumentPartitionerExtension3 extension= cast(IDocumentPartitionerExtension3) p;
+                    if (extension.getActiveRewriteSession() !is null)
+                        continue;
+                }
+                p.documentAboutToBeChanged(event);
+            }
+        }
+
+        Object[] listeners= fPrenotifiedDocumentListeners.getListeners();
+        for (int i= 0; i < listeners.length; i++)
+            (cast(IDocumentListener)listeners[i]).documentAboutToBeChanged(event);
+
+        listeners= fDocumentListeners.getListeners();
+        for (int i= 0; i < listeners.length; i++)
+            (cast(IDocumentListener)listeners[i]).documentAboutToBeChanged(event);
+    }
+
+
+    /**
+     * Updates document partitioning and document positions according to the
+     * specification given by the document event.
+     *
+     * @param event the document event describing the change to which structures must be adapted
+     */
+    protected void updateDocumentStructures(DocumentEvent event) {
+
+        if (fDocumentPartitioners !is null) {
+            fDocumentPartitioningChangedEvent= new DocumentPartitioningChangedEvent(this);
+            Iterator e= fDocumentPartitioners.keySet().iterator();
+            while (e.hasNext()) {
+                String partitioning= stringcast( e.next() );
+                IDocumentPartitioner partitioner= cast(IDocumentPartitioner) fDocumentPartitioners.get(partitioning);
+
+                if ( cast(IDocumentPartitionerExtension3)partitioner ) {
+                    IDocumentPartitionerExtension3 extension= cast(IDocumentPartitionerExtension3) partitioner;
+                    if (extension.getActiveRewriteSession() !is null)
+                        continue;
+                }
+
+                if ( cast(IDocumentPartitionerExtension)partitioner ) {
+                    IDocumentPartitionerExtension extension= cast(IDocumentPartitionerExtension) partitioner;
+                    IRegion r= extension.documentChanged2(event);
+                    if (r !is null)
+                        fDocumentPartitioningChangedEvent.setPartitionChange(partitioning, r.getOffset(), r.getLength());
+                } else {
+                    if (partitioner.documentChanged(event))
+                        fDocumentPartitioningChangedEvent.setPartitionChange(partitioning, 0, event.getDocument().getLength());
+                }
+            }
+        }
+
+        if (fPositions.size() > 0)
+            updatePositions(event);
+    }
+
+    /**
+     * Notifies all listeners about the given document change. Uses a robust
+     * iterator.
+     * <p>
+     * Executes all registered post notification replace operation.
+     *
+     * @param event the event to be sent out.
+     */
+    protected void doFireDocumentChanged(DocumentEvent event) {
+        bool changed= fDocumentPartitioningChangedEvent !is null && !fDocumentPartitioningChangedEvent.isEmpty();
+        IRegion change= changed ? fDocumentPartitioningChangedEvent.getCoverage() : null;
+        doFireDocumentChanged(event, changed, change);
+    }
+
+    /**
+     * Notifies all listeners about the given document change.
+     * Uses a robust iterator. <p>
+     * Executes all registered post notification replace operation.
+     *
+     * @param event the event to be sent out
+     * @param firePartitionChange <code>true</code> if a partition change notification should be sent
+     * @param partitionChange the region whose partitioning changed
+     * @since 2.0
+     * @deprecated as of 3.0. Use <code>doFireDocumentChanged2(DocumentEvent)</code> instead; this method will be removed.
+     */
+    protected void doFireDocumentChanged(DocumentEvent event, bool firePartitionChange, IRegion partitionChange) {
+        doFireDocumentChanged2(event);
+    }
+
+    /**
+     * Notifies all listeners about the given document change. Uses a robust
+     * iterator.
+     * <p>
+     * Executes all registered post notification replace operation.
+     * <p>
+     * This method will be renamed to <code>doFireDocumentChanged</code>.
+     *
+     * @param event the event to be sent out
+     * @since 3.0
+     */
+    protected void doFireDocumentChanged2(DocumentEvent event) {
+
+        DocumentPartitioningChangedEvent p= fDocumentPartitioningChangedEvent;
+        fDocumentPartitioningChangedEvent= null;
+        if (p !is null && !p.isEmpty())
+            fireDocumentPartitioningChanged(p);
+
+        Object[] listeners= fPrenotifiedDocumentListeners.getListeners();
+        for (int i= 0; i < listeners.length; i++)
+            (cast(IDocumentListener)listeners[i]).documentChanged(event);
+
+        listeners= fDocumentListeners.getListeners();
+        for (int i= 0; i < listeners.length; i++)
+            (cast(IDocumentListener)listeners[i]).documentChanged(event);
+
+        // IDocumentExtension
+        ++ fReentranceCount;
+        try {
+            if (fReentranceCount is 1)
+                executePostNotificationChanges();
+        } finally {
+            -- fReentranceCount;
+        }
+    }
+
+    /**
+     * Updates the internal document structures and informs all document listeners
+     * if listener notification has been enabled. Otherwise it remembers the event
+     * to be sent to the listeners on resume.
+     *
+     * @param event the document event to be sent out
+     */
+    protected void fireDocumentChanged(DocumentEvent event) {
+        updateDocumentStructures(event);
+
+        if (fStoppedListenerNotification is 0)
+            doFireDocumentChanged(event);
+        else
+            fDeferredDocumentEvent= event;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getChar(int)
+     */
+    public char getChar(int pos)  {
+        if ((0 > pos) || (pos >= getLength()))
+            throw new BadLocationException();
+        return getStore().get(pos);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getContentType(int)
+     */
+    public String getContentType(int offset)  {
+        String contentType= null;
+        try {
+            contentType= getContentType(DEFAULT_PARTITIONING, offset, false);
+            //Assert.isNotNull(contentType);
+        } catch (BadPartitioningException e) {
+            Assert.isTrue(false);
+        }
+        return contentType;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getLegalContentTypes()
+     */
+    public String[] getLegalContentTypes() {
+        String[] contentTypes= null;
+        try {
+            contentTypes= getLegalContentTypes(DEFAULT_PARTITIONING);
+            //Assert.isNotNull(contentTypes);
+        } catch (BadPartitioningException e) {
+            Assert.isTrue(false);
+        }
+        return contentTypes;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getLength()
+     */
+    public int getLength() {
+        return getStore().getLength();
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getLineDelimiter(int)
+     */
+    public String getLineDelimiter(int line)  {
+        return getTracker().getLineDelimiter(line);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getLegalLineDelimiters()
+     */
+    public String[] getLegalLineDelimiters() {
+        return getTracker().getLegalLineDelimiters();
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension4#getDefaultLineDelimiter()
+     * @since 3.1
+     */
+    public String getDefaultLineDelimiter() {
+
+        String lineDelimiter= null;
+
+        try {
+            lineDelimiter= getLineDelimiter(0);
+        } catch (BadLocationException x) {
+        }
+
+        if (lineDelimiter !is null)
+            return lineDelimiter;
+
+        if (fInitialLineDelimiter !is null)
+            return fInitialLineDelimiter;
+
+        String sysLineDelimiter= System.getProperty("line.separator"); //$NON-NLS-1$
+        String[] delimiters= getLegalLineDelimiters();
+        Assert.isTrue(delimiters.length > 0);
+        for (int i= 0; i < delimiters.length; i++) {
+            if (delimiters[i].equals(sysLineDelimiter)) {
+                lineDelimiter= sysLineDelimiter;
+                break;
+            }
+        }
+
+        if (lineDelimiter is null)
+            lineDelimiter= delimiters[0];
+
+        return lineDelimiter;
+
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension4#setInitialLineDelimiter(java.lang.String)
+     * @since 3.1
+     */
+    public void setInitialLineDelimiter(String lineDelimiter) {
+        Assert.isNotNull(lineDelimiter);
+        fInitialLineDelimiter= lineDelimiter;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getLineLength(int)
+     */
+    public int getLineLength(int line)  {
+        return getTracker().getLineLength(line);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getLineOfOffset(int)
+     */
+    public int getLineOfOffset(int pos)  {
+        return getTracker().getLineNumberOfOffset(pos);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getLineOffset(int)
+     */
+    public int getLineOffset(int line)  {
+        return getTracker().getLineOffset(line);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getLineInformation(int)
+     */
+    public IRegion getLineInformation(int line)  {
+        return getTracker().getLineInformation(line);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getLineInformationOfOffset(int)
+     */
+    public IRegion getLineInformationOfOffset(int offset)  {
+        return getTracker().getLineInformationOfOffset(offset);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getNumberOfLines()
+     */
+    public int getNumberOfLines() {
+        return getTracker().getNumberOfLines();
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getNumberOfLines(int, int)
+     */
+    public int getNumberOfLines(int offset, int length)  {
+        return getTracker().getNumberOfLines(offset, length);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#computeNumberOfLines(java.lang.String)
+     */
+    public int computeNumberOfLines(String text) {
+        return getTracker().computeNumberOfLines(text);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getPartition(int)
+     */
+    public ITypedRegion getPartition(int offset)  {
+        ITypedRegion partition= null;
+        try {
+            partition= getPartition(DEFAULT_PARTITIONING, offset, false);
+//             Assert.isNotNull(cast(Object)partition);
+        } catch (BadPartitioningException e) {
+            Assert.isTrue(false);
+        }
+        return  partition;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#computePartitioning(int, int)
+     */
+    public ITypedRegion[] computePartitioning(int offset, int length)  {
+        ITypedRegion[] partitioning= null;
+        try {
+            partitioning= computePartitioning(DEFAULT_PARTITIONING, offset, length, false);
+//             Assert.isNotNull(cast(Object)partitioning);
+        } catch (BadPartitioningException e) {
+            Assert.isTrue(false);
+        }
+        return partitioning;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getPositions(java.lang.String)
+     */
+    public Position[] getPositions(String category)  {
+
+        if (category is null)
+            throw new BadPositionCategoryException();
+
+        List c= cast(List) fPositions.get(category);
+        if (c is null)
+            throw new BadPositionCategoryException();
+
+        Position[] positions= new Position[c.size()];
+        c.toArray(positions);
+        return positions;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getPositionCategories()
+     */
+    public String[] getPositionCategories() {
+        String[] categories= new String[fPositions.size()];
+        Iterator keys= fPositions.keySet().iterator();
+        for (int i= 0; i < categories.length; i++)
+            categories[i]= stringcast( keys.next());
+        return categories;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#getPositionUpdaters()
+     */
+    public IPositionUpdater[] getPositionUpdaters() {
+        return arraycast!(IPositionUpdater)(fPositionUpdaters.toArray());
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#get()
+     */
+    public String get() {
+        return getStore().get(0, getLength());
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#get(int, int)
+     */
+    public String get(int pos, int length)  {
+        int myLength= getLength();
+        if ((0 > pos) || (0 > length) || (pos + length > myLength))
+            throw new BadLocationException();
+        return getStore().get(pos, length);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#insertPositionUpdater(dwtx.jface.text.IPositionUpdater, int)
+     */
+    public void insertPositionUpdater(IPositionUpdater updater, int index) {
+
+        for (int i= fPositionUpdaters.size() - 1; i >= 0; i--) {
+            if (fPositionUpdaters.get(i) is cast(Object)updater)
+                return;
+        }
+
+        if (index is fPositionUpdaters.size())
+            fPositionUpdaters.add(cast(Object)updater);
+        else
+            fPositionUpdaters.add(index, cast(Object)updater);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#removePosition(java.lang.String, dwtx.jface.text.Position)
+     */
+    public void removePosition(String category, Position position)  {
+
+        if (position is null)
+            return;
+
+        if (category is null)
+            throw new BadPositionCategoryException();
+
+        List c= cast(List) fPositions.get(category);
+        if (c is null)
+            throw new BadPositionCategoryException();
+        removeFromPositionsList(c, position, true);
+
+        List endPositions= cast(List) fEndPositions.get(category);
+        if (endPositions is null)
+            throw new BadPositionCategoryException();
+        removeFromPositionsList(endPositions, position, false);
+    }
+
+    /**
+     * Remove the given position form the given list of positions based on identity not equality.
+     *
+     * @param positions a list of positions
+     * @param position the position to remove
+     * @param orderedByOffset true if <code>positions</code> is ordered by offset, false if ordered by end position
+     * @since 3.4
+     */
+    private void removeFromPositionsList(List positions, Position position, bool orderedByOffset) {
+        int size= positions.size();
+
+        //Assume position is somewhere near it was before
+        int index= computeIndexInPositionList(positions, orderedByOffset ? position.offset : position.offset + position.length - 1, orderedByOffset);
+        if (index < size && positions.get(index) is position) {
+            positions.remove(index);
+            return;
+        }
+
+        int back= index - 1;
+        int forth= index + 1;
+        while (back >= 0 || forth < size) {
+            if (back >= 0) {
+                if (position is positions.get(back)) {
+                    positions.remove(back);
+                    return;
+                }
+                back--;
+            }
+
+            if (forth < size) {
+                if (position is positions.get(forth)) {
+                    positions.remove(forth);
+                    return;
+                }
+                forth++;
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#removePosition(dwtx.jface.text.Position)
+     */
+    public void removePosition(Position position) {
+        try {
+            removePosition(DEFAULT_CATEGORY, position);
+        } catch (BadPositionCategoryException e) {
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#removePositionCategory(java.lang.String)
+     */
+    public void removePositionCategory(String category)  {
+
+        if (category is null)
+            return;
+
+        if ( !containsPositionCategory(category))
+            throw new BadPositionCategoryException();
+
+        fPositions.remove(category);
+        fEndPositions.remove(category);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#removePositionUpdater(dwtx.jface.text.IPositionUpdater)
+     */
+    public void removePositionUpdater(IPositionUpdater updater) {
+        for (int i= fPositionUpdaters.size() - 1; i >= 0; i--) {
+            if (fPositionUpdaters.get(i) is cast(Object)updater) {
+                fPositionUpdaters.remove(i);
+                return;
+            }
+        }
+    }
+
+    private long getNextModificationStamp() {
+        if (fNextModificationStamp is Long.MAX_VALUE || fNextModificationStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP)
+            fNextModificationStamp= 0;
+        else
+            fNextModificationStamp= fNextModificationStamp + 1;
+
+        return fNextModificationStamp;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension4#getModificationStamp()
+     * @since 3.1
+     */
+    public long getModificationStamp() {
+        return fModificationStamp;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#replace(int, int, java.lang.String)
+     * @since 3.1
+     */
+    public void replace(int pos, int length, String text, long modificationStamp)  {
+        if ((0 > pos) || (0 > length) || (pos + length > getLength()))
+            throw new BadLocationException();
+
+        DocumentEvent e= new DocumentEvent(this, pos, length, text);
+        fireDocumentAboutToBeChanged(e);
+
+        getStore().replace(pos, length, text);
+        getTracker().replace(pos, length, text);
+
+        fModificationStamp= modificationStamp;
+        fNextModificationStamp= Math.max(fModificationStamp, fNextModificationStamp);
+        e.fModificationStamp= fModificationStamp;
+
+        fireDocumentChanged(e);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 3.4
+     */
+    public bool isLineInformationRepairNeeded(int offset, int length, String text)  {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#replace(int, int, java.lang.String)
+     */
+    public void replace(int pos, int length, String text)  {
+        if (length is 0 && (text is null || text.length is 0))
+            replace(pos, length, text, getModificationStamp());
+        else
+            replace(pos, length, text, getNextModificationStamp());
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#set(java.lang.String)
+     */
+    public void set(String text) {
+        set(text, getNextModificationStamp());
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension4#set(java.lang.String, long)
+     * @since 3.1
+     */
+    public void set(String text, long modificationStamp) {
+        int length= getStore().getLength();
+
+        DocumentEvent e= new DocumentEvent(this, 0, length, text);
+        fireDocumentAboutToBeChanged(e);
+
+        getStore().set(text);
+        getTracker().set(text);
+
+        fModificationStamp= modificationStamp;
+        fNextModificationStamp= Math.max(fModificationStamp, fNextModificationStamp);
+        e.fModificationStamp= fModificationStamp;
+
+        fireDocumentChanged(e);
+    }
+
+    /**
+     * Updates all positions of all categories to the change described by the
+     * document event. All registered document updaters are called in the
+     * sequence they have been arranged. Uses a robust iterator.
+     *
+     * @param event the document event describing the change to which to adapt
+     *            the positions
+     */
+    protected void updatePositions(DocumentEvent event) {
+        List list= new ArrayList(fPositionUpdaters);
+        Iterator e= list.iterator();
+        while (e.hasNext()) {
+            IPositionUpdater u= cast(IPositionUpdater) e.next();
+            u.update(event);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#search(int, java.lang.String, bool, bool, bool)
+     */
+    public int search(int startPosition, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord)  {
+        try {
+            IRegion region= getFindReplaceDocumentAdapter().find(startPosition, findString, forwardSearch, caseSensitive, wholeWord, false);
+            return region is null ?  -1 : region.getOffset();
+        } catch (IllegalStateException ex) {
+            return -1;
+        } catch (PatternSyntaxException ex) {
+            return -1;
+        }
+    }
+
+    /**
+     * Returns the find/replace adapter for this document.
+     *
+     * @return this document's find/replace document adapter
+     * @since 3.0
+     */
+    private FindReplaceDocumentAdapter getFindReplaceDocumentAdapter() {
+        if (fFindReplaceDocumentAdapter is null)
+            fFindReplaceDocumentAdapter= new FindReplaceDocumentAdapter(this);
+
+        return fFindReplaceDocumentAdapter;
+    }
+
+    /**
+     * Flushes all registered post notification changes.
+     *
+     * @since 2.0
+     */
+    private void flushPostNotificationChanges() {
+        if (fPostNotificationChanges !is null)
+            fPostNotificationChanges.clear();
+    }
+
+    /**
+     * Executes all registered post notification changes. The process is
+     * repeated until no new post notification changes are added.
+     *
+     * @since 2.0
+     */
+    private void executePostNotificationChanges() {
+
+        if (fStoppedCount > 0)
+            return;
+
+        while (fPostNotificationChanges !is null) {
+            List changes= fPostNotificationChanges;
+            fPostNotificationChanges= null;
+
+            Iterator e= changes.iterator();
+            while (e.hasNext()) {
+                RegisteredReplace replace= cast(RegisteredReplace) e.next();
+                replace.fReplace.perform(this, replace.fOwner);
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension2#acceptPostNotificationReplaces()
+     * @since 2.1
+     */
+    public void acceptPostNotificationReplaces() {
+        fAcceptPostNotificationReplaces= true;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension2#ignorePostNotificationReplaces()
+     * @since 2.1
+     */
+    public void ignorePostNotificationReplaces() {
+        fAcceptPostNotificationReplaces= false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension#registerPostNotificationReplace(dwtx.jface.text.IDocumentListener, dwtx.jface.text.IDocumentExtension.IReplace)
+     * @since 2.0
+     */
+    public void registerPostNotificationReplace(IDocumentListener owner, IDocumentExtension.IReplace replace) {
+        if (fAcceptPostNotificationReplaces) {
+            if (fPostNotificationChanges is null)
+                fPostNotificationChanges= new ArrayList(1);
+            fPostNotificationChanges.add(new RegisteredReplace(owner, replace));
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension#stopPostNotificationProcessing()
+     * @since 2.0
+     */
+    public void stopPostNotificationProcessing() {
+        ++ fStoppedCount;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension#resumePostNotificationProcessing()
+     * @since 2.0
+     */
+    public void resumePostNotificationProcessing() {
+        -- fStoppedCount;
+        if (fStoppedCount is 0 && fReentranceCount is 0)
+            executePostNotificationChanges();
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension#startSequentialRewrite(bool)
+     * @since 2.0
+     */
+    public void startSequentialRewrite(bool normalized) {
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension#stopSequentialRewrite()
+     * @since 2.0
+     */
+    public void stopSequentialRewrite() {
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension2#resumeListenerNotification()
+     * @since 2.1
+     */
+    public void resumeListenerNotification() {
+        -- fStoppedListenerNotification;
+        if (fStoppedListenerNotification is 0) {
+            resumeDocumentListenerNotification();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension2#stopListenerNotification()
+     * @since 2.1
+     */
+    public void stopListenerNotification() {
+        ++ fStoppedListenerNotification;
+    }
+
+    /**
+     * Resumes the document listener notification by sending out the remembered
+     * partition changed and document event.
+     *
+     * @since 2.1
+     */
+    private void resumeDocumentListenerNotification() {
+        if (fDeferredDocumentEvent !is null) {
+            DocumentEvent event= fDeferredDocumentEvent;
+            fDeferredDocumentEvent= null;
+            doFireDocumentChanged(event);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension3#computeZeroLengthPartitioning(java.lang.String, int, int)
+     * @since 3.0
+     */
+    public ITypedRegion[] computePartitioning(String partitioning, int offset, int length, bool includeZeroLengthPartitions)  {
+        if ((0 > offset) || (0 > length) || (offset + length > getLength()))
+            throw new BadLocationException();
+
+        IDocumentPartitioner partitioner= getDocumentPartitioner(partitioning);
+
+        if ( cast(IDocumentPartitionerExtension2)partitioner ) {
+            checkStateOfPartitioner(partitioner, partitioning);
+            return (cast(IDocumentPartitionerExtension2) partitioner).computePartitioning(offset, length, includeZeroLengthPartitions);
+        } else if (partitioner !is null) {
+            checkStateOfPartitioner(partitioner, partitioning);
+            return partitioner.computePartitioning(offset, length);
+        } else if (DEFAULT_PARTITIONING.equals(partitioning))
+            return [ new TypedRegion(offset, length, DEFAULT_CONTENT_TYPE) ];
+        else
+            throw new BadPartitioningException();
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension3#getZeroLengthContentType(java.lang.String, int)
+     * @since 3.0
+     */
+    public String getContentType(String partitioning, int offset, bool preferOpenPartitions)  {
+        if ((0 > offset) || (offset > getLength()))
+            throw new BadLocationException();
+
+        IDocumentPartitioner partitioner= getDocumentPartitioner(partitioning);
+
+        if ( cast(IDocumentPartitionerExtension2)partitioner ) {
+            checkStateOfPartitioner(partitioner, partitioning);
+            return (cast(IDocumentPartitionerExtension2) partitioner).getContentType(offset, preferOpenPartitions);
+        } else if (partitioner !is null) {
+            checkStateOfPartitioner(partitioner, partitioning);
+            return partitioner.getContentType(offset);
+        } else if (DEFAULT_PARTITIONING.equals(partitioning))
+            return DEFAULT_CONTENT_TYPE;
+        else
+            throw new BadPartitioningException();
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension3#getDocumentPartitioner(java.lang.String)
+     * @since 3.0
+     */
+    public IDocumentPartitioner getDocumentPartitioner(String partitioning)  {
+        return fDocumentPartitioners !is null ? cast(IDocumentPartitioner) fDocumentPartitioners.get(partitioning) : null;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension3#getLegalContentTypes(java.lang.String)
+     * @since 3.0
+     */
+    public String[] getLegalContentTypes(String partitioning)  {
+        IDocumentPartitioner partitioner= getDocumentPartitioner(partitioning);
+        if (partitioner !is null)
+            return partitioner.getLegalContentTypes();
+        if (DEFAULT_PARTITIONING.equals(partitioning))
+            return [ DEFAULT_CONTENT_TYPE ];
+        throw new BadPartitioningException();
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension3#getZeroLengthPartition(java.lang.String, int)
+     * @since 3.0
+     */
+    public ITypedRegion getPartition(String partitioning, int offset, bool preferOpenPartitions)  {
+        if ((0 > offset) || (offset > getLength()))
+            throw new BadLocationException();
+
+        IDocumentPartitioner partitioner= getDocumentPartitioner(partitioning);
+
+        if ( cast(IDocumentPartitionerExtension2)partitioner ) {
+            checkStateOfPartitioner(partitioner, partitioning);
+            return (cast(IDocumentPartitionerExtension2) partitioner).getPartition(offset, preferOpenPartitions);
+        } else if (partitioner !is null) {
+            checkStateOfPartitioner(partitioner, partitioning);
+            return partitioner.getPartition(offset);
+        } else if (DEFAULT_PARTITIONING.equals(partitioning))
+            return new TypedRegion(0, getLength(), DEFAULT_CONTENT_TYPE);
+        else
+            throw new BadPartitioningException();
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension3#getPartitionings()
+     * @since 3.0
+     */
+    public String[] getPartitionings() {
+        if (fDocumentPartitioners is null)
+            return new String[0];
+        return stringcast(fDocumentPartitioners.keySet().toArray());
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension3#setDocumentPartitioner(java.lang.String, dwtx.jface.text.IDocumentPartitioner)
+     * @since 3.0
+     */
+    public void setDocumentPartitioner(String partitioning, IDocumentPartitioner partitioner) {
+        if (partitioner is null) {
+            if (fDocumentPartitioners !is null) {
+                fDocumentPartitioners.remove(partitioning);
+                if (fDocumentPartitioners.size() is 0)
+                    fDocumentPartitioners= null;
+            }
+        } else {
+            if (fDocumentPartitioners is null)
+                fDocumentPartitioners= new HashMap();
+            fDocumentPartitioners.put(partitioning, cast(Object)partitioner);
+        }
+        DocumentPartitioningChangedEvent event= new DocumentPartitioningChangedEvent(this);
+        event.setPartitionChange(partitioning, 0, getLength());
+        fireDocumentPartitioningChanged(event);
+    }
+
+    /*
+     * @see dwtx.jface.text.IRepairableDocument#repairLineInformation()
+     * @since 3.0
+     */
+    public void repairLineInformation() {
+        getTracker().set(get());
+    }
+
+    /**
+     * Fires the given event to all registered rewrite session listeners. Uses robust iterators.
+     *
+     * @param event the event to be fired
+     * @since 3.1
+     */
+    protected void fireRewriteSessionChanged(DocumentRewriteSessionEvent event) {
+        if (fDocumentRewriteSessionListeners.size() > 0) {
+            List list= new ArrayList(fDocumentRewriteSessionListeners);
+            Iterator e= list.iterator();
+            while (e.hasNext()) {
+                IDocumentRewriteSessionListener l= cast(IDocumentRewriteSessionListener) e.next();
+                l.documentRewriteSessionChanged(event);
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension4#getActiveRewriteSession()
+     */
+    public final DocumentRewriteSession getActiveRewriteSession() {
+        return fDocumentRewriteSession;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension4#startRewriteSession(dwtx.jface.text.DocumentRewriteSessionType)
+     * @since 3.1
+     */
+    public DocumentRewriteSession startRewriteSession(DocumentRewriteSessionType sessionType) {
+
+        if (getActiveRewriteSession() !is null)
+            throw new IllegalStateException();
+
+
+        fDocumentRewriteSession= new DocumentRewriteSession(sessionType);
+        if (DEBUG)
+            System.out_.println(Format("AbstractDocument: Starting rewrite session: {}", fDocumentRewriteSession)); //$NON-NLS-1$
+
+        fireRewriteSessionChanged(new DocumentRewriteSessionEvent(this, fDocumentRewriteSession, DocumentRewriteSessionEvent.SESSION_START));
+
+        startRewriteSessionOnPartitioners(fDocumentRewriteSession);
+
+        ILineTracker tracker= getTracker();
+        if ( cast(ILineTrackerExtension)tracker ) {
+            ILineTrackerExtension extension= cast(ILineTrackerExtension) tracker;
+            extension.startRewriteSession(fDocumentRewriteSession);
+        }
+
+        if (DocumentRewriteSessionType.SEQUENTIAL is sessionType)
+            startSequentialRewrite(false);
+        else if (DocumentRewriteSessionType.STRICTLY_SEQUENTIAL is sessionType)
+            startSequentialRewrite(true);
+
+        return fDocumentRewriteSession;
+    }
+
+    /**
+     * Starts the given rewrite session.
+     *
+     * @param session the rewrite session
+     * @since 3.1
+     */
+    protected final void startRewriteSessionOnPartitioners(DocumentRewriteSession session) {
+        if (fDocumentPartitioners !is null) {
+            Iterator e= fDocumentPartitioners.values().iterator();
+            while (e.hasNext()) {
+                Object partitioner= e.next();
+                if ( cast(IDocumentPartitionerExtension3)partitioner ) {
+                    IDocumentPartitionerExtension3 extension= cast(IDocumentPartitionerExtension3) partitioner;
+                    extension.startRewriteSession(session);
+                }
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension4#stopRewriteSession(dwtx.jface.text.DocumentRewriteSession)
+     * @since 3.1
+     */
+    public void stopRewriteSession(DocumentRewriteSession session) {
+        if (fDocumentRewriteSession is session) {
+
+            if (DEBUG)
+                System.out_.println(Format("AbstractDocument: Stopping rewrite session: {}", session)); //$NON-NLS-1$
+
+            DocumentRewriteSessionType sessionType= session.getSessionType();
+            if (DocumentRewriteSessionType.SEQUENTIAL is sessionType || DocumentRewriteSessionType.STRICTLY_SEQUENTIAL is sessionType)
+                stopSequentialRewrite();
+
+            ILineTracker tracker= getTracker();
+            if ( cast(ILineTrackerExtension)tracker ) {
+                ILineTrackerExtension extension= cast(ILineTrackerExtension) tracker;
+                extension.stopRewriteSession(session, get());
+            }
+
+            stopRewriteSessionOnPartitioners(fDocumentRewriteSession);
+
+            fDocumentRewriteSession= null;
+            fireRewriteSessionChanged(new DocumentRewriteSessionEvent(this, session, DocumentRewriteSessionEvent.SESSION_STOP));
+        }
+    }
+
+    /**
+     * Stops the given rewrite session.
+     *
+     * @param session the rewrite session
+     * @since 3.1
+     */
+    protected final void stopRewriteSessionOnPartitioners(DocumentRewriteSession session) {
+        if (fDocumentPartitioners !is null) {
+            DocumentPartitioningChangedEvent event= new DocumentPartitioningChangedEvent(this);
+            Iterator e= fDocumentPartitioners.keySet().iterator();
+            while (e.hasNext()) {
+                String partitioning= stringcast( e.next());
+                IDocumentPartitioner partitioner= cast(IDocumentPartitioner) fDocumentPartitioners.get(partitioning);
+                if ( cast(IDocumentPartitionerExtension3)partitioner ) {
+                    IDocumentPartitionerExtension3 extension= cast(IDocumentPartitionerExtension3) partitioner;
+                    extension.stopRewriteSession(session);
+                    event.setPartitionChange(partitioning, 0, getLength());
+                }
+            }
+            if (!event.isEmpty())
+                fireDocumentPartitioningChanged(event);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension4#addDocumentRewriteSessionListener(dwtx.jface.text.IDocumentRewriteSessionListener)
+     * @since 3.1
+     */
+    public void addDocumentRewriteSessionListener(IDocumentRewriteSessionListener listener) {
+        Assert.isNotNull(cast(Object)listener);
+        if (! fDocumentRewriteSessionListeners.contains(cast(Object)listener))
+            fDocumentRewriteSessionListeners.add(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension4#removeDocumentRewriteSessionListener(dwtx.jface.text.IDocumentRewriteSessionListener)
+     * @since 3.1
+     */
+    public void removeDocumentRewriteSessionListener(IDocumentRewriteSessionListener listener) {
+        Assert.isNotNull(cast(Object)listener);
+        fDocumentRewriteSessionListeners.remove(cast(Object)listener);
+    }
+
+    /**
+     * Checks the state for the given partitioner and stops the
+     * active rewrite session.
+     *
+     * @param partitioner the document partitioner to be checked
+     * @param partitioning the document partitioning the partitioner is registered for
+     * @since 3.1
+     */
+    protected final void checkStateOfPartitioner(IDocumentPartitioner partitioner, String partitioning) {
+        if (!( cast(IDocumentPartitionerExtension3)partitioner ))
+            return;
+
+        IDocumentPartitionerExtension3 extension= cast(IDocumentPartitionerExtension3) partitioner;
+        DocumentRewriteSession session= extension.getActiveRewriteSession();
+        if (session !is null) {
+            extension.stopRewriteSession(session);
+
+            if (DEBUG)
+                System.out_.println(Format("AbstractDocument: Flushing rewrite session for partition type: {}", partitioning)); //$NON-NLS-1$
+
+            DocumentPartitioningChangedEvent event= new DocumentPartitioningChangedEvent(this);
+            event.setPartitionChange(partitioning, 0, getLength());
+            fireDocumentPartitioningChanged(event);
+        }
+    }
+
+    /**
+     * Returns all positions of the given category that are inside the given region.
+     *
+     * @param category the position category
+     * @param offset the start position of the region, must be >= 0
+     * @param length the length of the region, must be >= 0
+     * @param canStartBefore if <code>true</code> then positions are included
+     *            which start before the region if they end at or after the regions start
+     * @param canEndAfter if <code>true</code> then positions are included
+     *            which end after the region if they start at or before the regions end
+     * @return all positions inside the region of the given category
+     * @throws BadPositionCategoryException if category is undefined in this document
+     * @since 3.4
+     */
+    public Position[] getPositions(String category, int offset, int length, bool canStartBefore, bool canEndAfter)  {
+        if (canStartBefore && canEndAfter || (!canStartBefore && !canEndAfter)) {
+            List documentPositions;
+            if (canStartBefore && canEndAfter) {
+                if (offset < getLength() / 2) {
+                    documentPositions= getStartingPositions(category, 0, offset + length);
+                } else {
+                    documentPositions= getEndingPositions(category, offset, getLength() - offset + 1);
+                }
+            } else {
+                documentPositions= getStartingPositions(category, offset, length);
+            }
+
+            ArrayList list= new ArrayList(documentPositions.size());
+
+            Position region= new Position(offset, length);
+
+            for (Iterator iterator= documentPositions.iterator(); iterator.hasNext();) {
+                Position position= cast(Position) iterator.next();
+                if (isWithinRegion(region, position, canStartBefore, canEndAfter)) {
+                    list.add(position);
+                }
+            }
+
+            Position[] positions= new Position[list.size()];
+            list.toArray(positions);
+            return positions;
+        } else if (canStartBefore) {
+            List list= getEndingPositions(category, offset, length);
+            Position[] positions= new Position[list.size()];
+            list.toArray(positions);
+            return positions;
+        } else {
+            Assert.isLegal(canEndAfter && !canStartBefore);
+
+            List list= getStartingPositions(category, offset, length);
+            Position[] positions= new Position[list.size()];
+            list.toArray(positions);
+            return positions;
+        }
+    }
+
+    /*
+     * @since 3.4
+     */
+    private bool isWithinRegion(Position region, Position position, bool canStartBefore, bool canEndAfter) {
+        if (canStartBefore && canEndAfter) {
+            return region.overlapsWith(position.getOffset(), position.getLength());
+        } else if (canStartBefore) {
+            return region.includes(position.getOffset() + position.getLength() - 1);
+        } else if (canEndAfter) {
+            return region.includes(position.getOffset());
+        } else {
+            int start= position.getOffset();
+            return region.includes(start) && region.includes(start + position.getLength() - 1);
+        }
+    }
+
+    /**
+     * A list of positions in the given category with an offset inside the given
+     * region. The order of the positions is arbitrary.
+     *
+     * @param category the position category
+     * @param offset the offset of the region
+     * @param length the length of the region
+     * @return a list of the positions in the region
+     * @throws BadPositionCategoryException if category is undefined in this document
+     * @since 3.4
+     */
+    private List getStartingPositions(String category, int offset, int length)  {
+        List positions= cast(List) fPositions.get(category);
+        if (positions is null)
+            throw new BadPositionCategoryException();
+
+        int indexStart= computeIndexInPositionList(positions, offset, true);
+        int indexEnd= computeIndexInPositionList(positions, offset + length, true);
+
+        return positions.subList(indexStart, indexEnd);
+    }
+
+    /**
+     * A list of positions in the given category with an end position inside
+     * the given region. The order of the positions is arbitrary.
+     *
+     * @param category the position category
+     * @param offset the offset of the region
+     * @param length the length of the region
+     * @return a list of the positions in the region
+     * @throws BadPositionCategoryException if category is undefined in this document
+     * @since 3.4
+     */
+    private List getEndingPositions(String category, int offset, int length)  {
+        List positions= cast(List) fEndPositions.get(category);
+        if (positions is null)
+            throw new BadPositionCategoryException();
+
+        int indexStart= computeIndexInPositionList(positions, offset, false);
+        int indexEnd= computeIndexInPositionList(positions, offset + length, false);
+
+        return positions.subList(indexStart, indexEnd);
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/AbstractHoverInformationControlManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1138 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.AbstractHoverInformationControlManager;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+import tango.text.convert.Format;
+
+import dwt.DWT;
+import dwt.events.ControlEvent;
+import dwt.events.ControlListener;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.events.MouseMoveListener;
+import dwt.events.MouseTrackListener;
+import dwt.events.SelectionEvent;
+import dwt.events.SelectionListener;
+import dwt.events.ShellAdapter;
+import dwt.events.ShellEvent;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwt.widgets.ScrollBar;
+import dwt.widgets.Scrollable;
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.IProgressMonitor;
+import dwtx.core.runtime.IStatus;
+import dwtx.core.runtime.Status;
+import dwtx.core.runtime.jobs.Job;
+import dwtx.jface.internal.text.DelayedInputChangeListener;
+import dwtx.jface.internal.text.InformationControlReplacer;
+import dwtx.jface.internal.text.InternalAccessor;
+import dwtx.jface.text.ITextViewerExtension8;
+import dwtx.jface.text.source.AnnotationBarHoverManager;
+import dwtx.jface.util.Geometry;
+
+
+/**
+ * An information control manager that shows information in response to mouse
+ * hover events. The mouse hover events are caught by registering a
+ * {@link dwt.events.MouseTrackListener} on the manager's subject
+ * control. The manager has by default an information control closer that closes
+ * the information control as soon as the mouse pointer leaves the subject area,
+ * the user presses a key, or the subject control is resized, moved, or
+ * deactivated.
+ * <p>
+ * When being activated by a mouse hover event, the manager disables itself,
+ * until the mouse leaves the subject area. Thus, the manager is usually still
+ * disabled, when the information control has already been closed by the closer.
+ *
+ * @see dwt.events.MouseTrackListener
+ * @since 2.0
+ */
+abstract public class AbstractHoverInformationControlManager : AbstractInformationControlManager {
+
+    /**
+     * The  information control closer for the hover information. Closes the information control as
+     * soon as the mouse pointer leaves the subject area (unless "move into hover" is enabled),
+     * a mouse button is pressed, the user presses a key, or the subject control is resized, moved, or loses focus.
+     */
+    class Closer : IInformationControlCloser, MouseListener, MouseMoveListener, ControlListener, KeyListener, SelectionListener, Listener {
+
+        /** The closer's subject control */
+        private Control fSubjectControl;
+        /** The subject area */
+        private Rectangle fSubjectArea;
+        /** Indicates whether this closer is active */
+        private bool fIsActive= false;
+        /**
+         * The cached display.
+         * @since 3.1
+         */
+        private Display fDisplay;
+
+
+        /**
+         * Creates a new information control closer.
+         */
+        public this() {
+        }
+
+        /*
+         * @see IInformationControlCloser#setSubjectControl(Control)
+         */
+        public void setSubjectControl(Control control) {
+            fSubjectControl= control;
+        }
+
+        /*
+         * @see IInformationControlCloser#setHoverControl(IHoverControl)
+         */
+        public void setInformationControl(IInformationControl control) {
+            // NOTE: we use getCurrentInformationControl() from the outer class
+        }
+
+        /*
+         * @see IInformationControlCloser#start(Rectangle)
+         */
+        public void start(Rectangle subjectArea) {
+
+            if (fIsActive)
+                return;
+            fIsActive= true;
+            fWaitForMouseUp= false;
+
+            fSubjectArea= subjectArea;
+
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
+                fSubjectControl.addMouseListener(this);
+                fSubjectControl.addMouseMoveListener(this);
+                fSubjectControl.addControlListener(this);
+                fSubjectControl.addKeyListener(this);
+                if ( cast(Scrollable)fSubjectControl ) {
+                    Scrollable scrollable= cast(Scrollable) fSubjectControl;
+                    ScrollBar vBar= scrollable.getVerticalBar();
+                    if (vBar !is null)
+                        vBar.addSelectionListener(this);
+                    ScrollBar hBar= scrollable.getHorizontalBar();
+                    if (hBar !is null)
+                        hBar.addSelectionListener(this);
+                }
+
+                fDisplay= fSubjectControl.getDisplay();
+                if (!fDisplay.isDisposed()) {
+                    fDisplay.addFilter(DWT.Activate, this);
+                    fDisplay.addFilter(DWT.MouseWheel, this);
+
+                    fDisplay.addFilter(DWT.FocusOut, this);
+
+                    fDisplay.addFilter(DWT.MouseDown, this);
+                    fDisplay.addFilter(DWT.MouseUp, this);
+
+                    fDisplay.addFilter(DWT.MouseMove, this);
+                    fDisplay.addFilter(DWT.MouseEnter, this);
+                    fDisplay.addFilter(DWT.MouseExit, this);
+                }
+            }
+        }
+
+        /*
+         * @see IInformationControlCloser#stop()
+         */
+        public void stop() {
+            if (!fIsActive)
+                return;
+
+            fIsActive= false;
+
+            if (DEBUG)
+                System.out_.println("AbstractHoverInformationControlManager.Closer stopped"); //$NON-NLS-1$
+
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
+                fSubjectControl.removeMouseListener(this);
+                fSubjectControl.removeMouseMoveListener(this);
+                fSubjectControl.removeControlListener(this);
+                fSubjectControl.removeKeyListener(this);
+                if ( cast(Scrollable)fSubjectControl ) {
+                    Scrollable scrollable= cast(Scrollable) fSubjectControl;
+                    ScrollBar vBar= scrollable.getVerticalBar();
+                    if (vBar !is null)
+                        vBar.removeSelectionListener(this);
+                    ScrollBar hBar= scrollable.getHorizontalBar();
+                    if (hBar !is null)
+                        hBar.removeSelectionListener(this);
+                }
+            }
+
+            if (fDisplay !is null && !fDisplay.isDisposed()) {
+                fDisplay.removeFilter(DWT.Activate, this);
+                fDisplay.removeFilter(DWT.MouseWheel, this);
+
+                fDisplay.removeFilter(DWT.FocusOut, this);
+
+                fDisplay.removeFilter(DWT.MouseDown, this);
+                fDisplay.removeFilter(DWT.MouseUp, this);
+
+                fDisplay.removeFilter(DWT.MouseMove, this);
+                fDisplay.removeFilter(DWT.MouseEnter, this);
+                fDisplay.removeFilter(DWT.MouseExit, this);
+            }
+            fDisplay= null;
+        }
+
+        /*
+         * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent)
+         */
+        public void mouseMove(MouseEvent event) {
+            if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(getCurrentInformationControl())) {
+                if (!fSubjectArea.contains(event.x, event.y)) {
+                    hideInformationControl();
+                }
+
+            } else if (getCurrentInformationControl() !is null && !getCurrentInformationControl().isFocusControl()) {
+                if (!inKeepUpZone(event.x, event.y, fSubjectControl, fSubjectArea, true)) {
+                    hideInformationControl();
+                }
+            }
+        }
+
+        /*
+         * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent)
+         */
+        public void mouseUp(MouseEvent event) {
+        }
+
+        /*
+         * @see MouseListener#mouseDown(MouseEvent)
+         */
+        public void mouseDown(MouseEvent event) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see MouseListener#mouseDoubleClick(MouseEvent)
+         */
+        public void mouseDoubleClick(MouseEvent event) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see ControlListener#controlResized(ControlEvent)
+         */
+        public void controlResized(ControlEvent event) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see ControlListener#controlMoved(ControlEvent)
+         */
+        public void controlMoved(ControlEvent event) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see KeyListener#keyReleased(KeyEvent)
+         */
+        public void keyReleased(KeyEvent event) {
+        }
+
+        /*
+         * @see KeyListener#keyPressed(KeyEvent)
+         */
+        public void keyPressed(KeyEvent event) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see dwt.events.SelectionListener#widgetSelected(dwt.events.SelectionEvent)
+         */
+        public void widgetSelected(SelectionEvent e) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see dwt.events.SelectionListener#widgetDefaultSelected(dwt.events.SelectionEvent)
+         */
+        public void widgetDefaultSelected(SelectionEvent e) {
+        }
+
+        /*
+         * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event)
+         * @since 3.1
+         */
+        public void handleEvent(Event event) {
+            switch (event.type) {
+                case DWT.Activate:
+                case DWT.MouseWheel:
+                    if (!hasInformationControlReplacer())
+                        hideInformationControl();
+                    else if (!isReplaceInProgress()) {
+                        IInformationControl infoControl= getCurrentInformationControl();
+                        // During isReplaceInProgress(), events can come from the replacing information control
+                        if ( cast(Control)event.widget  && cast(IInformationControlExtension5)infoControl ) {
+                            Control control= cast(Control) event.widget;
+                            IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) infoControl;
+                            if (!(iControl5.containsControl(control)))
+                                hideInformationControl();
+                            else if (event.type is DWT.MouseWheel && cancelReplacingDelay())
+                                replaceInformationControl(false);
+                        } else if (infoControl !is null && infoControl.isFocusControl() && cancelReplacingDelay()) {
+                            replaceInformationControl(true);
+                        }
+                    }
+                    break;
+
+                case DWT.MouseUp:
+                case DWT.MouseDown:
+                    if (!hasInformationControlReplacer())
+                        hideInformationControl();
+                    else if (!isReplaceInProgress()) {
+                        IInformationControl infoControl= getCurrentInformationControl();
+                        if ( cast(Control)event.widget  && cast(IInformationControlExtension5)infoControl ) {
+                            Control control= cast(Control) event.widget;
+                            final IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) infoControl;
+                            if (!(iControl5.containsControl(control))) {
+                                hideInformationControl();
+                            } else if (cancelReplacingDelay()) {
+                                if (event.type is DWT.MouseUp) {
+                                    stop(); // avoid that someone else replaces the info control before the async is exec'd
+                                    if ( cast(IDelayedInputChangeProvider)infoControl ) {
+                                        final IDelayedInputChangeProvider delayedICP= cast(IDelayedInputChangeProvider) infoControl;
+                                        final IInputChangedListener inputChangeListener= new DelayedInputChangeListener(delayedICP, getInformationControlReplacer());
+                                        delayedICP.setDelayedInputChangeListener(inputChangeListener);
+                                        // cancel automatic input updating after a small timeout:
+                                        control.getShell().getDisplay().timerExec(1000, new class()  Runnable {
+                                            public void run() {
+                                                delayedICP.setDelayedInputChangeListener(null);
+                                            }
+                                        });
+                                    }
+
+                                    // XXX: workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=212392 :
+                                    control.getShell().getDisplay().asyncExec(new class()  Runnable {
+                                        public void run() {
+                                            replaceInformationControl(true);
+                                        }
+                                    });
+                                } else {
+                                    fWaitForMouseUp= true;
+                                }
+                            }
+                        } else {
+                            handleMouseMove(event);
+                        }
+                    }
+                    break;
+
+                case DWT.FocusOut:
+                    IInformationControl iControl= getCurrentInformationControl();
+                    if (iControl !is null && ! iControl.isFocusControl())
+                        hideInformationControl();
+                    break;
+
+                case DWT.MouseMove:
+                case DWT.MouseEnter:
+                case DWT.MouseExit:
+                    handleMouseMove(event);
+                    break;
+            }
+        }
+
+        /**
+         * Handle mouse movement events.
+         *
+         * @param event the event
+         * @since 3.4
+         */
+        private void handleMouseMove(Event event) {
+//          if (DEBUG)
+//              System.out_.println("AbstractHoverInformationControl.Closer.handleMouseMove():" + event); //$NON-NLS-1$
+
+            if (!( cast(Control)event.widget ))
+                return;
+            Control eventControl= cast(Control) event.widget;
+
+            //transform coordinates to subject control:
+            Point mouseLoc= event.display.map(eventControl, fSubjectControl, event.x, event.y);
+
+            if (fSubjectArea.contains(mouseLoc))
+                return;
+
+            IInformationControl iControl= getCurrentInformationControl();
+            if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(iControl)) {
+                if ( cast(AnnotationBarHoverManager)this.outer ) {
+                    if (getInternalAccessor().getAllowMouseExit())
+                        return;
+                }
+                hideInformationControl();
+                return;
+            }
+
+            IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) iControl;
+            Rectangle controlBounds= iControl3.getBounds();
+            if (controlBounds !is null) {
+                Rectangle tooltipBounds= event.display.map(null, eventControl, controlBounds);
+                if (tooltipBounds.contains(event.x, event.y)) {
+                    if (!isReplaceInProgress() && event.type !is DWT.MouseExit)
+                        startReplaceInformationControl(event.display);
+                    return;
+                }
+                cancelReplacingDelay();
+            }
+
+            if (!fSubjectControl.getBounds().contains(mouseLoc)) {
+                /*
+                 *  Use inKeepUpZone() to make sure it also works when the hover is
+                 *  completely outside of the subject control.
+                 */
+                if (!inKeepUpZone(mouseLoc.x, mouseLoc.y, fSubjectControl, fSubjectArea, true)) {
+                    hideInformationControl();
+                    return;
+                }
+            }
+        }
+    }
+
+    /**
+     * To be installed on the manager's subject control.  Serves two different purposes:
+     * <ul>
+     * <li> start function: initiates the computation of the information to be presented. This happens on
+     *      receipt of a mouse hover event and disables the information control manager,
+     * <li> restart function: tracks mouse move and shell activation event to determine when the information
+     *      control manager needs to be reactivated.
+     * </ul>
+     */
+    class MouseTracker : ShellAdapter , MouseTrackListener, MouseMoveListener {
+
+        /** Margin around the original hover event location for computing the hover area. */
+        private const static int EPSILON= 3;
+
+        /** The area in which the original hover event occurred. */
+        private Rectangle fHoverArea;
+        /** The area for which is computed information is valid. */
+        private Rectangle fSubjectArea;
+        /** The tracker's subject control. */
+        private Control fSubjectControl;
+
+        /** Indicates whether the tracker is in restart mode ignoring hover events. */
+        private bool fIsInRestartMode= false;
+        /** Indicates whether the tracker is computing the information to be presented. */
+        private bool fIsComputing= false;
+        /** Indicates whether the mouse has been lost. */
+        private bool fMouseLostWhileComputing= false;
+        /** Indicates whether the subject control's shell has been deactivated. */
+        private bool fShellDeactivatedWhileComputing= false;
+
+        /**
+         * Creates a new mouse tracker.
+         */
+        public this() {
+        }
+
+        /**
+         * Sets this mouse tracker's subject area, the area to be tracked in order
+         * to re-enable the information control manager.
+         *
+         * @param subjectArea the subject area
+         */
+        public void setSubjectArea(Rectangle subjectArea) {
+            Assert.isNotNull(subjectArea);
+            fSubjectArea= subjectArea;
+        }
+
+        /**
+         * Starts this mouse tracker. The given control becomes this tracker's subject control.
+         * Installs itself as mouse track listener on the subject control.
+         *
+         * @param subjectControl the subject control
+         */
+        public void start(Control subjectControl) {
+            fSubjectControl= subjectControl;
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed())
+                fSubjectControl.addMouseTrackListener(this);
+
+            fIsInRestartMode= false;
+            fIsComputing= false;
+            fMouseLostWhileComputing= false;
+            fShellDeactivatedWhileComputing= false;
+        }
+
+        /**
+         * Stops this mouse tracker. Removes itself  as mouse track, mouse move, and
+         * shell listener from the subject control.
+         */
+        public void stop() {
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
+                fSubjectControl.removeMouseTrackListener(this);
+                fSubjectControl.removeMouseMoveListener(this);
+                fSubjectControl.getShell().removeShellListener(this);
+            }
+        }
+
+        /**
+         * Initiates the computation of the information to be presented. Sets the initial hover area
+         * to a small rectangle around the hover event location. Adds mouse move and shell activation listeners
+         * to track whether the computed information is, after completion, useful for presentation and to
+         * implement the restart function.
+         *
+         * @param event the mouse hover event
+         */
+        public void mouseHover(MouseEvent event) {
+            if (fIsComputing || fIsInRestartMode ||
+                    (fSubjectControl !is null && !fSubjectControl.isDisposed() && fSubjectControl.getShell() !is fSubjectControl.getShell().getDisplay().getActiveShell())) {
+                if (DEBUG)
+                    System.out_.println(Format("AbstractHoverInformationControlManager...mouseHover: @ {}/{} : hover cancelled: fIsComputing= {}, fIsInRestartMode= {}", event.x, event.y, fIsComputing, fIsInRestartMode)); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+                return;
+            }
+
+            fIsInRestartMode= true;
+            fIsComputing= true;
+            fMouseLostWhileComputing= false;
+            fShellDeactivatedWhileComputing= false;
+
+            fHoverEventStateMask= event.stateMask;
+            fHoverEvent= event;
+            fHoverArea= new Rectangle(event.x - EPSILON, event.y - EPSILON, 2 * EPSILON, 2 * EPSILON );
+            if (fHoverArea.x < 0)
+                fHoverArea.x= 0;
+            if (fHoverArea.y < 0)
+                fHoverArea.y= 0;
+            setSubjectArea(fHoverArea);
+
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
+                fSubjectControl.addMouseMoveListener(this);
+                fSubjectControl.getShell().addShellListener(this);
+            }
+            doShowInformation();
+        }
+
+        /**
+         * Deactivates this tracker's restart function and enables the information control
+         * manager. Does not have any effect if the tracker is still executing the start function (i.e.
+         * computing the information to be presented.
+         */
+        protected void deactivate() {
+            if (fIsComputing)
+                return;
+
+            fIsInRestartMode= false;
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
+                fSubjectControl.removeMouseMoveListener(this);
+                fSubjectControl.getShell().removeShellListener(this);
+            }
+        }
+
+        /*
+         * @see MouseTrackListener#mouseEnter(MouseEvent)
+         */
+        public void mouseEnter(MouseEvent e) {
+        }
+
+        /*
+         * @see MouseTrackListener#mouseExit(MouseEvent)
+         */
+        public void mouseExit(MouseEvent e) {
+            if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(getCurrentInformationControl()) || !inKeepUpZone(e.x, e.y, fSubjectControl, fSubjectArea, false)) {
+                fMouseLostWhileComputing= true;
+                deactivate();
+            }
+        }
+
+        /*
+         * @see MouseMoveListener#mouseMove(MouseEvent)
+         */
+        public void mouseMove(MouseEvent event) {
+            if (!hasInformationControlReplacer() || !canMoveIntoInformationControl(getCurrentInformationControl())) {
+                if (!fSubjectArea.contains(event.x, event.y))
+                    deactivate();
+            } else {
+                if (!inKeepUpZone(event.x, event.y, fSubjectControl, fSubjectArea, false))
+                    deactivate();
+            }
+        }
+
+        /*
+         * @see ShellListener#shellDeactivated(ShellEvent)
+         */
+        public void shellDeactivated(ShellEvent e) {
+            fShellDeactivatedWhileComputing= true;
+            deactivate();
+        }
+
+        /*
+         * @see ShellListener#shellIconified(ShellEvent)
+         */
+        public void shellIconified(ShellEvent e) {
+            fShellDeactivatedWhileComputing= true;
+            deactivate();
+        }
+
+        /**
+         * Tells this tracker that the start function processing has been completed.
+         */
+        public void computationCompleted() {
+            fIsComputing= false;
+            fMouseLostWhileComputing= false;
+            fShellDeactivatedWhileComputing= false;
+        }
+
+        /**
+         * Determines whether the computed information is still useful for presentation.
+         * This is not the case, if the shell of the subject control has been deactivated, the mouse
+         * left the subject control, or the mouse moved on, so that it is no longer in the subject
+         * area.
+         *
+         * @return <code>true</code> if information is still useful for presentation, <code>false</code> otherwise
+         */
+        public bool isMouseLost() {
+
+            if (fMouseLostWhileComputing || fShellDeactivatedWhileComputing)
+                return true;
+
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
+                Display display= fSubjectControl.getDisplay();
+                Point p= display.getCursorLocation();
+                p= fSubjectControl.toControl(p);
+                if (!fSubjectArea.contains(p) && !fHoverArea.contains(p))
+                    return true;
+            }
+
+            return false;
+        }
+    }
+
+    /**
+     * The delay in {@link ITextViewerExtension8.EnrichMode#AFTER_DELAY} mode after which
+     * the hover is enriched when the mouse has stopped moving inside the hover.
+     * @since 3.4
+     */
+    private static const long HOVER_AUTO_REPLACING_DELAY= 200;
+
+    /** The mouse tracker on the subject control */
+    private MouseTracker fMouseTracker;
+    /**
+     * The remembered hover event.
+     * @since 3.0
+     */
+    private MouseEvent fHoverEvent= null;
+    /** The remembered hover event state mask of the keyboard modifiers */
+    private int fHoverEventStateMask= 0;
+    /**
+     * The thread that delays replacing of the hover information control.
+     * To be accessed in the UI thread only!
+     *
+     * @since 3.4
+     */
+    private Job fReplacingDelayJob;
+
+    /**
+     * The {@link ITextViewerExtension8.EnrichMode}, may be <code>null</code>.
+     * @since 3.4
+     */
+    private ITextViewerExtension8_EnrichMode fEnrichMode;
+
+    /**
+     * Indicates whether we have received a MouseDown event and are waiting for a MouseUp
+     * (and don't replace the information control until that happened).
+     * @since 3.4
+     */
+    private bool fWaitForMouseUp= false;
+
+    /**
+     * Creates a new hover information control manager using the given information control creator.
+     * By default a <code>Closer</code> instance is set as this manager's closer.
+     *
+     * @param creator the information control creator
+     */
+    protected this(IInformationControlCreator creator) {
+        fMouseTracker= new MouseTracker();
+        super(creator);
+        setCloser(new Closer());
+        setHoverEnrichMode(ITextViewerExtension8_EnrichMode.AFTER_DELAY);
+    }
+
+    /**
+     * Tests whether a given mouse location is within the keep-up zone.
+     * The hover should not be hidden as long as the mouse stays inside this zone.
+     *
+     * @param x the x coordinate, relative to the <em>subject control</em>
+     * @param y the y coordinate, relative to the <em>subject control</em>
+     * @param subjectControl the subject control
+     * @param subjectArea the area for which the presented information is valid
+     * @param blowUp If <code>true</code>, then calculate for the closer, i.e. blow up the keepUp area.
+     *        If <code>false</code>, then use tight bounds for hover detection.
+     *
+     * @return <code>true</code> iff the mouse event occurred in the keep-up zone
+     * @since 3.4
+     */
+    private bool inKeepUpZone(int x, int y, Control subjectControl, Rectangle subjectArea, bool blowUp) {
+        if (subjectArea.contains(x, y))
+            return true;
+
+        IInformationControl iControl= getCurrentInformationControl();
+        if (( cast(IInformationControlExtension5)iControl  && !(cast(IInformationControlExtension5) iControl).isVisible())) {
+            iControl= null;
+            if (getInformationControlReplacer() !is null) {
+                iControl= getInformationControlReplacer().getCurrentInformationControl2();
+                if (( cast(IInformationControlExtension5)iControl  && !(cast(IInformationControlExtension5) iControl).isVisible())) {
+                    return false;
+                }
+            }
+        }
+        if ( cast(IInformationControlExtension3)iControl ) {
+            IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) iControl;
+
+            Rectangle iControlBounds= subjectControl.getDisplay().map(null, subjectControl, iControl3.getBounds());
+            Rectangle totalBounds= Geometry.copy(iControlBounds);
+            if (blowUp && isReplaceInProgress()) {
+                //Problem: blown up iControl overlaps rest of subjectArea's line
+                // solution for now: only blow up for keep up (closer), but not for further hover detection
+                int margin= getInformationControlReplacer().getKeepUpMargin();
+                Geometry.expand(totalBounds, margin, margin, margin, margin);
+            }
+
+            if (!blowUp) {
+                if (iControlBounds.contains(x, y))
+                    return true;
+
+                if (subjectArea.y + subjectArea.height < iControlBounds.y) {
+                    // special case for hover events: subjectArea totally above iControl:
+                    //  +-----------+
+                    //  |subjectArea|
+                    //  +-----------+
+                    //  |also keepUp|
+                    // ++-----------+-------+
+                    // | InformationControl |
+                    // +--------------------+
+                    if (subjectArea.y + subjectArea.height <= y && y <= totalBounds.y) {
+                        // is vertically between subject area and iControl
+                        if (subjectArea.x <= x && x <= subjectArea.x + subjectArea.width) {
+                            // is below subject area (in a vertical projection)
+                            return true;
+                        }
+                        // FIXME: cases when subjectArea extends to left or right of iControl?
+                    }
+                    return false;
+
+                } else if (iControlBounds.x + iControlBounds.width < subjectArea.x) {
+                    // special case for hover events (e.g. in overview ruler): iControl totally left of subjectArea
+                    // +--------------------+-----------+
+                    // |                    |           +-----------+
+                    // | InformationControl |also keepUp|subjectArea|
+                    // |                    |           +-----------+
+                    // +--------------------+-----------+
+                    if (iControlBounds.x + iControlBounds.width <= x && x <= subjectArea.x) {
+                        // is horizontally between iControl and subject area
+                        if (iControlBounds.y <= y && y <= iControlBounds.y + iControlBounds.height) {
+                            // is to the right of iControl (in a horizontal projection)
+                            return true;
+                        }
+                    }
+                    return false;
+
+                } else if (subjectArea.x + subjectArea.width < iControlBounds.x) {
+                    // special case for hover events (e.g. in annotation ruler): subjectArea totally left of iControl
+                    //             +-----------+--------------------+
+                    // +-----------+           |                    |
+                    // |subjectArea|also keepUp| InformationControl |
+                    // +-----------+           |                    |
+                    //             +-----------+--------------------+
+                    if (subjectArea.x + subjectArea.width <= x && x <= iControlBounds.x) {
+                        // is horizontally between subject area and iControl
+                        if (iControlBounds.y <= y && y <= iControlBounds.y + iControlBounds.height) {
+                            // is to the left of iControl (in a horizontal projection)
+                            return true;
+                        }
+                    }
+                    return false;
+                }
+            }
+
+            // FIXME: should maybe use convex hull, not bounding box
+            totalBounds.add(subjectArea);
+            if (totalBounds.contains(x, y))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Tests whether the given information control allows the mouse to be moved
+     * into it.
+     *
+     * @param iControl information control or <code>null</code> if none
+     * @return <code>true</code> if information control allows mouse move into
+     *         control, <code>false</code> otherwise
+     */
+    bool canMoveIntoInformationControl(IInformationControl iControl) {
+        return fEnrichMode !is null && canReplace(iControl);
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl()
+     */
+    protected void hideInformationControl() {
+        cancelReplacingDelay();
+        super.hideInformationControl();
+    }
+
+    /**
+     * Sets the hover enrich mode. Only applicable when an information
+     * control replacer has been set with
+     * {@link #setInformationControlReplacer(InformationControlReplacer)} .
+     *
+     * @param mode the enrich mode
+     * @since 3.4
+     * @see ITextViewerExtension8#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode)
+     */
+    void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode) {
+        fEnrichMode= mode;
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#replaceInformationControl(bool)
+     */
+    void replaceInformationControl(bool takeFocus) {
+        fWaitForMouseUp= false;
+        super.replaceInformationControl(takeFocus);
+    }
+
+    /**
+     * Cancels the replacing delay job.
+     * @return <code>true</code> iff canceling was successful, <code>false</code> if replacing has already started
+     */
+    bool cancelReplacingDelay() {
+        fWaitForMouseUp= false;
+        if (fReplacingDelayJob !is null && fReplacingDelayJob.getState() !is Job.RUNNING) {
+            bool cancelled= fReplacingDelayJob.cancel();
+            fReplacingDelayJob= null;
+//          if (DEBUG)
+//              System.out_.println("AbstractHoverInformationControlManager.cancelReplacingDelay(): cancelled=" + cancelled); //$NON-NLS-1$
+            return cancelled;
+        }
+//      if (DEBUG)
+//          System.out_.println("AbstractHoverInformationControlManager.cancelReplacingDelay(): not delayed"); //$NON-NLS-1$
+        return true;
+    }
+
+    /**
+     * Starts replacing the information control, considering the current
+     * {@link ITextViewerExtension8.EnrichMode}.
+     * If set to {@link ITextViewerExtension8.EnrichMode#AFTER_DELAY}, this
+     * method cancels previous requests and restarts the delay timer.
+     *
+     * @param display the display to be used for the call to
+     *        {@link #replaceInformationControl(bool)} in the UI thread
+     */
+    private void startReplaceInformationControl(Display display) {
+        if (fEnrichMode is ITextViewerExtension8_EnrichMode.ON_CLICK)
+            return;
+
+        if (fReplacingDelayJob !is null) {
+            if (fReplacingDelayJob.getState() !is Job.RUNNING) {
+                if (fReplacingDelayJob.cancel()) {
+                    if (fEnrichMode is ITextViewerExtension8_EnrichMode.IMMEDIATELY) {
+                        fReplacingDelayJob= null;
+                        if (! fWaitForMouseUp)
+                            replaceInformationControl(false);
+                    } else {
+//                      if (DEBUG)
+//                          System.out_.println("AbstractHoverInformationControlManager.startReplaceInformationControl(): rescheduled"); //$NON-NLS-1$
+                        fReplacingDelayJob.schedule(HOVER_AUTO_REPLACING_DELAY);
+                    }
+                }
+            }
+            return;
+        }
+
+        fReplacingDelayJob= new class("AbstractHoverInformationControlManager Replace Delayer", display) Job { //$NON-NLS-1$
+            Display display_;
+            this( String str, Display b){
+                super(str);
+                display_=b;
+            }
+            public IStatus run(IProgressMonitor monitor) {
+                if (monitor.isCanceled() || display_.isDisposed()) {
+                    return Status.CANCEL_STATUS;
+                }
+                display_.syncExec(dgRunnable( (IProgressMonitor monitor_) {
+                    fReplacingDelayJob= null;
+                    if (monitor_.isCanceled())
+                        return;
+                    if (! fWaitForMouseUp)
+                        replaceInformationControl(false);
+                }, monitor ));
+                return Status.OK_STATUS;
+            }
+        };
+        fReplacingDelayJob.setSystem(true);
+        fReplacingDelayJob.setPriority(Job.INTERACTIVE);
+//      if (DEBUG)
+//          System.out_.println("AbstractHoverInformationControlManager.startReplaceInformationControl(): scheduled"); //$NON-NLS-1$
+        fReplacingDelayJob.schedule(HOVER_AUTO_REPLACING_DELAY);
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#presentInformation()
+     */
+    protected void presentInformation() {
+        if (fMouseTracker is null) {
+            super.presentInformation();
+            return;
+        }
+
+        Rectangle area= getSubjectArea();
+        if (area !is null)
+            fMouseTracker.setSubjectArea(area);
+
+        if (fMouseTracker.isMouseLost()) {
+            fMouseTracker.computationCompleted();
+            fMouseTracker.deactivate();
+        } else {
+            fMouseTracker.computationCompleted();
+            super.presentInformation();
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * @deprecated visibility will be changed to protected
+     */
+    public void setEnabled(bool enabled) {
+
+        bool was= isEnabled();
+        super.setEnabled(enabled);
+        bool is_= isEnabled();
+
+        if (was !is is_ && fMouseTracker !is null) {
+            if (is_)
+                fMouseTracker.start(getSubjectControl());
+            else
+                fMouseTracker.stop();
+        }
+    }
+
+    /**
+     * Disposes this manager's information control.
+     */
+    public void dispose() {
+        if (fMouseTracker !is null) {
+            fMouseTracker.stop();
+            fMouseTracker.fSubjectControl= null;
+            fMouseTracker= null;
+        }
+        super.dispose();
+    }
+
+    /**
+     * Returns the location at which the most recent mouse hover event
+     * has been issued.
+     *
+     * @return the location of the most recent mouse hover event
+     */
+    protected Point getHoverEventLocation() {
+        return fHoverEvent !is null ? new Point(fHoverEvent.x, fHoverEvent.y) : new Point(-1, -1);
+    }
+    package Point getHoverEventLocation_package() {
+        return getHoverEventLocation();
+    }
+
+    /**
+     * Returns the most recent mouse hover event.
+     *
+     * @return the most recent mouse hover event or <code>null</code>
+     * @since 3.0
+     */
+    protected MouseEvent getHoverEvent() {
+        return fHoverEvent;
+    }
+
+    /**
+     * Returns the DWT event state of the most recent mouse hover event.
+     *
+     * @return the DWT event state of the most recent mouse hover event
+     */
+    protected int getHoverEventStateMask() {
+        return fHoverEventStateMask;
+    }
+
+    /**
+     * Returns an adapter that gives access to internal methods.
+     * <p>
+     * <strong>Note:</strong> This method is not intended to be referenced or overridden by clients.</p>
+     *
+     * @return the replaceable information control accessor
+     * @since 3.4
+     * @noreference This method is not intended to be referenced by clients.
+     * @nooverride This method is not intended to be re-implemented or extended by clients.
+     */
+    public InternalAccessor getInternalAccessor() {
+        return new MyInternalAccessor2(this);
+    }
+        static class MyInternalAccessor2 : MyInternalAccessor {
+            AbstractHoverInformationControlManager outer_;
+            this( AbstractHoverInformationControlManager a ){
+                outer_=a;
+                super(a);
+            }
+            public void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode) {
+                outer_.setHoverEnrichMode(mode);
+            }
+        }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/AbstractInformationControl.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,900 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.AbstractInformationControl;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+// import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwt.DWT;
+import dwt.events.DisposeListener;
+import dwt.events.FocusEvent;
+import dwt.events.FocusListener;
+import dwt.events.MouseAdapter;
+import dwt.events.MouseEvent;
+import dwt.events.MouseMoveListener;
+import dwt.events.PaintEvent;
+import dwt.events.PaintListener;
+import dwt.graphics.Color;
+import dwt.graphics.Cursor;
+import dwt.graphics.Font;
+import dwt.graphics.FontData;
+import dwt.graphics.GC;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.layout.FillLayout;
+import dwt.layout.GridData;
+import dwt.layout.GridLayout;
+import dwt.widgets.Canvas;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Label;
+import dwt.widgets.Listener;
+import dwt.widgets.Shell;
+import dwt.widgets.Slider;
+import dwt.widgets.ToolBar;
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.ListenerList;
+import dwtx.jface.action.ToolBarManager;
+import dwtx.jface.resource.JFaceResources;
+import dwtx.jface.util.Geometry;
+
+
+/**
+ * An abstract information control that can show content inside a shell.
+ * The information control can be created in two styles:
+ * <ul>
+ *  <li>non-resizable tooltip with optional status</li>
+ *  <li>resizable tooltip with optional tool bar</li>
+ * </ul>
+ * Additionally it can present either a status line containing a status text or
+ * a toolbar containing toolbar buttons.
+ * <p>
+ * Subclasses must either override {@link IInformationControl#setInformation(String)}
+ * or implement {@link IInformationControlExtension2}.
+ * They should also extend {@link #computeTrim()} if they create a content area
+ * with additional trim (e.g. scrollbars) and override {@link #getInformationPresenterControlCreator()}.
+ * </p>
+ *
+ * @since 3.4
+ */
+public abstract class AbstractInformationControl : IInformationControl, IInformationControlExtension, IInformationControlExtension3, IInformationControlExtension4, IInformationControlExtension5 {
+
+    /** The information control's shell. */
+    private const Shell fShell;
+    /** Composite containing the content created by subclasses. */
+    private const Composite fContentComposite;
+    /** Whether the information control is resizable. */
+    private const bool fResizable;
+
+    /** Composite containing the status line content or <code>null</code> if none. */
+    private Composite fStatusComposite;
+    /** Separator between content and status line or <code>null</code> if none. */
+    private Label fSeparator;
+    /** Label in the status line or <code>null</code> if none. */
+    private Label fStatusLabel;
+    /** The toolbar manager used by the toolbar or <code>null</code> if none. */
+    private const ToolBarManager fToolBarManager;
+    /** Status line toolbar or <code>null</code> if none. */
+    private ToolBar fToolBar;
+
+    /** Listener for shell activation and deactivation. */
+    private Listener fShellListener;
+    /** All focus listeners registered to this information control. */
+    private ListenerList fFocusListeners;
+
+    /** Size constraints, x is the maxWidth and y is the maxHeight, or <code>null</code> if not set. */
+    private Point fSizeConstraints;
+    /** The size of the resize handle if already set, -1 otherwise */
+    private int fResizeHandleSize;
+
+    /**
+     * Creates an abstract information control with the given shell as parent.
+     * The control will not be resizable and optionally show a status line with
+     * the given status field text.
+     * <p>
+     * <em>Important: Subclasses are required to call {@link #create()} at the end of their constructor.</em>
+     * </p>
+     *
+     * @param parentShell the parent of this control's shell
+     * @param statusFieldText the text to be used in the status field or <code>null</code> to hide the status field
+     */
+    public this(Shell parentShell, String statusFieldText) {
+        this(parentShell, DWT.TOOL | DWT.ON_TOP, statusFieldText, null);
+    }
+
+    /**
+     * Creates an abstract information control with the given shell as parent.
+     * The control will be resizable and optionally show a tool bar managed by
+     * the given tool bar manager.
+     * <p>
+     * <em>Important: Subclasses are required to call {@link #create()} at the end of their constructor.</em>
+     * </p>
+     *
+     * @param parentShell the parent of this control's shell
+     * @param toolBarManager the manager or <code>null</code> if toolbar is not desired
+     */
+    public this(Shell parentShell, ToolBarManager toolBarManager) {
+        this(parentShell, DWT.TOOL | DWT.ON_TOP | DWT.RESIZE, null, toolBarManager);
+    }
+
+    /**
+     * Creates an abstract information control with the given shell as parent.
+     * <p>
+     * <em>Important: Subclasses are required to call {@link #create()} at the end of their constructor.</em>
+     * </p>
+     *
+     * @param parentShell the parent of this control's shell
+     * @param isResizable <code>true</code> if the control should be resizable
+     */
+    public this(Shell parentShell, bool isResizable) {
+        this(parentShell, DWT.TOOL | DWT.ON_TOP | (isResizable ? DWT.RESIZE : 0), null, null);
+    }
+
+    /**
+     * Creates an abstract information control with the given shell as parent.
+     * The given shell style is used for the shell (NO_TRIM will be removed to make sure there's a border).
+     * <p>
+     * The control will optionally show either a status line or a tool bar.
+     * At most one of <code>toolBarManager</code> or <code>statusFieldText</code> can be non-null.
+     * </p>
+     * <p>
+     * <strong>Important:</strong>: Subclasses are required to call {@link #create()} at the end of their constructor.
+     * </p>
+     *
+     * @param parentShell the parent of this control's shell
+     * @param shellStyle style of this control's shell
+     * @param statusFieldText the text to be used in the status field or <code>null</code> to hide the status field
+     * @param toolBarManager the manager or <code>null</code> if toolbar is not desired
+     *
+     * @deprecated clients should use one of the public constructors
+     */
+    this(Shell parentShell, int shellStyle, String statusFieldText, ToolBarManager toolBarManager) {
+
+        fFocusListeners= new ListenerList(ListenerList.IDENTITY);
+
+        Assert.isTrue(statusFieldText is null || toolBarManager is null);
+        fResizeHandleSize= -1;
+        fToolBarManager= toolBarManager;
+
+        if ((shellStyle & DWT.NO_TRIM) !is 0)
+            shellStyle&= ~(DWT.NO_TRIM | DWT.SHELL_TRIM); // make sure we get the OS border but no other trims
+
+        fResizable= (shellStyle & DWT.RESIZE) !is 0; // on GTK, Shell removes DWT.RESIZE if DWT.ON_TOP is set
+        fShell= new Shell(parentShell, shellStyle);
+        Display display= fShell.getDisplay();
+        Color foreground= display.getSystemColor(DWT.COLOR_INFO_FOREGROUND);
+        Color background= display.getSystemColor(DWT.COLOR_INFO_BACKGROUND);
+        setColor(fShell, foreground, background);
+
+        GridLayout layout= new GridLayout(1, false);
+        layout.marginHeight= 0;
+        layout.marginWidth= 0;
+        layout.verticalSpacing= 0;
+        fShell.setLayout(layout);
+
+        fContentComposite= new Composite(fShell, DWT.NONE);
+        fContentComposite.setLayoutData(new GridData(DWT.FILL, DWT.FILL, true, true));
+        fContentComposite.setLayout(new FillLayout());
+        setColor(fContentComposite, foreground, background);
+
+        createStatusComposite(statusFieldText, toolBarManager, foreground, background);
+    }
+
+    private void createStatusComposite(String statusFieldText, ToolBarManager toolBarManager, Color foreground, Color background) {
+        if (toolBarManager is null && statusFieldText is null)
+            return;
+
+        fStatusComposite= new Composite(fShell, DWT.NONE);
+        GridData gridData= new GridData(DWT.FILL, DWT.BOTTOM, true, false);
+        fStatusComposite.setLayoutData(gridData);
+        GridLayout statusLayout= new GridLayout(1, false);
+        statusLayout.marginHeight= 0;
+        statusLayout.marginWidth= 0;
+        statusLayout.verticalSpacing= 1;
+        fStatusComposite.setLayout(statusLayout);
+
+        fSeparator= new Label(fStatusComposite, DWT.SEPARATOR | DWT.HORIZONTAL);
+        fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+        if (statusFieldText !is null) {
+            createStatusLabel(statusFieldText, foreground, background);
+        } else {
+            createToolBar(toolBarManager);
+        }
+    }
+
+    private void createStatusLabel(String statusFieldText, Color foreground, Color background) {
+        fStatusLabel= new Label(fStatusComposite, DWT.RIGHT);
+        fStatusLabel.setLayoutData(new GridData(DWT.FILL, DWT.CENTER, true, false));
+        fStatusLabel.setText(statusFieldText);
+
+        FontData[] fontDatas= JFaceResources.getDialogFont().getFontData();
+        for (int i= 0; i < fontDatas.length; i++) {
+            fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10);
+        }
+        fStatusLabel.setFont(new Font(fStatusLabel.getDisplay(), fontDatas));
+
+        fStatusLabel.setForeground(fStatusLabel.getDisplay().getSystemColor(DWT.COLOR_WIDGET_DARK_SHADOW));
+        fStatusLabel.setBackground(background);
+        setColor(fStatusComposite, foreground, background);
+    }
+
+    private void createToolBar(ToolBarManager toolBarManager) {
+        Composite bars= new Composite(fStatusComposite, DWT.NONE);
+        bars.setLayoutData(new GridData(DWT.FILL, DWT.FILL, false, false));
+
+        GridLayout layout= new GridLayout(3, false);
+        layout.marginHeight= 0;
+        layout.marginWidth= 0;
+        layout.horizontalSpacing= 0;
+        layout.verticalSpacing= 0;
+        bars.setLayout(layout);
+
+        fToolBar= toolBarManager.createControl(bars);
+        GridData gd= new GridData(DWT.BEGINNING, DWT.BEGINNING, false, false);
+        fToolBar.setLayoutData(gd);
+
+        Composite spacer= new Composite(bars, DWT.NONE);
+        gd= new GridData(DWT.FILL, DWT.FILL, true, true);
+        gd.widthHint= 0;
+        gd.heightHint= 0;
+        spacer.setLayoutData(gd);
+
+        addMoveSupport(spacer);
+        addResizeSupportIfNecessary(bars);
+    }
+
+    private void addResizeSupportIfNecessary(Composite bars) {
+        // XXX: workarounds for
+        // - https://bugs.eclipse.org/bugs/show_bug.cgi?id=219139 : API to add resize grip / grow box in lower right corner of shell
+        // - https://bugs.eclipse.org/bugs/show_bug.cgi?id=23980 : platform specific shell resize behavior
+        String platform= DWT.getPlatform();
+        bool isWin= platform.equals("win32"); //$NON-NLS-1$
+        if (!isWin && !platform.equals("gtk")) //$NON-NLS-1$
+            return;
+
+        Canvas resizer= new Canvas(bars, DWT.NONE);
+
+        int size= getResizeHandleSize(bars);
+
+        GridData data= new GridData(DWT.END, DWT.END, false, true);
+        data.widthHint= size;
+        data.heightHint= size;
+        resizer.setLayoutData(data);
+        resizer.addPaintListener(new class(isWin,resizer)  PaintListener {
+            bool isWin_;
+            Canvas resizer_;
+            this(bool a, Canvas b ){
+                isWin_=a;
+                resizer_=b;
+            }
+            public void paintControl(PaintEvent e) {
+                Point s= resizer_.getSize();
+                int x= s.x - 2;
+                int y= s.y - 2;
+                int min= Math.min(x, y);
+                if (isWin_) {
+                    // draw dots
+                    e.gc.setBackground(resizer_.getDisplay().getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
+                    int end= min - 1;
+                    for (int i= 0; i <= 2; i++)
+                        for (int j= 0; j <= 2 - i; j++)
+                            e.gc.fillRectangle(end - 4 * i, end - 4 * j, 2, 2);
+                    end--;
+                    e.gc.setBackground(resizer_.getDisplay().getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW));
+                    for (int i= 0; i <= 2; i++)
+                        for (int j= 0; j <= 2 - i; j++)
+                            e.gc.fillRectangle(end - 4 * i, end - 4 * j, 2, 2);
+
+                } else {
+                    // draw diagonal lines
+                    e.gc.setForeground(resizer_.getDisplay().getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW));
+                    for (int i= 1; i < min; i+= 4) {
+                        e.gc.drawLine(i, y, x, i);
+                    }
+                    e.gc.setForeground(resizer_.getDisplay().getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
+                    for (int i= 2; i < min; i+= 4) {
+                        e.gc.drawLine(i, y, x, i);
+                    }
+                }
+            }
+        });
+
+        resizer.setCursor(new Cursor(resizer.getDisplay(), DWT.CURSOR_SIZESE));
+        MouseAdapter resizeSupport= new class(resizer)  MouseAdapter {
+            Canvas resizer_;
+            this(Canvas a){
+                resizer_=a;
+            }
+            private MouseMoveListener fResizeListener;
+
+            public void mouseDown(MouseEvent e) {
+                Point shellSize= fShell.getSize();
+                int shellX= shellSize.x;
+                int shellY= shellSize.y;
+                Point mouseLoc= resizer_.toDisplay(e.x, e.y);
+                int mouseX= mouseLoc.x;
+                int mouseY= mouseLoc.y;
+                fResizeListener= new class(shellX,shellY,mouseX,mouseY)  MouseMoveListener {
+                    int shellX_;
+                    int shellY_;
+                    int mouseX_;
+                    int mouseY_;
+                    this(int a, int b, int c, int d ){
+                        shellX_=a;
+                        shellY_=b;
+                        mouseX_=c;
+                        mouseY_=d;
+                    }
+                    public void mouseMove(MouseEvent e2) {
+                        Point mouseLoc2= resizer_.toDisplay(e2.x, e2.y);
+                        int dx= mouseLoc2.x - mouseX_;
+                        int dy= mouseLoc2.y - mouseY_;
+                        setSize(shellX_ + dx, shellY_ + dy);
+                    }
+                };
+                resizer_.addMouseMoveListener(fResizeListener);
+            }
+
+            public void mouseUp(MouseEvent e) {
+                resizer_.removeMouseMoveListener(fResizeListener);
+                fResizeListener= null;
+            }
+        };
+        resizer.addMouseListener(resizeSupport);
+    }
+
+    private int getResizeHandleSize(Composite parent) {
+        if (fResizeHandleSize is -1) {
+            Slider sliderV= new Slider(parent, DWT.VERTICAL);
+            Slider sliderH= new Slider(parent, DWT.HORIZONTAL);
+            int width= sliderV.computeSize(DWT.DEFAULT, DWT.DEFAULT).x;
+            int height= sliderH.computeSize(DWT.DEFAULT, DWT.DEFAULT).y;
+            sliderV.dispose();
+            sliderH.dispose();
+            fResizeHandleSize= Math.min(width, height);
+        }
+
+        return fResizeHandleSize;
+    }
+
+    /**
+     * Adds support to move the shell by dragging the given control.
+     *
+     * @param control the control that can be used to move the shell
+     */
+    private void addMoveSupport(Control control) {
+        MouseAdapter moveSupport= new class(control)  MouseAdapter {
+            private MouseMoveListener fMoveListener;
+            Control control_;
+            this(Control a){
+                control_=a;
+            }
+            public void mouseDown(MouseEvent e) {
+                Point shellLoc= fShell.getLocation();
+                final int shellX= shellLoc.x;
+                final int shellY= shellLoc.y;
+                Point mouseLoc= control_.toDisplay(e.x, e.y);
+                final int mouseX= mouseLoc.x;
+                final int mouseY= mouseLoc.y;
+                fMoveListener= new class()  MouseMoveListener {
+                    public void mouseMove(MouseEvent e2) {
+                        Point mouseLoc2= control_.toDisplay(e2.x, e2.y);
+                        int dx= mouseLoc2.x - mouseX;
+                        int dy= mouseLoc2.y - mouseY;
+                        fShell.setLocation(shellX + dx, shellY + dy);
+                    }
+                };
+                control_.addMouseMoveListener(fMoveListener);
+            }
+
+            public void mouseUp(MouseEvent e) {
+                control_.removeMouseMoveListener(fMoveListener);
+                fMoveListener= null;
+            }
+        };
+        control.addMouseListener(moveSupport);
+    }
+
+    /**
+     * Utility to set the foreground and the background color of the given
+     * control
+     *
+     * @param control the control to modify
+     * @param foreground the color to use for the foreground
+     * @param background the color to use for the background
+     */
+    private static void setColor(Control control, Color foreground, Color background) {
+        control.setForeground(foreground);
+        control.setBackground(background);
+    }
+
+    /**
+     * The shell of the popup window.
+     *
+     * @return the shell used for the popup window
+     */
+    protected final Shell getShell() {
+        return fShell;
+    }
+
+    /**
+     * The toolbar manager used to manage the toolbar, or <code>null</code> if
+     * no toolbar is shown.
+     *
+     * @return the tool bar manager or <code>null</code>
+     */
+    protected final ToolBarManager getToolBarManager() {
+        return fToolBarManager;
+    }
+
+    /**
+     * Creates the content of this information control. Subclasses must call
+     * this method at the end of their constructor(s).
+     */
+    protected final void create() {
+        createContent(fContentComposite);
+    }
+
+    /**
+     * Creates the content of the popup window.
+     * <p>
+     * Implementors will usually take over {@link Composite#getBackground()} and
+     * {@link Composite#getForeground()} from <code>parent</code>.
+     * </p>
+     * <p>
+     * Implementors are expected to consider {@link #isResizable()}: If
+     * <code>true</code>, they should show scrollbars if their content may
+     * exceed the size of the information control. If <code>false</code>,
+     * they should never show scrollbars.
+     * </p>
+     * <p>
+     * The given <code>parent</code> comes with a {@link FillLayout}.
+     * Subclasses may set a different layout.
+     * </p>
+     *
+     * @param parent the container of the content
+     */
+    protected abstract void createContent(Composite parent);
+
+    /**
+     * Sets the information to be presented by this information control.
+     * <p>
+     * The default implementation does nothing. Subclasses must either override this method
+     * or implement {@link IInformationControlExtension2}.
+     *
+     * @param information the information to be presented
+     *
+     * @see dwtx.jface.text.IInformationControl#setInformation(java.lang.String)
+     */
+    public void setInformation(String information) {
+
+    }
+
+    /**
+     * Returns whether the information control is resizable.
+     *
+     * @return <code>true</code> if the information control is resizable,
+     *         <code>false</code> if it is not resizable.
+     */
+    public bool isResizable() {
+        return fResizable;
+    }
+
+    /*
+     * @see IInformationControl#setVisible(bool)
+     */
+    public void setVisible(bool visible) {
+        if (fShell.isVisible() is visible)
+            return;
+
+        fShell.setVisible(visible);
+    }
+
+    /*
+     * @see IInformationControl#dispose()
+     */
+    public void dispose() {
+        if (fShell !is null && !fShell.isDisposed())
+            fShell.dispose();
+    }
+
+    /*
+     * @see IInformationControl#setSize(int, int)
+     */
+    public void setSize(int width, int height) {
+        fShell.setSize(width, height);
+    }
+
+    /*
+     * @see IInformationControl#setLocation(Point)
+     */
+    public void setLocation(Point location) {
+        fShell.setLocation(location);
+    }
+
+    /*
+     * @see IInformationControl#setSizeConstraints(int, int)
+     */
+    public void setSizeConstraints(int maxWidth, int maxHeight) {
+        fSizeConstraints= new Point(maxWidth, maxHeight);
+    }
+
+    /**
+     * Returns the size constraints.
+     *
+     * @return the size constraints or <code>null</code> if not set
+     * @see #setSizeConstraints(int, int)
+     */
+    protected final Point getSizeConstraints() {
+        return fSizeConstraints !is null ? Geometry.copy(fSizeConstraints) : null;
+    }
+
+    /*
+     * @see IInformationControl#computeSizeHint()
+     */
+    public Point computeSizeHint() {
+        // XXX: Verify whether this is a good default implementation. If yes, document it.
+        Point constrains= getSizeConstraints();
+        if (constrains is null)
+            return fShell.computeSize(DWT.DEFAULT, DWT.DEFAULT, true);
+
+        return fShell.computeSize(constrains.x, constrains.y, true);
+    }
+
+    /**
+     * Computes the trim (status text and tool bar are considered as trim).
+     * Subclasses can extend this method to add additional trim (e.g. scroll
+     * bars for resizable information controls).
+     *
+     * @see dwtx.jface.text.IInformationControlExtension3#computeTrim()
+     */
+    public Rectangle computeTrim() {
+        Rectangle trim= fShell.computeTrim(0, 0, 0, 0);
+
+        if (fStatusComposite !is null)
+            trim.height+= fStatusComposite.computeSize(DWT.DEFAULT, DWT.DEFAULT).y;
+
+        return trim;
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension3#getBounds()
+     */
+    public Rectangle getBounds() {
+        return fShell.getBounds();
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The default implementation always returns <code>false</code>.
+     * </p>
+     * @see dwtx.jface.text.IInformationControlExtension3#restoresLocation()
+     */
+    public bool restoresLocation() {
+        return false;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * The default implementation always returns <code>false</code>.
+     * </p>
+     * @see dwtx.jface.text.IInformationControlExtension3#restoresSize()
+     */
+    public bool restoresSize() {
+        return false;
+    }
+
+    /*
+     * @see IInformationControl#addDisposeListener(DisposeListener)
+     */
+    public void addDisposeListener(DisposeListener listener) {
+        fShell.addDisposeListener(listener);
+    }
+
+    /*
+     * @see IInformationControl#removeDisposeListener(DisposeListener)
+     */
+    public void removeDisposeListener(DisposeListener listener) {
+        fShell.removeDisposeListener(listener);
+    }
+
+    /*
+     * @see IInformationControl#setForegroundColor(Color)
+     */
+    public void setForegroundColor(Color foreground) {
+        fContentComposite.setForeground(foreground);
+    }
+
+    /*
+     * @see IInformationControl#setBackgroundColor(Color)
+     */
+    public void setBackgroundColor(Color background) {
+        fContentComposite.setBackground(background);
+    }
+
+    /**
+     * {@inheritDoc}
+     * This method is not intended to be overridden by subclasses.
+     */
+    public bool isFocusControl() {
+        return fShell.getDisplay().getActiveShell() is fShell;
+    }
+
+    /**
+     * This default implementation sets the focus on the popup shell.
+     * Subclasses can override or extend.
+     *
+     * @see IInformationControl#setFocus()
+     */
+    public void setFocus() {
+        bool focusTaken= fShell.setFocus();
+        if (!focusTaken)
+            fShell.forceFocus();
+    }
+
+    /**
+     * {@inheritDoc}
+     * This method is not intended to be overridden by subclasses.
+     */
+    public void addFocusListener(FocusListener listener) {
+        if (fFocusListeners.isEmpty()) {
+            fShellListener= new class()  Listener {
+
+                public void handleEvent(Event event) {
+                    Object[] listeners= fFocusListeners.getListeners();
+                    for (int i= 0; i < listeners.length; i++) {
+                        FocusListener focusListener= cast(FocusListener)listeners[i];
+                        if (event.type is DWT.Activate) {
+                            focusListener.focusGained(new FocusEvent(event));
+                        } else {
+                            focusListener.focusLost(new FocusEvent(event));
+                        }
+                    }
+                }
+            };
+            fShell.addListener(DWT.Deactivate, fShellListener);
+            fShell.addListener(DWT.Activate, fShellListener);
+        }
+        fFocusListeners.add(cast(Object)listener);
+    }
+
+    /**
+     * {@inheritDoc}
+     * This method is not intended to be overridden by subclasses.
+     */
+    public void removeFocusListener(FocusListener listener) {
+        fFocusListeners.remove(cast(Object)listener);
+        if (fFocusListeners.isEmpty()) {
+            fShell.removeListener(DWT.Activate, fShellListener);
+            fShell.removeListener(DWT.Deactivate, fShellListener);
+            fShellListener= null;
+        }
+    }
+
+    /**
+     * Sets the text of the status field.
+     * <p>
+     * The default implementation currently only updates the status field when
+     * the popup shell is not visible. The status field can currently only be
+     * shown if the information control has been created with a non-null status
+     * field text.
+     * </p>
+     *
+     * @param statusFieldText the text to be used in the optional status field
+     *        or <code>null</code> if the status field should be hidden
+     *
+     * @see dwtx.jface.text.IInformationControlExtension4#setStatusText(java.lang.String)
+     */
+    public void setStatusText(String statusFieldText) {
+        if (fStatusLabel !is null && ! getShell().isVisible()) {
+            if (statusFieldText is null ) {
+                fStatusComposite.setVisible(false);
+            } else {
+                fStatusLabel.setText(statusFieldText);
+                fStatusComposite.setVisible(true);
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension5#containsControl(dwt.widgets.Control)
+     */
+    public bool containsControl(Control control) {
+        do {
+            if (control is fShell)
+                return true;
+            if (cast(Shell)control )
+                return false;
+            control= control.getParent();
+        } while (control !is null);
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension5#isVisible()
+     */
+    public bool isVisible() {
+        return fShell !is null && !fShell.isDisposed() && fShell.isVisible();
+    }
+
+    /**
+     * {@inheritDoc}
+     * This default implementation returns <code>null</code>. Subclasses may override.
+     */
+    public IInformationControlCreator getInformationPresenterControlCreator() {
+        return null;
+    }
+
+    /**
+     * Computes the size constraints based on the
+     * {@link JFaceResources#getDialogFont() dialog font}. Subclasses can
+     * override or extend.
+     *
+     * @see dwtx.jface.text.IInformationControlExtension5#computeSizeConstraints(int, int)
+     */
+    public Point computeSizeConstraints(int widthInChars, int heightInChars) {
+        GC gc= new GC(fContentComposite);
+        gc.setFont(JFaceResources.getDialogFont());
+        int width= gc.getFontMetrics().getAverageCharWidth();
+        int height= gc.getFontMetrics().getHeight();
+        gc.dispose();
+
+        return new Point(widthInChars * width, heightInChars * height);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/AbstractInformationControlManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1601 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Sean Montgomery, sean_montgomery@comcast.net - https://bugs.eclipse.org/bugs/show_bug.cgi?id=45095
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.AbstractInformationControlManager;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+// import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+
+
+
+import dwt.DWT;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.graphics.GC;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Monitor;
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.Platform;
+import dwtx.jface.dialogs.IDialogSettings;
+import dwtx.jface.internal.text.InformationControlReplacer;
+import dwtx.jface.internal.text.InternalAccessor;
+import dwtx.jface.text.ITextViewerExtension8;
+import dwtx.jface.util.Geometry;
+
+
+/**
+ * Manages the life cycle, visibility, layout, and contents of an
+ * {@link dwtx.jface.text.IInformationControl}. This manager can be
+ * installed on and removed from a control, referred to as the subject control,
+ * i.e. the one from which the subject of the information to be shown is
+ * retrieved. Also a manager can be enabled or disabled. An installed and
+ * enabled manager can be forced to show information in its information control
+ * using <code>showInformation</code>. An information control manager uses an
+ * <code>IInformationControlCloser</code> to define the behavior when a
+ * presented information control must be closed. The disposal of the subject and
+ * the information control are internally handled by the information control
+ * manager and are not the responsibility of the information control closer.
+ *
+ * @see dwtx.jface.text.IInformationControl
+ * @since 2.0
+ */
+abstract public class AbstractInformationControlManager {
+
+    /**
+     * An internal class that gives access to internal methods.
+     *
+     * @since 3.4
+     */
+    public static class MyInternalAccessor : InternalAccessor {
+        AbstractInformationControlManager outer_;
+        this( AbstractInformationControlManager a ){
+            outer_=a;
+        }
+        public IInformationControl getCurrentInformationControl() {
+            return outer_.getCurrentInformationControl();
+        }
+
+        public void setInformationControlReplacer(InformationControlReplacer replacer) {
+            outer_.setInformationControlReplacer(replacer);
+        }
+
+        public InformationControlReplacer getInformationControlReplacer() {
+            return outer_.getInformationControlReplacer();
+        }
+
+        public bool canReplace(IInformationControl control) {
+            return outer_.canReplace(control);
+        }
+
+        public bool isReplaceInProgress() {
+            return outer_.isReplaceInProgress();
+        }
+
+        public void replaceInformationControl(bool takeFocus) {
+            outer_.replaceInformationControl(takeFocus);
+        }
+
+        public void cropToClosestMonitor(Rectangle bounds) {
+            outer_.cropToClosestMonitor(bounds);
+        }
+
+        public void setHoverEnrichMode(EnrichMode mode) {
+            throw new UnsupportedOperationException("only implemented in AbstractHoverInformationControlManager"); //$NON-NLS-1$
+        }
+
+        public bool getAllowMouseExit() {
+            throw new UnsupportedOperationException("only implemented in AnnotationBarHoverManager"); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Interface of an information control closer. An information control closer
+     * monitors its information control and its subject control and closes the
+     * information control if necessary.
+     * <p>
+     * Clients must implement this interface in order to equip an information
+     * control manager accordingly.
+     */
+    public interface IInformationControlCloser {
+
+        /**
+         * Sets the closer's subject control. This is the control that parents
+         * the information control and from which the subject of the information
+         * to be shown is retrieved. <p>
+         * Must be called before <code>start</code>. May again be called
+         * between <code>start</code> and <code>stop</code>.
+         *
+         * @param subject the subject control
+         */
+        public void setSubjectControl(Control subject);
+
+        /**
+         * Sets the closer's information control, the one to close if necessary. <p>
+         * Must be called before <code>start</code>. May again be called
+         * between <code>start</code> and <code>stop</code>.
+         *
+         * @param control the information control
+         */
+        public void setInformationControl(IInformationControl control);
+
+        /**
+         * Tells this closer to start monitoring the subject and the information
+         * control. The presented information is considered valid for the given
+         * area of the subject control's display.
+         *
+         * @param subjectArea the area for which the presented information is valid
+         */
+        public void start(Rectangle subjectArea);
+
+        /**
+         * Tells this closer to stop monitoring the subject and the information control.
+         */
+        public void stop();
+    }
+
+
+
+    /**
+     * Constitutes entities to enumerate anchors for the layout of the information control.
+     */
+    public static final class Anchor {
+        private const int fFlag;
+        private this(int flag) {
+            fFlag= flag;
+        }
+        /**
+         * Returns the DWT direction flag. One of {@link DWT#BOTTOM}, {@link DWT#TOP},
+         * {@link DWT#LEFT}, {@link DWT#RIGHT}, {@link DWT#CENTER},
+         *
+         * @return the DWT direction flag
+         * @since 3.3
+         */
+        int getSWTFlag() {
+            return fFlag;
+        }
+
+        public override String toString() {
+            switch (fFlag) {
+                case DWT.BOTTOM: return "BOTTOM"; //$NON-NLS-1$
+                case DWT.TOP: return "TOP"; //$NON-NLS-1$
+                case DWT.LEFT: return "LEFT"; //$NON-NLS-1$
+                case DWT.RIGHT: return "RIGHT"; //$NON-NLS-1$
+                case DWT.CENTER: return "CENTER"; //$NON-NLS-1$
+                default: return Integer.toHexString(fFlag);
+            }
+        }
+    }
+
+    /** Internal anchor list. */
+    private static Anchor[] ANCHORS_;
+    private static Anchor[] ANCHORS() {
+        if( ANCHORS_ is null ) ANCHORS_= [ new Anchor(DWT.TOP), new Anchor(DWT.BOTTOM), new Anchor(DWT.LEFT), new Anchor(DWT.RIGHT) ];
+        return ANCHORS_;
+    }
+
+
+    /** Anchor representing the top of the information area */
+    public static Anchor ANCHOR_TOP() { return ANCHORS()[0]; }
+    /** Anchor representing the bottom of the information area */
+    public static Anchor ANCHOR_BOTTOM() { return ANCHORS()[1]; }
+    /** Anchor representing the left side of the information area */
+    public static Anchor ANCHOR_LEFT() { return ANCHORS()[2]; }
+    /** Anchor representing the right side of the information area */
+    public static Anchor ANCHOR_RIGHT() { return ANCHORS()[3]; }
+    /**
+     * Anchor representing the middle of the subject control
+     * @since 2.1
+     */
+    public static Anchor ANCHOR_GLOBAL_;
+    public static Anchor ANCHOR_GLOBAL(){
+        if( ANCHOR_GLOBAL_ is null ) ANCHOR_GLOBAL_ = new Anchor(DWT.CENTER);
+        return ANCHOR_GLOBAL_;
+    }
+
+    /**
+     * Dialog store constant for the location's x-coordinate.
+     * @since 3.0
+     */
+    public static const String STORE_LOCATION_X= "location.x"; //$NON-NLS-1$
+    /**
+     * Dialog store constant for the location's y-coordinate.
+     * @since 3.0
+     */
+    public static const String STORE_LOCATION_Y= "location.y"; //$NON-NLS-1$
+    /**
+     * Dialog store constant for the size's width.
+     * @since 3.0
+     */
+    public static const String STORE_SIZE_WIDTH= "size.width"; //$NON-NLS-1$
+    /**
+     * Dialog store constant for the size's height.
+     * @since 3.0
+     */
+    public static const String STORE_SIZE_HEIGHT= "size.height"; //$NON-NLS-1$
+
+    /**
+     * Tells whether this class and its subclasses are in debug mode.
+     * <p>
+     * Subclasses may use this.
+     * </p>
+     * @since 3.4
+     */
+    private static bool DEBUG_;
+    private static bool DEBUG_init = false;
+    protected static bool DEBUG(){
+        if( !DEBUG_init ){
+            DEBUG_init = true;
+            DEBUG_ = "true".equalsIgnoreCase(Platform.getDebugOption("dwtx.jface.text/debug/AbstractInformationControlManager"));  //$NON-NLS-1$//$NON-NLS-2$
+        }
+        return DEBUG_;
+    }
+
+
+    /** The subject control of the information control */
+    private Control  fSubjectControl;
+
+    /** The display area for which the information to be presented is valid */
+    private Rectangle fSubjectArea;
+
+    /** The information to be presented */
+    private Object fInformation;
+
+    /** Indicates whether the information control takes focus when visible */
+    private bool fTakesFocusWhenVisible= false;
+
+    /**
+     * The information control.
+     *
+     * <p>This field should not be referenced by subclasses. It is <code>protected</code> for API
+     * compatibility reasons.
+     */
+    protected IInformationControl fInformationControl;
+
+    /**
+     * The information control creator.
+     *
+     * <p>This field should not be referenced by subclasses. It is <code>protected</code> for API
+     * compatibility reasons.
+     */
+    protected IInformationControlCreator fInformationControlCreator;
+
+    /**
+     * The information control closer.
+     *
+     * <p>This field should not be referenced by subclasses. It is <code>protected</code> for API
+     * compatibility reasons.
+     */
+    protected IInformationControlCloser fInformationControlCloser;
+
+    /**
+     * Indicates that the information control has been disposed.
+     *
+     * <p>This field should not be referenced by subclasses. It is <code>protected</code> for API
+     * compatibility reasons.
+     */
+    protected bool fDisposed= false;
+
+    /**
+     * The information control replacer to be used when this information control
+     * needs to be replaced with another information control.
+     *
+     * @since 3.4
+     */
+    private InformationControlReplacer fInformationControlReplacer;
+
+    /** Indicates the enable state of this manager */
+    private bool fEnabled= false;
+
+    /** Cached, computed size constraints of the information control in points */
+    private Point fSizeConstraints;
+
+    /** The vertical margin when laying out the information control */
+    private int fMarginY= 5;
+
+    /** The horizontal margin when laying out the information control */
+    private int fMarginX= 5;
+
+    /** The width constraint of the information control in characters */
+    private int fWidthConstraint= 60;
+
+    /** The height constraint of the information control  in characters */
+    private int fHeightConstraint= 6;
+
+    /** Indicates whether the size constraints should be enforced as minimal control size */
+    private bool fEnforceAsMinimalSize= false;
+
+    /** Indicates whether the size constraints should be enforced as maximal control size */
+    private bool fEnforceAsMaximalSize= false;
+
+    /** The anchor for laying out the information control in relation to the subject control */
+    private Anchor fAnchor;
+
+    /**
+     * The anchor sequence used to layout the information control if the original anchor
+     * can not be used because the information control would not fit in the display client area.
+     * <p>
+     * The fallback anchor for a given anchor is the one that comes directly after the given anchor or
+     * is the first one in the sequence if the given anchor is the last one in the sequence.
+     * <p>
+     * </p>
+     * Note: This sequence is ignored if the original anchor is not contained in this sequence.
+     * </p>
+     *
+     * @see #fAnchor
+     */
+    private Anchor[] fFallbackAnchors;
+    /**
+     * The custom information control creator.
+     * @since 3.0
+     */
+    private /+volatile+/ IInformationControlCreator fCustomInformationControlCreator;
+
+    /**
+     * Tells whether a custom information control is in use.
+     * @since 3.0
+     */
+    private bool fIsCustomInformationControl= false;
+
+    /**
+     * The dialog settings for the control's bounds.
+     * @since 3.0
+     */
+    private IDialogSettings fDialogSettings;
+
+    /**
+     * Tells whether the control's location should be read
+     * from the dialog settings and whether the last
+     * valid control's size is stored back into the  settings.
+     *
+     * @since 3.0
+     */
+    private bool fIsRestoringLocation;
+
+    /**
+     * Tells whether the control's size should be read
+     * from the dialog settings and whether the last
+     * valid control's size is stored back into the  settings.
+     *
+     * @since 3.0
+     */
+    private bool fIsRestoringSize;
+
+    /**
+     * The dispose listener on the subject control.
+     *
+     * @since 3.1
+     */
+    private DisposeListener fSubjectControlDisposeListener;
+
+
+    /**
+     * Creates a new information control manager using the given information control creator.
+     * By default the following configuration is given:
+     * <ul>
+     * <li> enabled is false
+     * <li> horizontal margin is 5 points
+     * <li> vertical margin is 5 points
+     * <li> width constraint is 60 characters
+     * <li> height constraint is 6 characters
+     * <li> enforce constraints as minimal size is false
+     * <li> enforce constraints as maximal size is false
+     * <li> layout anchor is ANCHOR_BOTTOM
+     * <li> fall back anchors is { ANCHOR_TOP, ANCHOR_BOTTOM, ANCHOR_LEFT, ANCHOR_RIGHT, ANCHOR_GLOBAL }
+     * <li> takes focus when visible is false
+     * </ul>
+     *
+     * @param creator the information control creator
+     */
+    protected this(IInformationControlCreator creator) {
+        fAnchor= ANCHOR_BOTTOM();
+        fFallbackAnchors= ANCHORS();
+        Assert.isNotNull(cast(Object)creator);
+        fInformationControlCreator= creator;
+    }
+
+    /**
+     * Computes the information to be displayed and the area in which the computed
+     * information is valid. Implementation of this method must finish their computation
+     * by setting the computation results using <code>setInformation</code>.
+     */
+    abstract protected void computeInformation();
+
+    /**
+     * Sets the parameters of the information to be displayed. These are the information itself and
+     * the area for which the given information is valid. This so called subject area is a graphical
+     * region of the information control's subject control. This method calls <code>presentInformation()</code>
+     * to trigger the presentation of the computed information.
+     *
+     * @param information the information, or <code>null</code> if none is available
+     * @param subjectArea the subject area, or <code>null</code> if none is available
+     */
+    protected final void setInformation(String information, Rectangle subjectArea) {
+        setInformation(stringcast(information), subjectArea);
+    }
+
+    /**
+     * Sets the parameters of the information to be displayed. These are the information itself and
+     * the area for which the given information is valid. This so called subject area is a graphical
+     * region of the information control's subject control. This method calls <code>presentInformation()</code>
+     * to trigger the presentation of the computed information.
+     *
+     * @param information the information, or <code>null</code> if none is available
+     * @param subjectArea the subject area, or <code>null</code> if none is available
+     * @since  2.1
+     */
+    protected final void setInformation(Object information, Rectangle subjectArea) {
+        fInformation= information;
+        fSubjectArea= subjectArea;
+        presentInformation();
+    }
+
+    /**
+     * Sets the information control closer for this manager.
+     *
+     * @param closer the information control closer for this manager
+     */
+    protected void setCloser(IInformationControlCloser closer) {
+        fInformationControlCloser= closer;
+    }
+
+    /**
+     * Sets the information control replacer for this manager and disposes the
+     * old one if set.
+     *
+     * @param replacer the information control replacer for this manager, or
+     *            <code>null</code> if no information control replacing should
+     *            take place
+     * @since 3.4
+     */
+    void setInformationControlReplacer(InformationControlReplacer replacer) {
+        if (fInformationControlReplacer !is null)
+            fInformationControlReplacer.dispose();
+        fInformationControlReplacer= replacer;
+    }
+
+    /**
+     * Returns the current information control replacer or <code>null</code> if none has been installed.
+     *
+     * @return the current information control replacer or <code>null</code> if none has been installed
+     * @since 3.4
+     */
+    InformationControlReplacer getInformationControlReplacer() {
+        return fInformationControlReplacer;
+    }
+
+    /**
+     * Returns whether an information control replacer has been installed.
+     *
+     * @return whether an information control replacer has been installed
+     * @since 3.4
+     */
+    bool hasInformationControlReplacer() {
+        return fInformationControlReplacer !is null;
+    }
+
+    /**
+     * Tests whether the given information control is replaceable.
+     *
+     * @param iControl information control or <code>null</code> if none
+     * @return <code>true</code> if information control is replaceable, <code>false</code> otherwise
+     * @since 3.4
+     */
+    bool canReplace(IInformationControl iControl) {
+        return cast(IInformationControlExtension3)iControl
+                && cast(IInformationControlExtension5)iControl
+                && (cast(IInformationControlExtension5) iControl).getInformationPresenterControlCreator() !is null;
+    }
+
+    /**
+     * Returns the current information control, or <code>null</code> if none.
+     *
+     * @return the current information control, or <code>null</code> if none
+     * @since 3.4
+     */
+    IInformationControl getCurrentInformationControl() {
+        return fInformationControl;
+    }
+
+    /**
+     * Tells whether this manager's information control is currently being replaced.
+     *
+     * @return <code>true</code> if a replace is in progress
+     * @since 3.4
+     */
+    bool isReplaceInProgress() {
+        return fInformationControlReplacer !is null && fInformationControlReplacer.isReplacing();
+    }
+
+    /**
+     * Sets the horizontal and vertical margin to be used when laying out the
+     * information control relative to the subject control.
+     *
+     * @param xMargin the x-margin
+     * @param yMargin the y-Margin
+     */
+    public void setMargins(int xMargin, int yMargin) {
+        fMarginX= xMargin;
+        fMarginY= yMargin;
+    }
+
+    /**
+     * Sets the width- and height constraints of the information control.
+     *
+     * @param widthInChar the width constraint in number of characters
+     * @param heightInChar the height constrain in number of characters
+     * @param enforceAsMinimalSize indicates whether the constraints describe the minimal allowed size of the control
+     * @param enforceAsMaximalSize indicates whether the constraints describe the maximal allowed size of the control
+     */
+    public void setSizeConstraints(int widthInChar, int heightInChar, bool enforceAsMinimalSize, bool enforceAsMaximalSize) {
+        fSizeConstraints= null;
+        fWidthConstraint= widthInChar;
+        fHeightConstraint= heightInChar;
+        fEnforceAsMinimalSize= enforceAsMinimalSize;
+        fEnforceAsMaximalSize= enforceAsMaximalSize;
+
+    }
+
+    /**
+     * Tells this information control manager to open the information
+     * control with the values contained in the given dialog settings
+     * and to store the control's last valid size in the given dialog
+     * settings.
+     * <p>
+     * Note: This API is only valid if the information control implements
+     * {@link IInformationControlExtension3}. Not following this restriction
+     * will later result in an {@link UnsupportedOperationException}.
+     * </p>
+     * <p>
+     * The constants used to store the values are:
+     * <ul>
+     *  <li>{@link AbstractInformationControlManager#STORE_LOCATION_X}</li>
+     *  <li>{@link AbstractInformationControlManager#STORE_LOCATION_Y}</li>
+     *  <li>{@link AbstractInformationControlManager#STORE_SIZE_WIDTH}</li>
+     *  <li>{@link AbstractInformationControlManager#STORE_SIZE_HEIGHT}</li>
+     * </ul>
+     * </p>
+     *
+     * @param dialogSettings
+     * @param restoreLocation <code>true</code> iff the location is must be (re-)stored
+     * @param restoreSize <code>true</code>iff the size is (re-)stored
+     * @since 3.0
+     */
+    public void setRestoreInformationControlBounds(IDialogSettings dialogSettings, bool restoreLocation, bool restoreSize) {
+        Assert.isTrue(dialogSettings !is null && (restoreLocation || restoreSize));
+        fDialogSettings= dialogSettings;
+        fIsRestoringLocation= restoreLocation;
+        fIsRestoringSize= restoreSize;
+    }
+
+    /**
+     * Sets the anchor used for laying out the information control relative to the
+     * subject control. E.g, using <code>ANCHOR_TOP</code> indicates that the
+     * information control is position above the area for which the information to
+     * be displayed is valid.
+     *
+     * @param anchor the layout anchor
+     */
+    public void setAnchor(Anchor anchor) {
+        fAnchor= anchor;
+    }
+
+    /**
+     * Sets the anchors fallback sequence used to layout the information control if the original
+     * anchor can not be used because the information control would not fit in the display client
+     * area.
+     * <p>
+     * The fallback anchor for a given anchor is the one that comes directly after the given anchor or
+     * is the first one in the sequence if the given anchor is the last one in the sequence.
+     * <p>
+     * </p>
+     * Note: This sequence is ignored if the original anchor is not contained in this list.
+     * </p>
+     *
+     * @param fallbackAnchors the array with the anchor fallback sequence
+     * @see #setAnchor(AbstractInformationControlManager.Anchor)
+     */
+    public void setFallbackAnchors(Anchor[] fallbackAnchors) {
+        if (fallbackAnchors !is null) {
+            fFallbackAnchors= new Anchor[fallbackAnchors.length];
+            System.arraycopy(fallbackAnchors, 0, fFallbackAnchors, 0, fallbackAnchors.length);
+        } else
+            fFallbackAnchors= null;
+    }
+
+    /**
+     * Sets the temporary custom control creator, overriding this manager's default information control creator.
+     *
+     * @param informationControlCreator the creator, possibly <code>null</code>
+     * @since 3.0
+     */
+    protected void setCustomInformationControlCreator(IInformationControlCreator informationControlCreator)  {
+        if (informationControlCreator !is null && cast(IInformationControlCreatorExtension)fCustomInformationControlCreator) {
+            IInformationControlCreatorExtension extension= cast(IInformationControlCreatorExtension) fCustomInformationControlCreator;
+            if (extension.canReplace(informationControlCreator))
+                return;
+        }
+        fCustomInformationControlCreator= informationControlCreator;
+    }
+
+    /**
+     * Tells the manager whether it should set the focus to the information control when made visible.
+     *
+     * @param takesFocus <code>true</code> if information control should take focus when made visible
+     */
+    public void takesFocusWhenVisible(bool takesFocus) {
+        fTakesFocusWhenVisible= takesFocus;
+    }
+
+    /**
+     * Handles the disposal of the subject control. By default, the information control
+     * is disposed by calling <code>disposeInformationControl</code>. Subclasses may extend
+     * this method.
+     */
+    protected void handleSubjectControlDisposed() {
+        disposeInformationControl();
+    }
+
+    /**
+     * Installs this manager on the given control. The control is now taking the role of
+     * the subject control. This implementation sets the control also as the information
+     * control closer's subject control and automatically enables this manager.
+     *
+     * @param subjectControl the subject control
+     */
+    public void install(Control subjectControl) {
+        if (fSubjectControl !is null && !fSubjectControl.isDisposed() && fSubjectControlDisposeListener !is null)
+            fSubjectControl.removeDisposeListener(fSubjectControlDisposeListener);
+
+        fSubjectControl= subjectControl;
+
+        if (fSubjectControl !is null)
+            fSubjectControl.addDisposeListener(getSubjectControlDisposeListener());
+
+        if (fInformationControlCloser !is null)
+            fInformationControlCloser.setSubjectControl(subjectControl);
+
+        setEnabled(true);
+        fDisposed= false;
+    }
+
+    /**
+     * Returns the dispose listener which gets added
+     * to the subject control.
+     *
+     * @return the dispose listener
+     * @since 3.1
+     */
+    private DisposeListener getSubjectControlDisposeListener() {
+        if (fSubjectControlDisposeListener is null) {
+            fSubjectControlDisposeListener= new class()  DisposeListener {
+                public void widgetDisposed(DisposeEvent e) {
+                    handleSubjectControlDisposed();
+                }
+            };
+        }
+        return fSubjectControlDisposeListener;
+    }
+
+    /**
+     * Returns the subject control of this manager/information control.
+     *
+     * @return the subject control
+     */
+    protected Control getSubjectControl() {
+        return fSubjectControl;
+    }
+
+    /**
+     * Returns the actual subject area.
+     *
+     * @return the actual subject area
+     */
+    protected Rectangle getSubjectArea() {
+        return fSubjectArea;
+    }
+
+    /**
+     * Sets the enable state of this manager.
+     *
+     * @param enabled the enable state
+     * @deprecated visibility will be changed to protected
+     */
+    public void setEnabled(bool enabled) {
+        fEnabled= enabled;
+    }
+
+    /**
+     * Returns whether this manager is enabled or not.
+     *
+     * @return <code>true</code> if this manager is enabled otherwise <code>false</code>
+     */
+    protected bool isEnabled() {
+        return fEnabled;
+    }
+
+    /**
+     * Computes the size constraints of the information control in points based on the
+     * default font of the given subject control as well as the size constraints in character
+     * width.
+     *
+     * @param subjectControl the subject control
+     * @param informationControl the information control whose size constraints are computed
+     * @return the computed size constraints in points
+     */
+    protected Point computeSizeConstraints(Control subjectControl, IInformationControl informationControl) {
+
+        if (fSizeConstraints is null) {
+            if ( cast(IInformationControlExtension5)informationControl ) {
+                IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) informationControl;
+                fSizeConstraints= iControl5.computeSizeConstraints(fWidthConstraint, fHeightConstraint);
+                if (fSizeConstraints !is null)
+                    return Geometry.copy(fSizeConstraints);
+            }
+            if (subjectControl is null)
+                return null;
+
+            GC gc= new GC(subjectControl);
+            gc.setFont(subjectControl.getFont());
+            int width= gc.getFontMetrics().getAverageCharWidth();
+            int height = gc.getFontMetrics().getHeight();
+            gc.dispose();
+
+            fSizeConstraints= new Point (fWidthConstraint * width, fHeightConstraint * height);
+        }
+
+        return new Point(fSizeConstraints.x, fSizeConstraints.y);
+    }
+
+    /**
+     * Computes the size constraints of the information control in points.
+     *
+     * @param subjectControl the subject control
+     * @param subjectArea the subject area
+     * @param informationControl the information control whose size constraints are computed
+     * @return the computed size constraints in points
+     * @since 3.0
+     */
+    protected Point computeSizeConstraints(Control subjectControl, Rectangle subjectArea, IInformationControl informationControl) {
+        return computeSizeConstraints(subjectControl, informationControl);
+    }
+
+    /**
+     * Handles the disposal of the information control. By default, the information
+     * control closer is stopped.
+     */
+    protected void handleInformationControlDisposed() {
+
+        storeInformationControlBounds();
+
+        if ( cast(IInformationControlExtension5)fInformationControl )
+            fSizeConstraints= null;
+        fInformationControl= null;
+        if (fInformationControlCloser !is null) {
+            fInformationControlCloser.setInformationControl(null); //XXX: null is against the spec
+            fInformationControlCloser.stop();
+        }
+    }
+
+    /**
+     * Returns the information control. If the information control has not been created yet,
+     * it is automatically created.
+     *
+     * @return the information control
+     */
+    protected IInformationControl getInformationControl() {
+
+        if (fDisposed)
+            return fInformationControl;
+
+        IInformationControlCreator creator= null;
+
+        if (fCustomInformationControlCreator is null) {
+            creator= fInformationControlCreator;
+            if (fIsCustomInformationControl && fInformationControl !is null) {
+                if ( cast(IInformationControlExtension5)fInformationControl )
+                    fSizeConstraints= null;
+                fInformationControl.dispose();
+                fInformationControl= null;
+            }
+            fIsCustomInformationControl= false;
+
+        } else  {
+
+            creator= fCustomInformationControlCreator;
+            if ( cast(IInformationControlCreatorExtension)creator )  {
+                IInformationControlCreatorExtension extension= cast(IInformationControlCreatorExtension) creator;
+                if (fInformationControl !is null && extension.canReuse(fInformationControl))
+                    return fInformationControl;
+            }
+            if (fInformationControl !is null)  {
+                if ( cast(IInformationControlExtension5)fInformationControl )
+                    fSizeConstraints= null;
+                fInformationControl.dispose();
+                fInformationControl= null;
+            }
+            fIsCustomInformationControl= true;
+        }
+
+        if (fInformationControl is null) {
+            fInformationControl= creator.createInformationControl(fSubjectControl.getShell());
+            fInformationControl.addDisposeListener(new class()  DisposeListener {
+                public void widgetDisposed(DisposeEvent e) {
+                    handleInformationControlDisposed();
+                }
+            });
+
+            if (fInformationControlCloser !is null)
+                fInformationControlCloser.setInformationControl(fInformationControl);
+        }
+
+        return fInformationControl;
+    }
+
+    /**
+     * Computes the display location of the information control. The location is computed
+     * considering the given subject area, the anchor at the subject area, and the
+     * size of the information control. This method does not care about whether the information
+     * control would be completely visible when placed at the result location.
+     *
+     * @param subjectArea the subject area
+     * @param controlSize the size of the information control
+     * @param anchor the anchor at the subject area
+     * @return the display location of the information control
+     */
+    protected Point computeLocation(Rectangle subjectArea, Point controlSize, Anchor anchor) {
+        int xShift= 0;
+        int yShift= 0;
+
+        switch (anchor.getSWTFlag()) {
+            case DWT.CENTER:
+                Point subjectControlSize= fSubjectControl.getSize();
+                Point location= new Point(subjectControlSize.x / 2, subjectControlSize.y / 2);
+                location.x -= (controlSize.x / 2);
+                location.y -= (controlSize.y / 2);
+                return fSubjectControl.toDisplay(location);
+            case DWT.BOTTOM:
+                yShift= subjectArea.height + fMarginY;
+                break;
+            case DWT.RIGHT:
+                xShift= fMarginX + subjectArea.width;
+                break;
+            case DWT.TOP:
+                yShift= -controlSize.y - fMarginY;
+                break;
+            case DWT.LEFT:
+                xShift= -controlSize.x - fMarginX;
+                break;
+        }
+
+        bool isRTL= fSubjectControl !is null && (fSubjectControl.getStyle() & DWT.RIGHT_TO_LEFT) !is 0;
+        if (isRTL)
+            xShift += controlSize.x;
+
+        return  fSubjectControl.toDisplay(new Point(subjectArea.x + xShift, subjectArea.y + yShift));
+    }
+
+    /**
+     * Computes the area available for an information control given an anchor and the subject area
+     * within <code>bounds</code>.
+     *
+     * @param subjectArea the subject area
+     * @param bounds the bounds
+     * @param anchor the anchor at the subject area
+     * @return the area available at the given anchor relative to the subject area, confined to the
+     *         monitor's client area
+     * @since 3.3
+     */
+    protected Rectangle computeAvailableArea(Rectangle subjectArea, Rectangle bounds, Anchor anchor) {
+        Rectangle area;
+        switch (anchor.getSWTFlag()) {
+            case DWT.CENTER:
+                area= bounds;
+                break;
+            case DWT.BOTTOM:
+                int y= subjectArea.y + subjectArea.height + fMarginY;
+                area= new Rectangle(bounds.x, y, bounds.width, bounds.y + bounds.height - y);
+                break;
+            case DWT.RIGHT:
+                int x= subjectArea.x + subjectArea.width + fMarginX;
+                area= new Rectangle(x, bounds.y, bounds.x + bounds.width - x, bounds.height);
+                break;
+            case DWT.TOP:
+                area= new Rectangle(bounds.x, bounds.y, bounds.width, subjectArea.y - bounds.y - fMarginY);
+                break;
+            case DWT.LEFT:
+                area= new Rectangle(bounds.x, bounds.y, subjectArea.x - bounds.x - fMarginX, bounds.height);
+                break;
+            default:
+                Assert.isLegal(false);
+                return null;
+        }
+
+        // Don't return negative areas if the subjectArea overlaps with the monitor bounds.
+        area.intersect(bounds);
+        return area;
+    }
+
+    /**
+     * Checks whether a control of the given size at the given location would be completely visible
+     * in the given display area when laid out by using the given anchor. If not, this method tries
+     * to shift the control orthogonal to the direction given by the anchor to make it visible. If possible
+     * it updates the location.<p>
+     * This method returns <code>true</code> if the potentially updated position results in a
+     * completely visible control, or <code>false</code> otherwise.
+     *
+     *
+     * @param location the location of the control
+     * @param size the size of the control
+     * @param displayArea the display area in which the control should be visible
+     * @param anchor anchor for lying out the control
+     * @return <code>true</code>if the updated location is useful
+     */
+    protected bool updateLocation(Point location, Point size, Rectangle displayArea, Anchor anchor) {
+
+        int displayLowerRightX= displayArea.x + displayArea.width;
+        int displayLowerRightY= displayArea.y + displayArea.height;
+        int lowerRightX= location.x + size.x;
+        int lowerRightY= location.y + size.y;
+
+        if (ANCHOR_BOTTOM is anchor || ANCHOR_TOP is anchor) {
+
+            if (ANCHOR_BOTTOM is anchor) {
+                if (lowerRightY > displayLowerRightY)
+                    return false;
+            } else {
+                if (location.y < displayArea.y)
+                    return false;
+            }
+
+            if (lowerRightX > displayLowerRightX)
+                location.x= location.x - (lowerRightX - displayLowerRightX);
+
+            return (location.x >= displayArea.x && location.y >= displayArea.y);
+
+        } else if (ANCHOR_RIGHT is anchor || ANCHOR_LEFT is anchor) {
+
+            if (ANCHOR_RIGHT is anchor) {
+                if (lowerRightX > displayLowerRightX)
+                    return false;
+            } else {
+                if (location.x < displayArea.x)
+                    return false;
+            }
+
+            if (lowerRightY > displayLowerRightY)
+                location.y= location.y - (lowerRightY - displayLowerRightY);
+
+            return (location.x >= displayArea.x && location.y >= displayArea.y);
+
+        } else if (ANCHOR_GLOBAL is anchor) {
+
+            if (lowerRightX > displayLowerRightX)
+                location.x= location.x - (lowerRightX - displayLowerRightX);
+
+            if (lowerRightY > displayLowerRightY)
+                location.y= location.y - (lowerRightY - displayLowerRightY);
+
+            return (location.x >= displayArea.x && location.y >= displayArea.y);
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the next fallback anchor as specified by this manager's
+     * fallback anchor sequence.
+     * <p>
+     * The fallback anchor for the given anchor is the one that comes directly after
+     * the given anchor or is the first one in the sequence if the given anchor is the
+     * last one in the sequence.
+     * </p>
+     * <p>
+     * Note: It is the callers responsibility to prevent an endless loop i.e. to test
+     * whether a given anchor has already been used once.
+     * then
+     * </p>
+     *
+     * @param anchor the current anchor
+     * @return the next fallback anchor or <code>null</code> if no fallback anchor is available
+     */
+    protected Anchor getNextFallbackAnchor(Anchor anchor) {
+
+        if (anchor is null || fFallbackAnchors is null)
+            return null;
+
+        for (int i= 0; i < fFallbackAnchors.length; i++) {
+            if (fFallbackAnchors[i] is anchor)
+                return fFallbackAnchors[i + 1 is fFallbackAnchors.length ? 0 : i + 1];
+        }
+
+        return null;
+    }
+
+    /**
+     * Computes the location of the information control depending on the
+     * subject area and the size of the information control. This method attempts
+     * to find a location at which the information control lies completely in the display's
+     * client area while honoring the manager's default anchor. If this isn't possible using the
+     * default anchor, the fallback anchors are tried out.
+     *
+     * @param subjectArea the information area
+     * @param controlSize the size of the information control
+     * @return the computed location of the information control
+     */
+    protected Point computeInformationControlLocation(Rectangle subjectArea, Point controlSize) {
+        Rectangle subjectAreaDisplayRelative= Geometry.toDisplay(fSubjectControl, subjectArea);
+
+        Point upperLeft;
+        Anchor testAnchor= fAnchor;
+        Rectangle bestBounds= null;
+        int bestArea= Integer.MIN_VALUE;
+        Anchor bestAnchor= null;
+        do {
+
+            upperLeft= computeLocation(subjectArea, controlSize, testAnchor);
+            dwt.widgets.Monitor.Monitor monitor= getClosestMonitor(subjectAreaDisplayRelative, testAnchor);
+            if (updateLocation(upperLeft, controlSize, monitor.getClientArea(), testAnchor))
+                return upperLeft;
+
+            // compute available area for this anchor and update if better than best
+            Rectangle available= computeAvailableArea(subjectAreaDisplayRelative, monitor.getClientArea(), testAnchor);
+            Rectangle proposed= new Rectangle(upperLeft.x, upperLeft.y, controlSize.x, controlSize.y);
+            available.intersect(proposed);
+            int area= available.width * available.height;
+            if (area > bestArea) {
+                bestArea= area;
+                bestBounds= available;
+                bestAnchor= testAnchor;
+            }
+
+            testAnchor= getNextFallbackAnchor(testAnchor);
+
+        } while (testAnchor !is fAnchor && testAnchor !is null);
+
+        // no anchor is perfect - select the one with larges area and set the size to not overlap with the subjectArea
+        if (bestAnchor !is ANCHOR_GLOBAL)
+            Geometry.set(controlSize, Geometry.getSize(bestBounds));
+        return Geometry.getLocation(bestBounds);
+    }
+
+    /**
+     * Gets the closest monitor given an anchor and the subject area.
+     *
+     * @param area the subject area
+     * @param anchor the anchor
+     * @return the monitor closest to the edge of <code>area</code> defined by
+     *         <code>anchor</code>
+     * @since 3.3
+     */
+    private dwt.widgets.Monitor.Monitor getClosestMonitor(Rectangle area, Anchor anchor) {
+        Point center;
+        if (ANCHOR_GLOBAL is anchor)
+            center= Geometry.centerPoint(area);
+        else
+            center= Geometry.centerPoint(Geometry.getExtrudedEdge(area, 0, anchor.getSWTFlag()));
+        return getClosestMonitor(fSubjectControl.getDisplay(), Geometry.createRectangle(center, new Point(0, 0)));
+    }
+
+    /**
+     * Copied from dwtx.jface.window.Window. Returns the monitor whose client area contains
+     * the given point. If no monitor contains the point, returns the monitor that is closest to the
+     * point. If this is ever made public, it should be moved into a separate utility class.
+     *
+     * @param display the display to search for monitors
+     * @param rectangle the rectangle to find the closest monitor for (display coordinates)
+     * @return the monitor closest to the given point
+     * @since 3.3
+     */
+    private dwt.widgets.Monitor.Monitor getClosestMonitor(Display display, Rectangle rectangle) {
+        int closest = Integer.MAX_VALUE;
+
+        Point toFind= Geometry.centerPoint(rectangle);
+        dwt.widgets.Monitor.Monitor[] monitors = display.getMonitors();
+        dwt.widgets.Monitor.Monitor result = monitors[0];
+
+        for (int idx = 0; idx < monitors.length; idx++) {
+            dwt.widgets.Monitor.Monitor current = monitors[idx];
+
+            Rectangle clientArea = current.getClientArea();
+
+            if (clientArea.contains(toFind)) {
+                return current;
+            }
+
+            int distance = Geometry.distanceSquared(Geometry.centerPoint(clientArea), toFind);
+            if (distance < closest) {
+                closest = distance;
+                result = current;
+            }
+        }
+
+        return result;
+    }
+
+    /**
+     * Computes information to be displayed as well as the subject area
+     * and initiates that this information is presented in the information control.
+     * This happens only if this controller is enabled.
+     */
+    public void showInformation() {
+        if (fEnabled)
+            doShowInformation();
+    }
+
+    /**
+     * Computes information to be displayed as well as the subject area
+     * and initiates that this information is presented in the information control.
+     */
+    protected void doShowInformation() {
+        fSubjectArea= null;
+        fInformation= null;
+        computeInformation();
+    }
+
+    /**
+     * Presents the information in the information control or hides the information
+     * control if no information should be presented. The information has previously
+     * been set using <code>setInformation</code>.
+     */
+    protected void presentInformation() {
+        bool hasContents= false;
+        if ( stringcast(fInformation) )
+            hasContents= (stringcast(fInformation)).trim().length() > 0;
+        else
+            hasContents= (fInformation !is null);
+
+        if (fSubjectArea !is null && hasContents)
+            internalShowInformationControl(fSubjectArea, fInformation);
+        else
+            hideInformationControl();
+    }
+
+    /**
+     * Opens the information control with the given information and the specified
+     * subject area. It also activates the information control closer.
+     *
+     * @param subjectArea the information area
+     * @param information the information
+     */
+    private void internalShowInformationControl(Rectangle subjectArea, Object information) {
+        if ( cast(InformationControlReplacer)this ) {
+            (cast(InformationControlReplacer) this).showInformationControl(subjectArea, information);
+            return;
+        }
+
+        IInformationControl informationControl= getInformationControl();
+        if (informationControl !is null) {
+
+            Point sizeConstraints= computeSizeConstraints(fSubjectControl, fSubjectArea, informationControl);
+            if ( cast(IInformationControlExtension3)informationControl ) {
+                IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) informationControl;
+                Rectangle trim= iControl3.computeTrim();
+                sizeConstraints.x += trim.width;
+                sizeConstraints.y += trim.height;
+            }
+            informationControl.setSizeConstraints(sizeConstraints.x, sizeConstraints.y);
+
+            if ( cast(IInformationControlExtension2)informationControl )
+                (cast(IInformationControlExtension2)informationControl).setInput(information);
+            else
+                informationControl.setInformation(information.toString());
+
+            if ( cast(IInformationControlExtension)informationControl ) {
+                IInformationControlExtension extension= cast(IInformationControlExtension)informationControl;
+                if (!extension.hasContents())
+                    return;
+            }
+
+            Point size= null;
+            Point location= null;
+            Rectangle bounds= restoreInformationControlBounds();
+
+            if (bounds !is null) {
+                if (bounds.x > -1 && bounds.y > -1)
+                    location= Geometry.getLocation(bounds);
+
+                if (bounds.width > -1 && bounds.height > -1)
+                    size= Geometry.getSize(bounds);
+            }
+
+            if (size is null)
+                size= informationControl.computeSizeHint();
+
+            if (fEnforceAsMinimalSize)
+                size= Geometry.max(size, sizeConstraints);
+            if (fEnforceAsMaximalSize)
+                size= Geometry.min(size, sizeConstraints);
+
+            if (location is null)
+                location= computeInformationControlLocation(subjectArea, size);
+
+            Rectangle controlBounds= Geometry.createRectangle(location, size);
+            cropToClosestMonitor(controlBounds);
+            location= Geometry.getLocation(controlBounds);
+            size= Geometry.getSize(controlBounds);
+            informationControl.setLocation(location);
+            informationControl.setSize(size.x, size.y);
+
+            showInformationControl(subjectArea);
+        }
+    }
+
+    /**
+     * Crops the given bounds such that they lie completely on the closest monitor.
+     *
+     * @param bounds shell bounds to crop
+     * @since 3.4
+     */
+    void cropToClosestMonitor(Rectangle bounds) {
+        Rectangle monitorBounds= getClosestMonitor(fSubjectControl.getDisplay(), bounds).getClientArea();
+        bounds.intersect(monitorBounds);
+    }
+
+    /**
+     * Hides the information control and stops the information control closer.
+     */
+    protected void hideInformationControl() {
+        if (fInformationControl !is null) {
+            storeInformationControlBounds();
+            fInformationControl.setVisible(false);
+            if (fInformationControlCloser !is null)
+                fInformationControlCloser.stop();
+        }
+    }
+
+    /**
+     * Shows the information control and starts the information control closer.
+     * This method may not be called by clients.
+     *
+     * @param subjectArea the information area
+     */
+    protected void showInformationControl(Rectangle subjectArea) {
+        fInformationControl.setVisible(true);
+
+        if (fTakesFocusWhenVisible)
+            fInformationControl.setFocus();
+
+        if (fInformationControlCloser !is null)
+            fInformationControlCloser.start(subjectArea);
+    }
+
+    /**
+     * Replaces this manager's information control as defined by
+     * the information control replacer.
+     * <strong>Must only be called when {@link #fInformationControl} instanceof {@link IInformationControlExtension3}!</strong>
+     *
+     * @param takeFocus <code>true</code> iff the replacing information control should take focus
+     *
+     * @since 3.4
+     */
+    void replaceInformationControl(bool takeFocus) {
+        if (fInformationControlReplacer !is null && canReplace(fInformationControl)) {
+            IInformationControlExtension3 iControl3= cast(IInformationControlExtension3) fInformationControl;
+            Rectangle b= iControl3.getBounds();
+            Rectangle t= iControl3.computeTrim();
+            Rectangle contentBounds= new Rectangle(b.x - t.x, b.y - t.y, b.width - t.width, b.height - t.height);
+            IInformationControlCreator informationPresenterControlCreator= (cast(IInformationControlExtension5) fInformationControl).getInformationPresenterControlCreator();
+            fInformationControlReplacer.replaceInformationControl(informationPresenterControlCreator, contentBounds, fInformation, fSubjectArea, takeFocus);
+        }
+        hideInformationControl();
+    }
+
+    /**
+     * Disposes this manager's information control.
+     */
+    public void disposeInformationControl() {
+        if (fInformationControl !is null) {
+            fInformationControl.dispose();
+            handleInformationControlDisposed();
+        }
+    }
+
+    /**
+     * Disposes this manager and if necessary all dependent parts such as
+     * the information control. For symmetry it first disables this manager.
+     */
+    public void dispose() {
+        if (!fDisposed) {
+
+            fDisposed= true;
+
+            setEnabled(false);
+            disposeInformationControl();
+
+            if (fInformationControlReplacer !is null) {
+                fInformationControlReplacer.dispose();
+                fInformationControlReplacer= null;
+            }
+
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed() && fSubjectControlDisposeListener !is null)
+                fSubjectControl.removeDisposeListener(fSubjectControlDisposeListener);
+            fSubjectControl= null;
+            fSubjectControlDisposeListener= null;
+
+            fIsCustomInformationControl= false;
+            fCustomInformationControlCreator= null;
+            fInformationControlCreator= null;
+            fInformationControlCloser= null;
+        }
+    }
+
+    // ------ control's size handling dialog settings ------
+
+    /**
+     * Stores the information control's bounds.
+     *
+     * @since 3.0
+     */
+    protected void storeInformationControlBounds() {
+        if (fDialogSettings is null || fInformationControl is null || !(fIsRestoringLocation || fIsRestoringSize))
+            return;
+
+        if (!( cast(IInformationControlExtension3)fInformationControl ))
+            throw new UnsupportedOperationException();
+
+        bool controlRestoresSize= (cast(IInformationControlExtension3)fInformationControl).restoresSize();
+        bool controlRestoresLocation= (cast(IInformationControlExtension3)fInformationControl).restoresLocation();
+
+        Rectangle bounds= (cast(IInformationControlExtension3)fInformationControl).getBounds();
+        if (bounds is null)
+            return;
+
+        if (fIsRestoringSize && controlRestoresSize) {
+            fDialogSettings.put(STORE_SIZE_WIDTH, bounds.width);
+            fDialogSettings.put(STORE_SIZE_HEIGHT, bounds.height);
+        }
+        if (fIsRestoringLocation && controlRestoresLocation) {
+            fDialogSettings.put(STORE_LOCATION_X, bounds.x);
+            fDialogSettings.put(STORE_LOCATION_Y, bounds.y);
+        }
+    }
+    /**
+     * Restores the information control's bounds.
+     *
+     * @return the stored bounds
+     * @since 3.0
+     */
+    protected Rectangle restoreInformationControlBounds() {
+        if (fDialogSettings is null || !(fIsRestoringLocation || fIsRestoringSize))
+            return null;
+
+        if (!( cast(IInformationControlExtension3)fInformationControl ))
+            throw new UnsupportedOperationException();
+
+        bool controlRestoresSize= (cast(IInformationControlExtension3)fInformationControl).restoresSize();
+        bool controlRestoresLocation= (cast(IInformationControlExtension3)fInformationControl).restoresLocation();
+
+        Rectangle bounds= new Rectangle(-1, -1, -1, -1);
+
+        if (fIsRestoringSize && controlRestoresSize) {
+            try {
+                bounds.width= fDialogSettings.getInt(STORE_SIZE_WIDTH);
+                bounds.height= fDialogSettings.getInt(STORE_SIZE_HEIGHT);
+            } catch (NumberFormatException ex) {
+                bounds.width= -1;
+                bounds.height= -1;
+            }
+        }
+
+        if (fIsRestoringLocation && controlRestoresLocation) {
+            try {
+                bounds.x= fDialogSettings.getInt(STORE_LOCATION_X);
+                bounds.y= fDialogSettings.getInt(STORE_LOCATION_Y);
+            } catch (NumberFormatException ex) {
+                bounds.x= -1;
+                bounds.y= -1;
+            }
+        }
+
+        // sanity check
+        if (bounds.x is -1 && bounds.y is -1 && bounds.width is -1 && bounds.height is -1)
+            return null;
+
+        Rectangle maxBounds= null;
+        if (fSubjectControl !is null && !fSubjectControl.isDisposed())
+            maxBounds= fSubjectControl.getDisplay().getBounds();
+        else {
+            // fallback
+            Display display= Display.getCurrent();
+            if (display is null)
+                display= Display.getDefault();
+            if (display !is null && !display.isDisposed())
+                maxBounds= display.getBounds();
+        }
+
+
+        if (bounds.width > -1 && bounds.height > -1) {
+            if (maxBounds !is null) {
+                bounds.width= Math.min(bounds.width, maxBounds.width);
+                bounds.height= Math.min(bounds.height, maxBounds.height);
+            }
+
+            // Enforce an absolute minimal size
+            bounds.width= Math.max(bounds.width, 30);
+            bounds.height= Math.max(bounds.height, 30);
+        }
+
+        if (bounds.x > -1 && bounds.y > -1 && maxBounds !is null) {
+            bounds.x= Math.max(bounds.x, maxBounds.x);
+            bounds.y= Math.max(bounds.y, maxBounds.y);
+
+            if (bounds .width > -1 && bounds.height > -1) {
+                bounds.x= Math.min(bounds.x, maxBounds.width - bounds.width);
+                bounds.y= Math.min(bounds.y, maxBounds.height - bounds.height);
+            }
+        }
+
+        return bounds;
+    }
+
+    /**
+     * Returns an adapter that gives access to internal methods.
+     * <p>
+     * <strong>Note:</strong> This method is not intended to be referenced or overridden by clients.</p>
+     *
+     * @return the replaceable information control accessor
+     * @since 3.4
+     * @noreference This method is not intended to be referenced by clients.
+     * @nooverride This method is not intended to be re-implemented or extended by clients.
+     */
+    public InternalAccessor getInternalAccessor() {
+        return new MyInternalAccessor(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/AbstractLineTracker.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,471 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.AbstractLineTracker;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+import tango.text.convert.Format;
+
+import dwtx.dwtxhelper.Collection;
+
+
+    /**
+     * Combines the information of the occurrence of a line delimiter. <code>delimiterIndex</code>
+     * is the index where a line delimiter starts, whereas <code>delimiterLength</code>,
+     * indicates the length of the delimiter.
+     */
+    protected class DelimiterInfo {
+        public int delimiterIndex;
+        public int delimiterLength;
+        public String delimiter;
+    }
+    alias DelimiterInfo AbstractLineTracker_DelimiterInfo;
+
+/**
+ * Abstract implementation of <code>ILineTracker</code>. It lets the definition of line
+ * delimiters to subclasses. Assuming that '\n' is the only line delimiter, this abstract
+ * implementation defines the following line scheme:
+ * <ul>
+ * <li> "" -> [0,0]
+ * <li> "a" -> [0,1]
+ * <li> "\n" -> [0,1], [1,0]
+ * <li> "a\n" -> [0,2], [2,0]
+ * <li> "a\nb" -> [0,2], [2,1]
+ * <li> "a\nbc\n" -> [0,2], [2,3], [5,0]
+ * </ul>
+ * <p>
+ * This class must be subclassed.
+ * </p>
+ */
+public abstract class AbstractLineTracker : ILineTracker, ILineTrackerExtension {
+
+    /**
+     * Tells whether this class is in debug mode.
+     *
+     * @since 3.1
+     */
+    private static const bool DEBUG= false;
+
+    /**
+     * Representation of replace and set requests.
+     *
+     * @since 3.1
+     */
+    protected static class Request {
+        public const int offset;
+        public const int length;
+        public const String text;
+
+        public this(int offset, int length, String text) {
+            this.offset= offset;
+            this.length= length;
+            this.text= text;
+        }
+
+        public this(String text) {
+            this.offset= -1;
+            this.length= -1;
+            this.text= text;
+        }
+
+        public bool isReplaceRequest() {
+            return this.offset > -1 && this.length > -1;
+        }
+    }
+
+    /**
+     * The active rewrite session.
+     *
+     * @since 3.1
+     */
+    private DocumentRewriteSession fActiveRewriteSession;
+    /**
+     * The list of pending requests.
+     *
+     * @since 3.1
+     */
+    private List fPendingRequests;
+    /**
+     * The implementation that this tracker delegates to.
+     *
+     * @since 3.2
+     */
+    private ILineTracker fDelegate;
+    private void fDelegate_init() {
+        fDelegate = new class() ListLineTracker {
+            public String[] getLegalLineDelimiters() {
+                return this.outer.getLegalLineDelimiters();
+            }
+
+            protected DelimiterInfo nextDelimiterInfo(String text, int offset) {
+                return this.outer.nextDelimiterInfo(text, offset);
+            }
+        };
+    }
+    /**
+     * Whether the delegate needs conversion when the line structure is modified.
+     */
+    private bool fNeedsConversion= true;
+
+    /**
+     * Creates a new line tracker.
+     */
+    protected this() {
+        fDelegate_init();
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#computeNumberOfLines(java.lang.String)
+     */
+    public int computeNumberOfLines(String text) {
+        return fDelegate.computeNumberOfLines(text);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineDelimiter(int)
+     */
+    public String getLineDelimiter(int line)  {
+        checkRewriteSession();
+        return fDelegate.getLineDelimiter(line);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineInformation(int)
+     */
+    public IRegion getLineInformation(int line)  {
+        checkRewriteSession();
+        return fDelegate.getLineInformation(line);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineInformationOfOffset(int)
+     */
+    public IRegion getLineInformationOfOffset(int offset)  {
+        checkRewriteSession();
+        return fDelegate.getLineInformationOfOffset(offset);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineLength(int)
+     */
+    public int getLineLength(int line)  {
+        checkRewriteSession();
+        return fDelegate.getLineLength(line);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineNumberOfOffset(int)
+     */
+    public int getLineNumberOfOffset(int offset)  {
+        checkRewriteSession();
+        return fDelegate.getLineNumberOfOffset(offset);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineOffset(int)
+     */
+    public int getLineOffset(int line)  {
+        checkRewriteSession();
+        return fDelegate.getLineOffset(line);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getNumberOfLines()
+     */
+    public int getNumberOfLines() {
+        try {
+            checkRewriteSession();
+        } catch (BadLocationException x) {
+            // TODO there is currently no way to communicate that exception back to the document
+        }
+        return fDelegate.getNumberOfLines();
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getNumberOfLines(int, int)
+     */
+    public int getNumberOfLines(int offset, int length)  {
+        checkRewriteSession();
+        return fDelegate.getNumberOfLines(offset, length);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#set(java.lang.String)
+     */
+    public void set(String text) {
+        if (hasActiveRewriteSession()) {
+            fPendingRequests.clear();
+            fPendingRequests.add(new Request(text));
+            return;
+        }
+
+        fDelegate.set(text);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#replace(int, int, java.lang.String)
+     */
+    public void replace(int offset, int length, String text)  {
+        if (hasActiveRewriteSession()) {
+            fPendingRequests.add(new Request(offset, length, text));
+            return;
+        }
+
+        checkImplementation();
+
+        fDelegate.replace(offset, length, text);
+    }
+
+    /**
+     * Converts the implementation to be a {@link TreeLineTracker} if it isn't yet.
+     *
+     * @since 3.2
+     */
+    private void checkImplementation() {
+        if (fNeedsConversion) {
+            fNeedsConversion= false;
+            fDelegate= new class(cast(ListLineTracker) fDelegate)  TreeLineTracker {
+                this(ListLineTracker arg){
+                    super(arg);
+                }
+                protected DelimiterInfo nextDelimiterInfo(String text, int offset) {
+                    return this.outer.nextDelimiterInfo(text, offset);
+                }
+
+                public String[] getLegalLineDelimiters() {
+                    return this.outer.getLegalLineDelimiters();
+                }
+            };
+        }
+    }
+
+    /**
+     * Returns the information about the first delimiter found in the given text starting at the
+     * given offset.
+     *
+     * @param text the text to be searched
+     * @param offset the offset in the given text
+     * @return the information of the first found delimiter or <code>null</code>
+     */
+    protected abstract DelimiterInfo nextDelimiterInfo(String text, int offset);
+
+    /*
+     * @see dwtx.jface.text.ILineTrackerExtension#startRewriteSession(dwtx.jface.text.DocumentRewriteSession)
+     * @since 3.1
+     */
+    public final void startRewriteSession(DocumentRewriteSession session) {
+        if (fActiveRewriteSession !is null)
+            throw new IllegalStateException();
+        fActiveRewriteSession= session;
+        fPendingRequests= new ArrayList(20);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTrackerExtension#stopRewriteSession(dwtx.jface.text.DocumentRewriteSession, java.lang.String)
+     * @since 3.1
+     */
+    public final void stopRewriteSession(DocumentRewriteSession session, String text) {
+        if (fActiveRewriteSession is session) {
+            fActiveRewriteSession= null;
+            fPendingRequests= null;
+            set(text);
+        }
+    }
+
+    /**
+     * Tells whether there's an active rewrite session.
+     *
+     * @return <code>true</code> if there is an active rewrite session, <code>false</code>
+     *         otherwise
+     * @since 3.1
+     */
+    protected final bool hasActiveRewriteSession() {
+        return fActiveRewriteSession !is null;
+    }
+
+    /**
+     * Flushes the active rewrite session.
+     *
+     * @throws BadLocationException in case the recorded requests cannot be processed correctly
+     * @since 3.1
+     */
+    protected final void flushRewriteSession()  {
+        if (DEBUG)
+            System.out_.println(Format("AbstractLineTracker: Flushing rewrite session: {}", fActiveRewriteSession)); //$NON-NLS-1$
+
+        Iterator e= fPendingRequests.iterator();
+
+        fPendingRequests= null;
+        fActiveRewriteSession= null;
+
+        while (e.hasNext()) {
+            Request request= cast(Request) e.next();
+            if (request.isReplaceRequest())
+                replace(request.offset, request.length, request.text);
+            else
+                set(request.text);
+        }
+    }
+
+    /**
+     * Checks the presence of a rewrite session and flushes it.
+     *
+     * @throws BadLocationException in case flushing does not succeed
+     * @since 3.1
+     */
+    protected final void checkRewriteSession()  {
+        if (hasActiveRewriteSession())
+            flushRewriteSession();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/AbstractReusableInformationControlCreator.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.AbstractReusableInformationControlCreator;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.widgets.Composite;
+import dwt.widgets.Shell;
+
+
+/**
+ * Abstract class for a reusable information control creators.
+ *
+ * @since 3.3
+ */
+public abstract class AbstractReusableInformationControlCreator : IInformationControlCreator, IInformationControlCreatorExtension, DisposeListener {
+
+    private Map fInformationControls;
+
+    /**
+     * Creates the control.
+     *
+     * @param parent the parent shell
+     * @return the created information control
+     */
+    protected abstract IInformationControl doCreateInformationControl(Shell parent);
+
+    this(){
+        fInformationControls= new HashMap();
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlCreator#createInformationControl(dwt.widgets.Shell)
+     */
+    public IInformationControl createInformationControl(Shell parent) {
+        IInformationControl control= cast(IInformationControl)fInformationControls.get(parent);
+        if (control is null) {
+            control= doCreateInformationControl(parent);
+            control.addDisposeListener(this);
+            fInformationControls.put(parent, cast(Object)control);
+        }
+        return control;
+    }
+
+    /*
+     * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent)
+     */
+    public void widgetDisposed(DisposeEvent e) {
+        Composite parent= null;
+        if (cast(Shell)e.widget )
+            parent= (cast(Shell)e.widget).getParent();
+        if ( cast(Shell)parent )
+            fInformationControls.remove(parent);
+    }
+
+
+    /*
+     * @see dwtx.jface.text.IInformationControlCreatorExtension#canReuse(dwtx.jface.text.IInformationControl)
+     */
+    public bool canReuse(IInformationControl control) {
+        return fInformationControls.containsValue(cast(Object)control);
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlCreatorExtension#canReplace(dwtx.jface.text.IInformationControlCreator)
+     */
+    public bool canReplace(IInformationControlCreator creator) {
+        return creator.classinfo is this.classinfo;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/Assert.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,341 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.Assert;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * <code>Assert</code> is useful for for embedding runtime sanity checks
+ * in code. The static predicate methods all test a condition and throw some
+ * type of unchecked exception if the condition does not hold.
+ * <p>
+ * Assertion failure exceptions, like most runtime exceptions, are
+ * thrown when something is misbehaving. Assertion failures are invariably
+ * unspecified behavior; consequently, clients should never rely on
+ * these being thrown (or not thrown). <b>If you find yourself in the
+ * position where you need to catch an assertion failure, you have most
+ * certainly written your program incorrectly.</b>
+ * </p>
+ * <p>
+ * Note that an <code>assert</code> statement is slated to be added to the
+ * Java language in JDK 1.4, rending this class obsolete.
+ * </p>
+ *
+ * @deprecated As of 3.3, replaced by {@link dwtx.core.runtime.Assert}
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class Assert {
+
+        /**
+         * <code>AssertionFailedException</code> is a runtime exception thrown
+         * by some of the methods in <code>Assert</code>.
+         * <p>
+         * This class is not declared public to prevent some misuses; programs that catch
+         * or otherwise depend on assertion failures are susceptible to unexpected
+         * breakage when assertions in the code are added or removed.
+         * </p>
+         * <p>
+         * This class is not intended to be serialized.
+         * </p>
+         */
+        private static class AssertionFailedException : RuntimeException {
+
+            /**
+             * Serial version UID for this class.
+             * <p>
+             * Note: This class is not intended to be serialized.
+             * </p>
+             * @since 3.1
+             */
+            private static const long serialVersionUID= 3689918374733886002L;
+
+            /**
+             * Constructs a new exception.
+             */
+            public this() {
+            }
+
+            /**
+             * Constructs a new exception with the given message.
+             *
+             * @param detail the detailed message
+             */
+            public this(String detail) {
+                super(detail);
+            }
+        }
+
+    /* This class is not intended to be instantiated. */
+    private this() {
+    }
+
+    /**
+     * Asserts that an argument is legal. If the given bool is
+     * not <code>true</code>, an <code>IllegalArgumentException</code>
+     * is thrown.
+     *
+     * @param expression the outcome of the check
+     * @return <code>true</code> if the check passes (does not return
+     *    if the check fails)
+     * @exception IllegalArgumentException if the legality test failed
+     */
+    public static bool isLegal(bool expression) {
+        // succeed as quickly as possible
+        if (expression) {
+            return true;
+        }
+        return isLegal(expression, "");//$NON-NLS-1$
+    }
+
+    /**
+     * Asserts that an argument is legal. If the given bool is
+     * not <code>true</code>, an <code>IllegalArgumentException</code>
+     * is thrown.
+     * The given message is included in that exception, to aid debugging.
+     *
+     * @param expression the outcome of the check
+     * @param message the message to include in the exception
+     * @return <code>true</code> if the check passes (does not return
+     *    if the check fails)
+     * @exception IllegalArgumentException if the legality test failed
+     */
+    public static bool isLegal(bool expression, String message) {
+        if (!expression)
+            throw new IllegalArgumentException("assertion failed; " ~ message); //$NON-NLS-1$
+        return expression;
+    }
+
+    /**
+     * Asserts that the given object is not <code>null</code>. If this
+     * is not the case, some kind of unchecked exception is thrown.
+     * <p>
+     * As a general rule, parameters passed to API methods must not be
+     * <code>null</code> unless <b>explicitly</b> allowed in the method's
+     * specification. Similarly, results returned from API methods are never
+     * <code>null</code> unless <b>explicitly</b> allowed in the method's
+     * specification. Implementations are encouraged to make regular use of
+     * <code>Assert.isNotNull</code> to ensure that <code>null</code>
+     * parameters are detected as early as possible.
+     * </p>
+     *
+     * @param object the value to test
+     * @exception RuntimeException an unspecified unchecked exception if the object
+     *   is <code>null</code>
+     */
+    public static void isNotNull(Object object) {
+        // succeed as quickly as possible
+        if (object !is null) {
+            return;
+        }
+        isNotNull(object, "");//$NON-NLS-1$
+    }
+
+    /**
+     * Asserts that the given object is not <code>null</code>. If this
+     * is not the case, some kind of unchecked exception is thrown.
+     * The given message is included in that exception, to aid debugging.
+     * <p>
+     * As a general rule, parameters passed to API methods must not be
+     * <code>null</code> unless <b>explicitly</b> allowed in the method's
+     * specification. Similarly, results returned from API methods are never
+     * <code>null</code> unless <b>explicitly</b> allowed in the method's
+     * specification. Implementations are encouraged to make regular use of
+     * <code>Assert.isNotNull</code> to ensure that <code>null</code>
+     * parameters are detected as early as possible.
+     * </p>
+     *
+     * @param object the value to test
+     * @param message the message to include in the exception
+     * @exception RuntimeException an unspecified unchecked exception if the object
+     *   is <code>null</code>
+     */
+    public static void isNotNull(Object object, String message) {
+        if (object is null)
+            throw new AssertionFailedException("null argument;" ~ message);//$NON-NLS-1$
+    }
+
+    /**
+     * Asserts that the given bool is <code>true</code>. If this
+     * is not the case, some kind of unchecked exception is thrown.
+     *
+     * @param expression the outcome of the check
+     * @return <code>true</code> if the check passes (does not return
+     *    if the check fails)
+     */
+    public static bool isTrue(bool expression) {
+        // succeed as quickly as possible
+        if (expression) {
+            return true;
+        }
+        return isTrue(expression, "");//$NON-NLS-1$
+    }
+
+    /**
+     * Asserts that the given bool is <code>true</code>. If this
+     * is not the case, some kind of unchecked exception is thrown.
+     * The given message is included in that exception, to aid debugging.
+     *
+     * @param expression the outcome of the check
+     * @param message the message to include in the exception
+     * @return <code>true</code> if the check passes (does not return
+     *    if the check fails)
+     */
+    public static bool isTrue(bool expression, String message) {
+        if (!expression)
+            throw new AssertionFailedException("Assertion failed: "~message);//$NON-NLS-1$
+        return expression;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/BadLocationException.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.BadLocationException;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+/**
+ * Indicates the attempt to access a non-existing position. The attempt has been
+ * performed on a text store such as a document or string.
+ * <p>
+ * This class is not intended to be serialized.
+ * </p>
+ */
+public class BadLocationException : Exception {
+
+    /**
+     * Serial version UID for this class.
+     * <p>
+     * Note: This class is not intended to be serialized.
+     * </p>
+     * @since 3.1
+     */
+    private static const long serialVersionUID= 3257281452776370224L;
+
+    /**
+     * Creates a new bad location exception.
+     */
+    public this() {
+        super(null);
+    }
+
+    /**
+     * Creates a new bad location exception.
+     *
+     * @param message the exception message
+     */
+    public this(String message) {
+        super(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/BadPartitioningException.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.BadPartitioningException;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Represents the attempt to refer to a non-existing document partitioning.
+ * <p>
+ * This class is not intended to be serialized.
+ * </p>
+ *
+ * @see dwtx.jface.text.IDocument
+ * @see dwtx.jface.text.IDocumentExtension3
+ * @since 3.0
+ */
+public class BadPartitioningException : Exception {
+
+    /**
+     * Serial version UID for this class.
+     * <p>
+     * Note: This class is not intended to be serialized.
+     * </p>
+     * @since 3.1
+     */
+    private static const long serialVersionUID= 3256439205327876408L;
+
+    /**
+     * Creates a new bad partitioning exception.
+     */
+    public this() {
+        super("");
+    }
+
+    /**
+     * Creates a new bad partitioning exception.
+     *
+     * @param message message describing the exception
+     */
+    public this(String message) {
+        super(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/BadPositionCategoryException.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.BadPositionCategoryException;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+/**
+ * Indicates the attempt to access a non-existing position
+ * category in a document.
+ * <p>
+ * This class is not intended to be serialized.
+ * </p>
+ *
+ * @see dwtx.jface.text.IDocument
+ */
+public class BadPositionCategoryException : Exception {
+
+    /**
+     * Serial version UID for this class.
+     * <p>
+     * Note: This class is not intended to be serialized.
+     * </p>
+     * @since 3.1
+     */
+    private static const long serialVersionUID= 3761405300745713206L;
+
+    /**
+     * Creates a new bad position category exception.
+     */
+    public this() {
+        super( null );
+    }
+
+    /**
+     * Creates a new bad position category exception.
+     *
+     * @param message the exception's message
+     */
+    public this(String message) {
+        super(message);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ConfigurableLineTracker.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,223 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ConfigurableLineTracker;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Standard implementation of a generic
+ * {@link dwtx.jface.text.ILineTracker}.
+ * <p>
+ * The line tracker can be configured with the set of legal line delimiters.
+ * Line delimiters are unconstrained. The line delimiters are used to compute
+ * the tracker's line structure. In the case of overlapping line delimiters, the
+ * longest line delimiter is given precedence of the shorter ones.
+ * <p>
+ * This class is not intended to be subclassed.
+ * </p>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ConfigurableLineTracker : AbstractLineTracker {
+
+
+    /** The strings which are considered being the line delimiter */
+    private String[] fDelimiters;
+    /** A predefined delimiter information which is always reused as return value */
+    private AbstractLineTracker_DelimiterInfo fDelimiterInfo;
+
+
+    /**
+     * Creates a standard line tracker for the given line delimiters.
+     *
+     * @param legalLineDelimiters the tracker's legal line delimiters,
+     *      may not be <code>null</code> and must be longer than 0
+     */
+    public this(String[] legalLineDelimiters) {
+        Assert.isTrue(legalLineDelimiters.length > 0);
+        fDelimiterInfo= new AbstractLineTracker_DelimiterInfo();
+        fDelimiters= TextUtilities.copy(legalLineDelimiters);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLegalLineDelimiters()
+     */
+    public String[] getLegalLineDelimiters() {
+        return TextUtilities.copy(fDelimiters);
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractLineTracker#nextDelimiterInfo(java.lang.String, int)
+     */
+    protected AbstractLineTracker_DelimiterInfo nextDelimiterInfo(String text, int offset) {
+        if (fDelimiters.length > 1) {
+            int[] info= TextUtilities.indexOf(fDelimiters, text, offset);
+            if (info[0] is -1)
+                return null;
+            fDelimiterInfo.delimiterIndex= info[0];
+            fDelimiterInfo.delimiter= fDelimiters[info[1]];
+        } else {
+            int index= text.indexOf(fDelimiters[0], offset);
+            if (index is -1)
+                return null;
+            fDelimiterInfo.delimiterIndex= index;
+            fDelimiterInfo.delimiter= fDelimiters[0];
+        }
+
+        fDelimiterInfo.delimiterLength= fDelimiterInfo.delimiter.length();
+        return fDelimiterInfo;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/CopyOnWriteTextStore.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Anton Leherbauer (anton.leherbauer@windriver.com) - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.CopyOnWriteTextStore;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Copy-on-write <code>ITextStore</code> wrapper.
+ * <p>
+ * This implementation uses an unmodifiable text store for the initial content.
+ * Upon first modification attempt, the unmodifiable store is replaced with
+ * a modifiable instance which must be supplied in the constructor.</p>
+ * <p>
+ * This class is not intended to be subclassed.
+ * </p>
+ *
+ * @since 3.2
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class CopyOnWriteTextStore : ITextStore {
+
+    /**
+     * An unmodifiable String based text store. It is not possible to modify the content
+     * other than using {@link #set}. Trying to {@link #replace} a text range will
+     * throw an <code>UnsupportedOperationException</code>.
+     */
+    private static class StringTextStore : ITextStore {
+
+        /** Represents the content of this text store. */
+        private String fText= ""; //$NON-NLS-1$
+
+        /**
+         * Create an empty text store.
+         */
+        private this() {
+//             super();
+        }
+
+        /**
+         * Create a text store with initial content.
+         * @param text  the initial content
+         */
+        private this(String text) {
+//             super();
+            set(text);
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextStore#get(int)
+         */
+        public char get(int offset) {
+            return fText.charAt(offset);
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextStore#get(int, int)
+         */
+        public String get(int offset, int length) {
+            return fText.substring(offset, offset + length);
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextStore#getLength()
+         */
+        public int getLength() {
+            return fText.length();
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextStore#replace(int, int, java.lang.String)
+         */
+        public void replace(int offset, int length, String text) {
+            // modification not supported
+            throw new UnsupportedOperationException();
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextStore#set(java.lang.String)
+         */
+        public void set(String text) {
+            fText= text !is null ? text : ""; //$NON-NLS-1$
+        }
+
+    }
+
+    /** The underlying "real" text store */
+    protected ITextStore fTextStore;
+
+    /** A modifiable <code>ITextStore</code> instance */
+    private const ITextStore fModifiableTextStore;
+
+    /**
+     * Creates an empty text store. The given text store will be used upon first
+     * modification attempt.
+     *
+     * @param modifiableTextStore
+     *            a modifiable <code>ITextStore</code> instance, may not be
+     *            <code>null</code>
+     */
+    public this(ITextStore modifiableTextStore) {
+        Assert.isNotNull(cast(Object)modifiableTextStore);
+        fTextStore= new StringTextStore();
+        fTextStore= new StringTextStore();
+        fModifiableTextStore= modifiableTextStore;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#get(int)
+     */
+    public char get(int offset) {
+        return fTextStore.get(offset);
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#get(int, int)
+     */
+    public String get(int offset, int length) {
+        return fTextStore.get(offset, length);
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#getLength()
+     */
+    public int getLength() {
+        return fTextStore.getLength();
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#replace(int, int, java.lang.String)
+     */
+    public void replace(int offset, int length, String text) {
+        if (fTextStore !is fModifiableTextStore) {
+            String content= fTextStore.get(0, fTextStore.getLength());
+            fTextStore= fModifiableTextStore;
+            fTextStore.set(content);
+        }
+        fTextStore.replace(offset, length, text);
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#set(java.lang.String)
+     */
+    public void set(String text) {
+        fTextStore= new StringTextStore(text);
+        fModifiableTextStore.set(""); //$NON-NLS-1$
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/CursorLinePainter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,406 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.CursorLinePainter;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+
+
+import dwt.custom.LineBackgroundEvent;
+import dwt.custom.LineBackgroundListener;
+import dwt.custom.StyledText;
+import dwt.graphics.Color;
+import dwt.graphics.Point;
+
+
+/**
+ * A painter the draws the background of the caret line in a configured color.
+ * <p>
+ * Clients usually instantiate and configure object of this class.</p>
+ * <p>
+ * This class is not intended to be subclassed.</p>
+ *
+ * @since 2.1
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class CursorLinePainter : IPainter, LineBackgroundListener {
+
+    /** The viewer the painter works on */
+    private const ITextViewer fViewer;
+    /** The cursor line back ground color */
+    private Color fHighlightColor;
+    /** The paint position manager for managing the line coordinates */
+    private IPaintPositionManager fPositionManager;
+
+    /** Keeps track of the line to be painted */
+    private Position fCurrentLine;
+    /** Keeps track of the line to be cleared */
+    private Position fLastLine;
+    /** Keeps track of the line number of the last painted line */
+    private int fLastLineNumber= -1;
+    /** Indicates whether this painter is active */
+    private bool fIsActive;
+
+    /**
+     * Creates a new painter for the given source viewer.
+     *
+     * @param textViewer the source viewer for which to create a painter
+     */
+    public this(ITextViewer textViewer) {
+        fCurrentLine= new Position(0, 0);
+        fLastLine= new Position(0, 0);
+        fViewer= textViewer;
+    }
+
+    /**
+     * Sets the color in which to draw the background of the cursor line.
+     *
+     * @param highlightColor the color in which to draw the background of the cursor line
+     */
+    public void setHighlightColor(Color highlightColor) {
+        fHighlightColor= highlightColor;
+    }
+
+    /*
+     * @see LineBackgroundListener#lineGetBackground(LineBackgroundEvent)
+     */
+    public void lineGetBackground(LineBackgroundEvent event) {
+        // don't use cached line information because of asynchronous painting
+
+        StyledText textWidget= fViewer.getTextWidget();
+        if (textWidget !is null) {
+
+            int caret= textWidget.getCaretOffset();
+            int length= event.lineText.length();
+
+            if (event.lineOffset <= caret && caret <= event.lineOffset + length)
+                event.lineBackground= fHighlightColor;
+            else
+                event.lineBackground= textWidget.getBackground();
+        }
+    }
+
+    /**
+     * Updates all the cached information about the lines to be painted and to be cleared. Returns <code>true</code>
+     * if the line number of the cursor line has changed.
+     *
+     * @return <code>true</code> if cursor line changed
+     */
+    private bool updateHighlightLine() {
+        try {
+
+            IDocument document= fViewer.getDocument();
+            int modelCaret= getModelCaret();
+            int lineNumber= document.getLineOfOffset(modelCaret);
+
+            // redraw if the current line number is different from the last line number we painted
+            // initially fLastLineNumber is -1
+            if (lineNumber !is fLastLineNumber || !fCurrentLine.overlapsWith(modelCaret, 0)) {
+
+                fLastLine.offset= fCurrentLine.offset;
+                fLastLine.length= fCurrentLine.length;
+                fLastLine.isDeleted_= fCurrentLine.isDeleted_;
+
+                if (fCurrentLine.isDeleted_) {
+                    fCurrentLine.isDeleted_= false;
+                    fPositionManager.managePosition(fCurrentLine);
+                }
+
+                fCurrentLine.offset= document.getLineOffset(lineNumber);
+                if (lineNumber is document.getNumberOfLines() - 1)
+                    fCurrentLine.length= document.getLength() - fCurrentLine.offset;
+                else
+                    fCurrentLine.length= document.getLineOffset(lineNumber + 1) - fCurrentLine.offset;
+
+                fLastLineNumber= lineNumber;
+                return true;
+
+            }
+
+        } catch (BadLocationException e) {
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the location of the caret as offset in the source viewer's
+     * input document.
+     *
+     * @return the caret location
+     */
+    private int getModelCaret() {
+        int widgetCaret= fViewer.getTextWidget().getCaretOffset();
+        if ( cast(ITextViewerExtension5)fViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) fViewer;
+            return extension.widgetOffset2ModelOffset(widgetCaret);
+        }
+        IRegion visible= fViewer.getVisibleRegion();
+        return widgetCaret + visible.getOffset();
+    }
+
+    /**
+     * Assumes the given position to specify offset and length of a line to be painted.
+     *
+     * @param position the specification of the line  to be painted
+     */
+    private void drawHighlightLine(Position position) {
+
+        // if the position that is about to be drawn was deleted then we can't
+        if (position.isDeleted())
+            return;
+
+        int widgetOffset= 0;
+        if ( cast(ITextViewerExtension5)fViewer ) {
+
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) fViewer;
+            widgetOffset= extension.modelOffset2WidgetOffset(position.getOffset());
+            if (widgetOffset is -1)
+                return;
+
+        } else {
+
+            IRegion visible= fViewer.getVisibleRegion();
+            widgetOffset= position.getOffset() - visible.getOffset();
+            if (widgetOffset < 0 || visible.getLength() < widgetOffset )
+                return;
+        }
+
+        StyledText textWidget= fViewer.getTextWidget();
+        // check for https://bugs.eclipse.org/bugs/show_bug.cgi?id=64898
+        // this is a guard against the symptoms but not the actual solution
+        if (0 <= widgetOffset && widgetOffset <= textWidget.getCharCount()) {
+            Point upperLeft= textWidget.getLocationAtOffset(widgetOffset);
+            int width= textWidget.getClientArea().width + textWidget.getHorizontalPixel();
+            int height= textWidget.getLineHeight(widgetOffset);
+            textWidget.redraw(0, upperLeft.y, width, height, false);
+        }
+    }
+
+    /*
+     * @see IPainter#deactivate(bool)
+     */
+    public void deactivate(bool redraw) {
+        if (fIsActive) {
+            fIsActive= false;
+
+            /* on turning off the feature one has to paint the currently
+             * highlighted line with the standard background color
+             */
+            if (redraw)
+                drawHighlightLine(fCurrentLine);
+
+            fViewer.getTextWidget().removeLineBackgroundListener(this);
+
+            if (fPositionManager !is null)
+                fPositionManager.unmanagePosition(fCurrentLine);
+
+            fLastLineNumber= -1;
+            fCurrentLine.offset= 0;
+            fCurrentLine.length= 0;
+        }
+    }
+
+    /*
+     * @see IPainter#dispose()
+     */
+    public void dispose() {
+    }
+
+    /*
+     * @see IPainter#paint(int)
+     */
+    public void paint(int reason) {
+        if (fViewer.getDocument() is null) {
+            deactivate(false);
+            return;
+        }
+
+        StyledText textWidget= fViewer.getTextWidget();
+
+        // check selection
+        Point selection= textWidget.getSelection();
+        int startLine= textWidget.getLineAtOffset(selection.x);
+        int endLine= textWidget.getLineAtOffset(selection.y);
+        if (startLine !is endLine) {
+            deactivate(true);
+            return;
+        }
+
+        // initialization
+        if (!fIsActive) {
+            textWidget.addLineBackgroundListener(this);
+            fPositionManager.managePosition(fCurrentLine);
+            fIsActive= true;
+        }
+
+        //redraw line highlight only if it hasn't been drawn yet on the respective line
+        if (updateHighlightLine()) {
+            // clear last line
+            drawHighlightLine(fLastLine);
+            // draw new line
+            drawHighlightLine(fCurrentLine);
+        }
+    }
+
+    /*
+     * @see IPainter#setPositionManager(IPaintPositionManager)
+     */
+    public void setPositionManager(IPaintPositionManager manager) {
+        fPositionManager = manager;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DefaultAutoIndentStrategy.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.DefaultAutoIndentStrategy;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Default implementation of {@link dwtx.jface.text.IAutoIndentStrategy}.
+ * This strategy always copies the indentation of the previous line.
+ * <p>
+ * This class is not intended to be subclassed.</p>
+ *
+ * @deprecated since 3.1 use {@link dwtx.jface.text.DefaultIndentLineAutoEditStrategy} instead
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class DefaultAutoIndentStrategy : DefaultIndentLineAutoEditStrategy , IAutoIndentStrategy {
+
+    /**
+     * Creates a new default auto indent strategy.
+     */
+    public this() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DefaultDocumentAdapter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,575 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.DefaultDocumentAdapter;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+import dwt.DWT;
+import dwt.custom.TextChangeListener;
+import dwt.custom.TextChangedEvent;
+import dwt.custom.TextChangingEvent;
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Default implementation of {@link dwtx.jface.text.IDocumentAdapter}.
+ * <p>
+ * <strong>Note:</strong> This adapter does not work if the widget auto-wraps the text.
+ * </p>
+ */
+class DefaultDocumentAdapter : IDocumentAdapter, IDocumentListener, IDocumentAdapterExtension {
+
+    /** The adapted document. */
+    private IDocument fDocument;
+    /** The document clone for the non-forwarding case. */
+    private IDocument fDocumentClone;
+    /** The original content */
+    private String fOriginalContent;
+    /** The original line delimiters */
+    private String[] fOriginalLineDelimiters;
+    /** The registered text change listeners */
+    private List fTextChangeListeners;
+    /**
+     * The remembered document event
+     * @since 2.0
+     */
+    private DocumentEvent fEvent;
+    /** The line delimiter */
+    private String fLineDelimiter= null;
+    /**
+     * Indicates whether this adapter is forwarding document changes
+     * @since 2.0
+     */
+    private bool fIsForwarding= true;
+    /**
+     * Length of document at receipt of <code>documentAboutToBeChanged</code>
+     * @since 2.1
+     */
+    private int fRememberedLengthOfDocument;
+    /**
+     * Length of first document line at receipt of <code>documentAboutToBeChanged</code>
+     * @since 2.1
+     */
+    private int fRememberedLengthOfFirstLine;
+    /**
+     * The data of the event at receipt of <code>documentAboutToBeChanged</code>
+     * @since 2.1
+     */
+    private  DocumentEvent fOriginalEvent;
+
+
+    /**
+     * Creates a new document adapter which is initially not connected to
+     * any document.
+     */
+    public this() {
+        fTextChangeListeners= new ArrayList(1);
+        fOriginalEvent= new DocumentEvent();
+    }
+
+    /**
+     * Sets the given document as the document to be adapted.
+     *
+     * @param document the document to be adapted or <code>null</code> if there is no document
+     */
+    public void setDocument(IDocument document) {
+
+        if (fDocument !is null)
+            fDocument.removePrenotifiedDocumentListener(this);
+
+        fDocument= document;
+        fLineDelimiter= null;
+
+        if (!fIsForwarding) {
+            fDocumentClone= null;
+            if (fDocument !is null) {
+                fOriginalContent= fDocument.get();
+                fOriginalLineDelimiters= fDocument.getLegalLineDelimiters();
+            } else {
+                fOriginalContent= null;
+                fOriginalLineDelimiters= null;
+            }
+        }
+
+        if (fDocument !is null)
+            fDocument.addPrenotifiedDocumentListener(this);
+    }
+
+    /*
+     * @see StyledTextContent#addTextChangeListener(TextChangeListener)
+     */
+    public void addTextChangeListener(TextChangeListener listener) {
+        Assert.isNotNull(cast(Object)listener);
+        if (!fTextChangeListeners.contains(cast(Object)listener))
+            fTextChangeListeners.add(cast(Object)listener);
+    }
+
+    /*
+     * @see StyledTextContent#removeTextChangeListener(TextChangeListener)
+     */
+    public void removeTextChangeListener(TextChangeListener listener) {
+        Assert.isNotNull(cast(Object)listener);
+        fTextChangeListeners.remove(cast(Object)listener);
+    }
+
+    /**
+     * Tries to repair the line information.
+     *
+     * @param document the document
+     * @see IRepairableDocument#repairLineInformation()
+     * @since 3.0
+     */
+    private void repairLineInformation(IDocument document) {
+        if ( cast(IRepairableDocument)document ) {
+            IRepairableDocument repairable= cast(IRepairableDocument) document;
+            repairable.repairLineInformation();
+        }
+    }
+
+    /**
+     * Returns the line for the given line number.
+     *
+     * @param document the document
+     * @param line the line number
+     * @return the content of the line of the given number in the given document
+     * @throws BadLocationException if the line number is invalid for the adapted document
+     * @since 3.0
+     */
+    private String doGetLine(IDocument document, int line)  {
+        IRegion r= document.getLineInformation(line);
+        return document.get(r.getOffset(), r.getLength());
+    }
+
+    private IDocument getDocumentForRead() {
+        if (!fIsForwarding) {
+            if (fDocumentClone is null) {
+                String content= fOriginalContent is null ? "" : fOriginalContent; //$NON-NLS-1$
+                String[] delims= fOriginalLineDelimiters is null ? DefaultLineTracker.DELIMITERS : fOriginalLineDelimiters;
+                fDocumentClone= new DocumentClone(content, delims);
+            }
+            return fDocumentClone;
+        }
+
+        return fDocument;
+    }
+
+    /*
+     * @see StyledTextContent#getLine(int)
+     */
+    public String getLine(int line) {
+
+        IDocument document= getDocumentForRead();
+        try {
+            return doGetLine(document, line);
+        } catch (BadLocationException x) {
+            repairLineInformation(document);
+            try {
+                return doGetLine(document, line);
+            } catch (BadLocationException x2) {
+            }
+        }
+
+        DWT.error(DWT.ERROR_INVALID_ARGUMENT);
+        return null;
+    }
+
+    /*
+     * @see StyledTextContent#getLineAtOffset(int)
+     */
+    public int getLineAtOffset(int offset) {
+        IDocument document= getDocumentForRead();
+        try {
+            return document.getLineOfOffset(offset);
+        } catch (BadLocationException x) {
+            repairLineInformation(document);
+            try {
+                return document.getLineOfOffset(offset);
+            } catch (BadLocationException x2) {
+            }
+        }
+
+        DWT.error(DWT.ERROR_INVALID_ARGUMENT);
+        return -1;
+    }
+
+    /*
+     * @see StyledTextContent#getLineCount()
+     */
+    public int getLineCount() {
+        return getDocumentForRead().getNumberOfLines();
+    }
+
+    /*
+     * @see StyledTextContent#getOffsetAtLine(int)
+     */
+    public int getOffsetAtLine(int line) {
+        IDocument document= getDocumentForRead();
+        try {
+            return document.getLineOffset(line);
+        } catch (BadLocationException x) {
+            repairLineInformation(document);
+            try {
+                return document.getLineOffset(line);
+            } catch (BadLocationException x2) {
+            }
+        }
+
+        DWT.error(DWT.ERROR_INVALID_ARGUMENT);
+        return -1;
+    }
+
+    /*
+     * @see StyledTextContent#getTextRange(int, int)
+     */
+    public String getTextRange(int offset, int length) {
+        try {
+            return getDocumentForRead().get(offset, length);
+        } catch (BadLocationException x) {
+            DWT.error(DWT.ERROR_INVALID_ARGUMENT);
+            return null;
+        }
+    }
+
+    /*
+     * @see StyledTextContent#replaceTextRange(int, int, String)
+     */
+    public void replaceTextRange(int pos, int length, String text) {
+        try {
+            fDocument.replace(pos, length, text);
+        } catch (BadLocationException x) {
+            DWT.error(DWT.ERROR_INVALID_ARGUMENT);
+        }
+    }
+
+    /*
+     * @see StyledTextContent#setText(String)
+     */
+    public void setText(String text) {
+        fDocument.set(text);
+    }
+
+    /*
+     * @see StyledTextContent#getCharCount()
+     */
+    public int getCharCount() {
+        return getDocumentForRead().getLength();
+    }
+
+    /*
+     * @see StyledTextContent#getLineDelimiter()
+     */
+    public String getLineDelimiter() {
+        if (fLineDelimiter is null)
+            fLineDelimiter= TextUtilities.getDefaultLineDelimiter(fDocument);
+        return fLineDelimiter;
+    }
+
+    /*
+     * @see IDocumentListener#documentChanged(DocumentEvent)
+     */
+    public void documentChanged(DocumentEvent event) {
+        // check whether the given event is the one which was remembered
+        if (fEvent is null || event !is fEvent)
+            return;
+
+        if (isPatchedEvent(event) || (event.getOffset() is 0 && event.getLength() is fRememberedLengthOfDocument)) {
+            fLineDelimiter= null;
+            fireTextSet();
+        } else {
+            if (event.getOffset() < fRememberedLengthOfFirstLine)
+                fLineDelimiter= null;
+            fireTextChanged();
+        }
+    }
+
+    /*
+     * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
+     */
+    public void documentAboutToBeChanged(DocumentEvent event) {
+
+        fRememberedLengthOfDocument= fDocument.getLength();
+        try {
+            fRememberedLengthOfFirstLine= fDocument.getLineLength(0);
+        } catch (BadLocationException e) {
+            fRememberedLengthOfFirstLine= -1;
+        }
+
+        fEvent= event;
+        rememberEventData(fEvent);
+        fireTextChanging();
+    }
+
+    /**
+     * Checks whether this event has been changed between <code>documentAboutToBeChanged</code> and
+     * <code>documentChanged</code>.
+     *
+     * @param event the event to be checked
+     * @return <code>true</code> if the event has been changed, <code>false</code> otherwise
+     */
+    private bool isPatchedEvent(DocumentEvent event) {
+        return fOriginalEvent.fOffset !is event.fOffset || fOriginalEvent.fLength !is event.fLength || fOriginalEvent.fText !is event.fText;
+    }
+
+    /**
+     * Makes a copy of the given event and remembers it.
+     *
+     * @param event the event to be copied
+     */
+    private void rememberEventData(DocumentEvent event) {
+        fOriginalEvent.fOffset= event.fOffset;
+        fOriginalEvent.fLength= event.fLength;
+        fOriginalEvent.fText= event.fText;
+    }
+
+    /**
+     * Sends a text changed event to all registered listeners.
+     */
+    private void fireTextChanged() {
+
+        if (!fIsForwarding)
+            return;
+
+        TextChangedEvent event= new TextChangedEvent(this);
+
+        if (fTextChangeListeners !is null && fTextChangeListeners.size() > 0) {
+            Iterator e= (new ArrayList(fTextChangeListeners)).iterator();
+            while (e.hasNext())
+                (cast(TextChangeListener) e.next()).textChanged(event);
+        }
+    }
+
+    /**
+     * Sends a text set event to all registered listeners.
+     */
+    private void fireTextSet() {
+
+        if (!fIsForwarding)
+            return;
+
+        TextChangedEvent event = new TextChangedEvent(this);
+
+        if (fTextChangeListeners !is null && fTextChangeListeners.size() > 0) {
+            Iterator e= (new ArrayList(fTextChangeListeners)).iterator();
+            while (e.hasNext())
+                (cast(TextChangeListener) e.next()).textSet(event);
+        }
+    }
+
+    /**
+     * Sends the text changing event to all registered listeners.
+     */
+    private void fireTextChanging() {
+
+        if (!fIsForwarding)
+            return;
+
+        try {
+            IDocument document= fEvent.getDocument();
+            if (document is null)
+                return;
+
+            TextChangingEvent event= new TextChangingEvent(this);
+            event.start= fEvent.fOffset;
+            event.replaceCharCount= fEvent.fLength;
+            event.replaceLineCount= document.getNumberOfLines(fEvent.fOffset, fEvent.fLength) - 1;
+            event.newText= fEvent.fText;
+            event.newCharCount= (fEvent.fText is null ? 0 : fEvent.fText.length());
+            event.newLineCount= (fEvent.fText is null ? 0 : document.computeNumberOfLines(fEvent.fText));
+
+            if (fTextChangeListeners !is null && fTextChangeListeners.size() > 0) {
+                Iterator e= (new ArrayList(fTextChangeListeners)).iterator();
+                while (e.hasNext())
+                     (cast(TextChangeListener) e.next()).textChanging(event);
+            }
+
+        } catch (BadLocationException e) {
+        }
+    }
+
+    /*
+     * @see IDocumentAdapterExtension#resumeForwardingDocumentChanges()
+     * @since 2.0
+     */
+    public void resumeForwardingDocumentChanges() {
+        fIsForwarding= true;
+        fDocumentClone= null;
+        fOriginalContent= null;
+        fOriginalLineDelimiters= null;
+        fireTextSet();
+    }
+
+    /*
+     * @see IDocumentAdapterExtension#stopForwardingDocumentChanges()
+     * @since 2.0
+     */
+    public void stopForwardingDocumentChanges() {
+        fDocumentClone= null;
+        fOriginalContent= fDocument.get();
+        fOriginalLineDelimiters= fDocument.getLegalLineDelimiters();
+        fIsForwarding= false;
+    }
+
+    /++
+     + DWT extension
+     +/
+    public int utf8AdjustOffset( int offset ){
+        implMissing(__FILE__,__LINE__);
+        return offset;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DefaultIndentLineAutoEditStrategy.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,238 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.DefaultIndentLineAutoEditStrategy;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * This strategy always copies the indentation of the previous line.
+ * <p>
+ * This class is not intended to be subclassed.</p>
+ *
+ * @since 3.1
+ */
+public class DefaultIndentLineAutoEditStrategy : IAutoEditStrategy {
+
+    /**
+     * Creates a new indent line auto edit strategy which can be installed on
+     * text viewers.
+     */
+    public this() {
+    }
+
+    /**
+     * Returns the first offset greater than <code>offset</code> and smaller than
+     * <code>end</code> whose character is not a space or tab character. If no such
+     * offset is found, <code>end</code> is returned.
+     *
+     * @param document the document to search in
+     * @param offset the offset at which searching start
+     * @param end the offset at which searching stops
+     * @return the offset in the specified range whose character is not a space or tab
+     * @exception BadLocationException if position is an invalid range in the given document
+     */
+    protected int findEndOfWhiteSpace(IDocument document, int offset, int end)  {
+        while (offset < end) {
+            char c= document.getChar(offset);
+            if (c !is ' ' && c !is '\t') {
+                return offset;
+            }
+            offset++;
+        }
+        return end;
+    }
+
+    /**
+     * Copies the indentation of the previous line.
+     *
+     * @param d the document to work on
+     * @param c the command to deal with
+     */
+    private void autoIndentAfterNewLine(IDocument d, DocumentCommand c) {
+
+        if (c.offset is -1 || d.getLength() is 0)
+            return;
+
+        try {
+            // find start of line
+            int p= (c.offset is d.getLength() ? c.offset  - 1 : c.offset);
+            IRegion info= d.getLineInformationOfOffset(p);
+            int start= info.getOffset();
+
+            // find white spaces
+            int end= findEndOfWhiteSpace(d, start, c.offset);
+
+            StringBuffer buf= new StringBuffer(c.text);
+            if (end > start) {
+                // append to input
+                buf.append(d.get(start, end - start));
+            }
+
+            c.text= buf.toString();
+
+        } catch (BadLocationException excp) {
+            // stop work
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IAutoEditStrategy#customizeDocumentCommand(dwtx.jface.text.IDocument, dwtx.jface.text.DocumentCommand)
+     */
+    public void customizeDocumentCommand(IDocument d, DocumentCommand c) {
+        if (c.length is 0 && c.text !is null && TextUtilities.endsWith(d.getLegalLineDelimiters(), c.text) !is -1)
+            autoIndentAfterNewLine(d, c);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DefaultInformationControl.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,584 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.DefaultInformationControl;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.graphics.Color;
+import dwt.graphics.Drawable;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.layout.FillLayout;
+import dwt.widgets.Composite;
+import dwt.widgets.Display;
+import dwt.widgets.Shell;
+import dwtx.jface.action.ToolBarManager;
+import dwtx.jface.internal.text.html.HTMLTextPresenter;
+import dwtx.jface.resource.JFaceResources;
+import dwtx.jface.util.Geometry;
+
+    /**
+     * An information presenter determines the style presentation
+     * of information displayed in the default information control.
+     * The interface can be implemented by clients.
+     */
+    public interface IInformationPresenter {
+
+        /**
+         * Updates the given presentation of the given information and
+         * thereby may manipulate the information to be displayed. The manipulation
+         * could be the extraction of textual encoded style information etc. Returns the
+         * manipulated information.
+         * <p>
+         * <strong>Note:</strong> The given display must only be used for measuring.</p>
+         *
+         * @param display the display of the information control
+         * @param hoverInfo the information to be presented
+         * @param presentation the presentation to be updated
+         * @param maxWidth the maximal width in pixels
+         * @param maxHeight the maximal height in pixels
+         *
+         * @return the manipulated information
+         * @deprecated As of 3.2, replaced by {@link DefaultInformationControl.IInformationPresenterExtension#updatePresentation(Drawable, String, TextPresentation, int, int)}
+         */
+        String updatePresentation(Display display, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight);
+    }
+    alias IInformationPresenter DefaultInformationControl_IInformationPresenter;
+
+    /**
+     * An information presenter determines the style presentation
+     * of information displayed in the default information control.
+     * The interface can be implemented by clients.
+     *
+     * @since 3.2
+     */
+    public interface IInformationPresenterExtension {
+
+        /**
+         * Updates the given presentation of the given information and
+         * thereby may manipulate the information to be displayed. The manipulation
+         * could be the extraction of textual encoded style information etc. Returns the
+         * manipulated information.
+         * <p>
+         * Replaces {@link DefaultInformationControl.IInformationPresenter#updatePresentation(Display, String, TextPresentation, int, int)}
+         * Implementations should use the font of the given <code>drawable</code> to calculate
+         * the size of the text to be presented.
+         * </p>
+         *
+         * @param drawable the drawable of the information control
+         * @param hoverInfo the information to be presented
+         * @param presentation the presentation to be updated
+         * @param maxWidth the maximal width in pixels
+         * @param maxHeight the maximal height in pixels
+         *
+         * @return the manipulated information
+         */
+        String updatePresentation(Drawable drawable, String hoverInfo, TextPresentation presentation, int maxWidth, int maxHeight);
+    }
+    alias IInformationPresenterExtension DefaultInformationControl_IInformationPresenterExtension;
+
+
+/**
+ * Default implementation of {@link dwtx.jface.text.IInformationControl}.
+ * <p>
+ * Displays textual information in a {@link dwt.custom.StyledText}
+ * widget. Before displaying, the information set to this information control is
+ * processed by an <code>IInformationPresenter</code>.
+ *
+ * @since 2.0
+ */
+public class DefaultInformationControl : AbstractInformationControl , DisposeListener {
+
+    /**
+     * Inner border thickness in pixels.
+     * @since 3.1
+     */
+    private static const int INNER_BORDER= 1;
+
+    /** The control's text widget */
+    private StyledText fText;
+    /** The information presenter, or <code>null</code> if none. */
+    private const IInformationPresenter fPresenter;
+    /** A cached text presentation */
+    private const TextPresentation fPresentation;
+
+    /**
+     * Additional styles to use for the text control.
+     * @since 3.4, previously called <code>fTextStyle</code>
+     */
+    private const int fAdditionalTextStyles;
+
+    /**
+     * Creates a default information control with the given shell as parent. An information
+     * presenter that can handle simple HTML is used to process the information to be displayed.
+     *
+     * @param parent the parent shell
+     * @param isResizeable <code>true</code> if the control should be resizable
+     * @since 3.4
+     */
+    public this(Shell parent, bool isResizeable) {
+        fPresentation= new TextPresentation();
+        super(parent, isResizeable);
+        fAdditionalTextStyles= isResizeable ? DWT.V_SCROLL | DWT.H_SCROLL : DWT.NONE;
+        fPresenter= new HTMLTextPresenter(!isResizeable);
+        create();
+    }
+
+    /**
+     * Creates a default information control with the given shell as parent. An information
+     * presenter that can handle simple HTML is used to process the information to be displayed.
+     *
+     * @param parent the parent shell
+     * @param statusFieldText the text to be used in the status field or <code>null</code> to hide the status field
+     * @since 3.4
+     */
+    public this(Shell parent, String statusFieldText) {
+        this(parent, statusFieldText, new HTMLTextPresenter(true));
+    }
+
+    /**
+     * Creates a default information control with the given shell as parent. The
+     * given information presenter is used to process the information to be
+     * displayed.
+     *
+     * @param parent the parent shell
+     * @param statusFieldText the text to be used in the status field or <code>null</code> to hide the status field
+     * @param presenter the presenter to be used, or <code>null</code> if no presenter should be used
+     * @since 3.4
+     */
+    public this(Shell parent, String statusFieldText, IInformationPresenter presenter) {
+        fPresentation= new TextPresentation();
+        super(parent, statusFieldText);
+        fAdditionalTextStyles= DWT.NONE;
+        fPresenter= presenter;
+        create();
+    }
+
+    /**
+     * Creates a resizable default information control with the given shell as parent. An
+     * information presenter that can handle simple HTML is used to process the information to be
+     * displayed.
+     *
+     * @param parent the parent shell
+     * @param toolBarManager the manager or <code>null</code> if toolbar is not desired
+     * @since 3.4
+     */
+    public this(Shell parent, ToolBarManager toolBarManager) {
+        this(parent, toolBarManager, new HTMLTextPresenter(false));
+    }
+
+    /**
+     * Creates a resizable default information control with the given shell as
+     * parent. The given information presenter is used to process the
+     * information to be displayed.
+     *
+     * @param parent the parent shell
+     * @param toolBarManager the manager or <code>null</code> if toolbar is not desired
+     * @param presenter the presenter to be used, or <code>null</code> if no presenter should be used
+     * @since 3.4
+     */
+    public this(Shell parent, ToolBarManager toolBarManager, IInformationPresenter presenter) {
+        fPresentation= new TextPresentation();
+        super(parent, toolBarManager);
+        fAdditionalTextStyles= DWT.V_SCROLL | DWT.H_SCROLL;
+        fPresenter= presenter;
+        create();
+    }
+
+    /**
+     * Creates a default information control with the given shell as parent.
+     * No information presenter is used to process the information
+     * to be displayed.
+     *
+     * @param parent the parent shell
+     */
+    public this(Shell parent) {
+        this(parent, cast(String)null, null);
+    }
+
+    /**
+     * Creates a default information control with the given shell as parent. The given
+     * information presenter is used to process the information to be displayed.
+     *
+     * @param parent the parent shell
+     * @param presenter the presenter to be used
+     */
+    public this(Shell parent, IInformationPresenter presenter) {
+        this(parent, cast(String)null, presenter);
+    }
+
+    /**
+     * Creates a default information control with the given shell as parent. The
+     * given information presenter is used to process the information to be
+     * displayed. The given styles are applied to the created styled text
+     * widget.
+     *
+     * @param parent the parent shell
+     * @param shellStyle the additional styles for the shell
+     * @param style the additional styles for the styled text widget
+     * @param presenter the presenter to be used
+     * @deprecated As of 3.4, replaced by simpler constructors
+     */
+    public this(Shell parent, int shellStyle, int style, IInformationPresenter presenter) {
+        this(parent, shellStyle, style, presenter, null);
+    }
+
+    /**
+     * Creates a default information control with the given shell as parent. The
+     * given information presenter is used to process the information to be
+     * displayed. The given styles are applied to the created styled text
+     * widget.
+     *
+     * @param parentShell the parent shell
+     * @param shellStyle the additional styles for the shell
+     * @param style the additional styles for the styled text widget
+     * @param presenter the presenter to be used
+     * @param statusFieldText the text to be used in the status field or <code>null</code> to hide the status field
+     * @since 3.0
+     * @deprecated As of 3.4, replaced by simpler constructors
+     */
+    public this(Shell parentShell, int shellStyle, int style, IInformationPresenter presenter, String statusFieldText) {
+        fPresentation= new TextPresentation();
+        super(parentShell, DWT.NO_FOCUS | DWT.ON_TOP | shellStyle, statusFieldText, null);
+        fAdditionalTextStyles= style;
+        fPresenter= presenter;
+        create();
+    }
+
+    /**
+     * Creates a default information control with the given shell as parent. The
+     * given information presenter is used to process the information to be
+     * displayed.
+     *
+     * @param parent the parent shell
+     * @param textStyles the additional styles for the styled text widget
+     * @param presenter the presenter to be used
+     * @deprecated As of 3.4, replaced by {@link #DefaultInformationControl(Shell, DefaultInformationControl.IInformationPresenter)}
+     */
+    public this(Shell parent, int textStyles, IInformationPresenter presenter) {
+        this(parent, textStyles, presenter, null);
+    }
+
+    /**
+     * Creates a default information control with the given shell as parent. The
+     * given information presenter is used to process the information to be
+     * displayed.
+     *
+     * @param parent the parent shell
+     * @param textStyles the additional styles for the styled text widget
+     * @param presenter the presenter to be used
+     * @param statusFieldText the text to be used in the status field or <code>null</code> to hide the status field
+     * @since 3.0
+     * @deprecated As of 3.4, replaced by {@link #DefaultInformationControl(Shell, String, DefaultInformationControl.IInformationPresenter)}
+     */
+    public this(Shell parent, int textStyles, IInformationPresenter presenter, String statusFieldText) {
+        fPresentation= new TextPresentation();
+        super(parent, statusFieldText);
+        fAdditionalTextStyles= textStyles;
+        fPresenter= presenter;
+        create();
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControl#createContent(dwt.widgets.Composite)
+     */
+    protected void createContent(Composite parent) {
+        fText= new StyledText(parent, DWT.MULTI | DWT.READ_ONLY | fAdditionalTextStyles);
+        fText.setForeground(parent.getForeground());
+        fText.setBackground(parent.getBackground());
+        fText.setFont(JFaceResources.getDialogFont());
+        FillLayout layout= cast(FillLayout)parent.getLayout();
+        if (fText.getWordWrap()) {
+            // indent does not work for wrapping StyledText, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=56342 and https://bugs.eclipse.org/bugs/show_bug.cgi?id=115432
+            layout.marginHeight= INNER_BORDER;
+            layout.marginWidth= INNER_BORDER;
+        } else {
+            fText.setIndent(INNER_BORDER);
+        }
+    }
+
+    /*
+     * @see IInformationControl#setInformation(String)
+     */
+    public void setInformation(String content) {
+        if (fPresenter is null) {
+            fText.setText(content);
+        } else {
+            fPresentation.clear();
+
+            int maxWidth= -1;
+            int maxHeight= -1;
+            Point constraints= getSizeConstraints();
+            if (constraints !is null) {
+                maxWidth= constraints.x;
+                maxHeight= constraints.y;
+                if (fText.getWordWrap()) {
+                    maxWidth-= INNER_BORDER * 2;
+                    maxHeight-= INNER_BORDER * 2;
+                } else {
+                    maxWidth-= INNER_BORDER; // indent
+                }
+                Rectangle trim= computeTrim();
+                maxWidth-= trim.width;
+                maxHeight-= trim.height;
+                maxWidth-= fText.getCaret().getSize().x; // StyledText adds a border at the end of the line for the caret.
+            }
+            if (isResizable())
+                maxHeight= Integer.MAX_VALUE;
+
+            if ( cast(IInformationPresenterExtension)fPresenter )
+                content= (cast(IInformationPresenterExtension)fPresenter).updatePresentation(fText, content, fPresentation, maxWidth, maxHeight);
+            else
+                content= fPresenter.updatePresentation(getShell().getDisplay(), content, fPresentation, maxWidth, maxHeight);
+
+            if (content !is null) {
+                fText.setText(content);
+                TextPresentation.applyTextPresentation(fPresentation, fText);
+            } else {
+                fText.setText(""); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /*
+     * @see IInformationControl#setVisible(bool)
+     */
+    public void setVisible(bool visible) {
+        if (visible) {
+            if (fText.getWordWrap()) {
+                Point currentSize= getShell().getSize();
+                getShell().pack(true);
+                Point newSize= getShell().getSize();
+                if (newSize.x > currentSize.x || newSize.y > currentSize.y)
+                    setSize(currentSize.x, currentSize.y); // restore previous size
+            }
+        }
+
+        super.setVisible(visible);
+    }
+
+    /*
+     * @see IInformationControl#computeSizeHint()
+     */
+    public Point computeSizeHint() {
+        // see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=117602
+        int widthHint= DWT.DEFAULT;
+        Point constraints= getSizeConstraints();
+        if (constraints !is null && fText.getWordWrap())
+            widthHint= constraints.x;
+
+        return getShell().computeSize(widthHint, DWT.DEFAULT, true);
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControl#computeTrim()
+     */
+    public Rectangle computeTrim() {
+        return Geometry.add(super.computeTrim(), fText.computeTrim(0, 0, 0, 0));
+    }
+
+    /*
+     * @see IInformationControl#setForegroundColor(Color)
+     */
+    public void setForegroundColor(Color foreground) {
+        super.setForegroundColor(foreground);
+        fText.setForeground(foreground);
+    }
+
+    /*
+     * @see IInformationControl#setBackgroundColor(Color)
+     */
+    public void setBackgroundColor(Color background) {
+        super.setBackgroundColor(background);
+        fText.setBackground(background);
+    }
+
+    /*
+     * @see IInformationControlExtension#hasContents()
+     */
+    public bool hasContents() {
+        return fText.getCharCount() > 0;
+    }
+
+    /**
+     * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent)
+     * @since 3.0
+     * @deprecated As of 3.2, no longer used and called
+     */
+    public void widgetDisposed(DisposeEvent event) {
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension5#getInformationPresenterControlCreator()
+     * @since 3.4
+     */
+    public IInformationControlCreator getInformationPresenterControlCreator() {
+        return new class()  IInformationControlCreator {
+            /*
+             * @see dwtx.jface.text.IInformationControlCreator#createInformationControl(dwt.widgets.Shell)
+             */
+            public IInformationControl createInformationControl(Shell parent) {
+                return new DefaultInformationControl(parent, cast(ToolBarManager) null, fPresenter);
+            }
+        };
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DefaultLineTracker.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,229 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.DefaultLineTracker;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Standard implementation of {@link dwtx.jface.text.ILineTracker}.
+ * <p>
+ * The line tracker considers the three common line delimiters which are '\n',
+ * '\r', '\r\n'.
+ * <p>
+ * This class is not intended to be subclassed.
+ * </p>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class DefaultLineTracker : AbstractLineTracker {
+
+    /** The predefined delimiters of this tracker */
+    public const static String[] DELIMITERS= [ "\r", "\n", "\r\n" ]; //$NON-NLS-3$ //$NON-NLS-1$ //$NON-NLS-2$
+    /** A predefined delimiter information which is always reused as return value */
+    private AbstractLineTracker_DelimiterInfo fDelimiterInfo;
+
+
+    /**
+     * Creates a standard line tracker.
+     */
+    public this() {
+        fDelimiterInfo= new AbstractLineTracker_DelimiterInfo();
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLegalLineDelimiters()
+     */
+    public String[] getLegalLineDelimiters() {
+        return TextUtilities.copy(DELIMITERS);
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractLineTracker#nextDelimiterInfo(java.lang.String, int)
+     */
+    protected AbstractLineTracker_DelimiterInfo nextDelimiterInfo(String text, int offset) {
+
+        char ch;
+        int length= text.length();
+        for (int i= offset; i < length; i++) {
+
+            ch= text.charAt(i);
+            if (ch is '\r') {
+
+                if (i + 1 < length) {
+                    if (text.charAt(i + 1) is '\n') {
+                        fDelimiterInfo.delimiter= DELIMITERS[2];
+                        fDelimiterInfo.delimiterIndex= i;
+                        fDelimiterInfo.delimiterLength= 2;
+                        return fDelimiterInfo;
+                    }
+                }
+
+                fDelimiterInfo.delimiter= DELIMITERS[0];
+                fDelimiterInfo.delimiterIndex= i;
+                fDelimiterInfo.delimiterLength= 1;
+                return fDelimiterInfo;
+
+            } else if (ch is '\n') {
+
+                fDelimiterInfo.delimiter= DELIMITERS[1];
+                fDelimiterInfo.delimiterIndex= i;
+                fDelimiterInfo.delimiterLength= 1;
+                return fDelimiterInfo;
+            }
+        }
+
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DefaultPositionUpdater.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,393 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.DefaultPositionUpdater;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Default implementation of {@link dwtx.jface.text.IPositionUpdater}.
+ * <p>
+ * A default position updater must be configured with the position category whose positions it will
+ * update. Other position categories are not affected by this updater.
+ * </p>
+ * <p>
+ * This implementation follows the specification below:
+ * </p>
+ * <ul>
+ * <li>Inserting or deleting text before the position shifts the position accordingly.</li>
+ * <li>Inserting text at the position offset shifts the position accordingly.</li>
+ * <li>Inserting or deleting text strictly contained by the position shrinks or stretches the
+ * position.</li>
+ * <li>Inserting or deleting text after a position does not affect the position.</li>
+ * <li>Deleting text which strictly contains the position deletes the position. Note that the
+ * position is not deleted if its only shrunken to length zero. To delete a position, the
+ * modification must delete from <i>strictly before</i> to <i>strictly after</i> the position.</li>
+ * <li>Replacing text overlapping with the position is considered as a sequence of first deleting
+ * the replaced text and afterwards inserting the new text. Thus, a position might first be shifted
+ * and shrunken and then be stretched.</li>
+ * </ul>
+ * This class can be used as is or be adapted by subclasses. Fields are protected to allow
+ * subclasses direct access. Because of the frequency with which position updaters are used this is
+ * a performance decision.
+ */
+public class DefaultPositionUpdater : IPositionUpdater {
+
+    /** The position category the updater draws responsible for */
+    private String fCategory;
+
+    /** Caches the currently investigated position */
+    protected Position fPosition;
+    /**
+     * Remembers the original state of the investigated position
+     * @since 2.1
+     */
+    protected Position fOriginalPosition;
+    /** Caches the offset of the replaced text */
+    protected int fOffset;
+    /** Caches the length of the replaced text */
+    protected int fLength;
+    /** Caches the length of the newly inserted text */
+    protected int fReplaceLength;
+    /** Catches the document */
+    protected IDocument fDocument;
+
+
+    /**
+     * Creates a new default position updater for the given category.
+     *
+     * @param category the category the updater is responsible for
+     */
+    public this(String category) {
+        fOriginalPosition= new Position(0, 0);
+        fCategory= category;
+    }
+
+    /**
+     * Returns the category this updater is responsible for.
+     *
+     * @return the category this updater is responsible for
+     */
+    protected String getCategory() {
+        return fCategory;
+    }
+
+    /**
+     * Returns whether the current event describes a well formed replace
+     * by which the current position is directly affected.
+     *
+     * @return <code>true</code> the current position is directly affected
+     * @since 3.0
+     */
+    protected bool isAffectingReplace() {
+        return fLength > 0 && fReplaceLength > 0 && fPosition.length < fOriginalPosition.length;
+    }
+
+    /**
+     * Adapts the currently investigated position to an insertion.
+     */
+    protected void adaptToInsert() {
+
+        int myStart= fPosition.offset;
+        int myEnd=   fPosition.offset + fPosition.length - 1;
+        myEnd= Math.max(myStart, myEnd);
+
+        int yoursStart= fOffset;
+        int yoursEnd=   fOffset + fReplaceLength -1;
+        yoursEnd= Math.max(yoursStart, yoursEnd);
+
+        if (myEnd < yoursStart)
+            return;
+
+        if (fLength <= 0) {
+
+            if (myStart < yoursStart)
+                fPosition.length += fReplaceLength;
+            else
+                fPosition.offset += fReplaceLength;
+
+        } else {
+
+            if (myStart <= yoursStart && fOriginalPosition.offset <= yoursStart)
+                fPosition.length += fReplaceLength;
+            else
+                fPosition.offset += fReplaceLength;
+        }
+    }
+
+    /**
+     * Adapts the currently investigated position to a deletion.
+     */
+    protected void adaptToRemove() {
+
+        int myStart= fPosition.offset;
+        int myEnd=   fPosition.offset + fPosition.length -1;
+        myEnd= Math.max(myStart, myEnd);
+
+        int yoursStart= fOffset;
+        int yoursEnd=   fOffset + fLength -1;
+        yoursEnd= Math.max(yoursStart, yoursEnd);
+
+        if (myEnd < yoursStart)
+            return;
+
+        if (myStart <= yoursStart) {
+
+            if (yoursEnd <= myEnd)
+                fPosition.length -= fLength;
+            else
+                fPosition.length -= (myEnd - yoursStart +1);
+
+        } else if (yoursStart < myStart) {
+
+            if (yoursEnd < myStart)
+                fPosition.offset -= fLength;
+            else {
+                fPosition.offset -= (myStart - yoursStart);
+                fPosition.length -= (yoursEnd - myStart +1);
+            }
+
+        }
+
+        // validate position to allowed values
+        if (fPosition.offset < 0)
+            fPosition.offset= 0;
+
+        if (fPosition.length < 0)
+            fPosition.length= 0;
+    }
+
+    /**
+     * Adapts the currently investigated position to the replace operation.
+     * First it checks whether the change replaces the whole range of the position.
+     * If not, it performs first the deletion of the previous text and afterwards
+     * the insertion of the new text.
+     */
+    protected void adaptToReplace() {
+
+        if (fPosition.offset is fOffset && fPosition.length is fLength && fPosition.length > 0) {
+
+            // replace the whole range of the position
+            fPosition.length += (fReplaceLength - fLength);
+            if (fPosition.length < 0) {
+                fPosition.offset += fPosition.length;
+                fPosition.length= 0;
+            }
+
+        } else {
+
+            if (fLength >  0)
+                adaptToRemove();
+
+            if (fReplaceLength > 0)
+                adaptToInsert();
+        }
+    }
+
+    /**
+     * Determines whether the currently investigated position has been deleted by
+     * the replace operation specified in the current event. If so, it deletes
+     * the position and removes it from the document's position category.
+     *
+     * @return <code>true</code> if position has not been deleted
+     */
+    protected bool notDeleted() {
+
+        if (fOffset < fPosition.offset && (fPosition.offset + fPosition.length < fOffset + fLength)) {
+
+            fPosition.delete_();
+
+            try {
+                fDocument.removePosition(fCategory, fPosition);
+            } catch (BadPositionCategoryException x) {
+            }
+
+            return false;
+        }
+
+        return true;
+    }
+
+    /*
+     * @see dwtx.jface.text.IPositionUpdater#update(dwtx.jface.text.DocumentEvent)
+     */
+    public void update(DocumentEvent event) {
+
+        try {
+
+
+            fOffset= event.getOffset();
+            fLength= event.getLength();
+            fReplaceLength= (event.getText() is null ? 0 : event.getText().length());
+            fDocument= event.getDocument();
+
+            Position[] category= fDocument.getPositions(fCategory);
+            for (int i= 0; i < category.length; i++) {
+
+                fPosition= category[i];
+                fOriginalPosition.offset= fPosition.offset;
+                fOriginalPosition.length= fPosition.length;
+
+                if (notDeleted())
+                    adaptToReplace();
+            }
+
+        } catch (BadPositionCategoryException x) {
+            // do nothing
+        } finally {
+            fDocument= null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DefaultTextDoubleClickStrategy.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,369 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.DefaultTextDoubleClickStrategy;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.CharacterIterator;
+
+import dwtx.dwtxhelper.mangoicu.UBreakIterator;
+
+/**
+ * Standard implementation of
+ * {@link dwtx.jface.text.ITextDoubleClickStrategy}.
+ * <p>
+ * Selects words using <code>java.text.UBreakIterator</code> for the default
+ * locale.</p>
+ * <p>
+ * This class is not intended to be subclassed.
+ * </p>
+ *
+ * @see java.text.UBreakIterator
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class DefaultTextDoubleClickStrategy : ITextDoubleClickStrategy {
+
+
+    /**
+     * Implements a character iterator that works directly on
+     * instances of <code>IDocument</code>. Used to collaborate with
+     * the break iterator.
+     *
+     * @see IDocument
+     * @since 2.0
+     */
+    static class DocumentCharacterIterator : CharacterIterator {
+
+        /** Document to iterate over. */
+        private IDocument fDocument;
+        /** Start offset of iteration. */
+        private int fOffset= -1;
+        /** End offset of iteration. */
+        private int fEndOffset= -1;
+        /** Current offset of iteration. */
+        private int fIndex= -1;
+
+        /** Creates a new document iterator. */
+        public this() {
+        }
+
+        /**
+         * Configures this document iterator with the document section to be visited.
+         *
+         * @param document the document to be iterated
+         * @param iteratorRange the range in the document to be iterated
+         */
+        public void setDocument(IDocument document, IRegion iteratorRange) {
+            fDocument= document;
+            fOffset= iteratorRange.getOffset();
+            fEndOffset= fOffset + iteratorRange.getLength();
+        }
+
+        /*
+         * @see CharacterIterator#first()
+         */
+        public char first() {
+            fIndex= fOffset;
+            return current();
+        }
+
+        /*
+         * @see CharacterIterator#last()
+         */
+        public char last() {
+            fIndex= fOffset < fEndOffset ? fEndOffset -1 : fEndOffset;
+            return current();
+        }
+
+        /*
+         * @see CharacterIterator#current()
+         */
+        public char current() {
+            if (fOffset <= fIndex && fIndex < fEndOffset) {
+                try {
+                    return fDocument.getChar(fIndex);
+                } catch (BadLocationException x) {
+                }
+            }
+            return DONE;
+        }
+
+        /*
+         * @see CharacterIterator#next()
+         */
+        public char next() {
+            ++fIndex;
+            int end= getEndIndex();
+            if (fIndex >= end) {
+                fIndex= end;
+                return DONE;
+            }
+            return current();
+        }
+
+        /*
+         * @see CharacterIterator#previous()
+         */
+        public char previous() {
+            if (fIndex is fOffset)
+                return DONE;
+
+            if (fIndex > fOffset)
+                -- fIndex;
+
+            return current();
+        }
+
+        /*
+         * @see CharacterIterator#setIndex(int)
+         */
+        public char setIndex(int index) {
+            fIndex= index;
+            return current();
+        }
+
+        /*
+         * @see CharacterIterator#getBeginIndex()
+         */
+        public int getBeginIndex() {
+            return fOffset;
+        }
+
+        /*
+         * @see CharacterIterator#getEndIndex()
+         */
+        public int getEndIndex() {
+            return fEndOffset;
+        }
+
+        /*
+         * @see CharacterIterator#getIndex()
+         */
+        public int getIndex() {
+            return fIndex;
+        }
+
+        /*
+         * @see CharacterIterator#clone()
+         */
+        public Object clone() {
+            DocumentCharacterIterator i= new DocumentCharacterIterator();
+            i.fDocument= fDocument;
+            i.fIndex= fIndex;
+            i.fOffset= fOffset;
+            i.fEndOffset= fEndOffset;
+            return i;
+        }
+    }
+
+
+    /**
+     * The document character iterator used by this strategy.
+     * @since 2.0
+     */
+    private DocumentCharacterIterator fDocIter= new DocumentCharacterIterator();
+
+
+    /**
+     * Creates a new default text double click strategy.
+     */
+    public this() {
+//         super();
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextDoubleClickStrategy#doubleClicked(dwtx.jface.text.ITextViewer)
+     */
+    public void doubleClicked(ITextViewer text) {
+
+        int position= text.getSelectedRange().x;
+
+        if (position < 0)
+            return;
+
+        try {
+
+            IDocument document= text.getDocument();
+            IRegion line= document.getLineInformationOfOffset(position);
+            if (position is line.getOffset() + line.getLength())
+                return;
+
+            fDocIter.setDocument(document, line);
+
+            UBreakIterator breakIter= UBreakIterator.openWordIterator( ULocale.Default, fDocIter );
+
+            int start= breakIter.preceding(position);
+            if (start is UBreakIterator.DONE)
+                start= line.getOffset();
+
+            int end= breakIter.following(position);
+            if (end is UBreakIterator.DONE)
+                end= line.getOffset() + line.getLength();
+
+            if (breakIter.isBoundary(position)) {
+                if (end - position > position- start)
+                    start= position;
+                else
+                    end= position;
+            }
+
+            if (start !is end)
+                text.setSelectedRange(start, end - start);
+
+        } catch (BadLocationException x) {
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DefaultTextHover.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,283 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.DefaultTextHover;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.source.Annotation;
+import dwtx.jface.text.source.IAnnotationModel;
+import dwtx.jface.text.source.ISourceViewer;
+import dwtx.jface.text.source.ISourceViewerExtension2;
+
+/**
+ * Standard implementation of {@link dwtx.jface.text.ITextHover}.
+ *
+ * @since 3.2
+ */
+public class DefaultTextHover : ITextHover {
+
+    /** This hover's source viewer */
+    private ISourceViewer fSourceViewer;
+
+    /**
+     * Creates a new annotation hover.
+     *
+     * @param sourceViewer this hover's annotation model
+     */
+    public this(ISourceViewer sourceViewer)  {
+        dwtx.core.runtime.Assert.Assert.isNotNull(cast(Object)sourceViewer);
+        fSourceViewer= sourceViewer;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextHover#getHoverInfo(dwtx.jface.text.ITextViewer, dwtx.jface.text.IRegion)
+     */
+    public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+        IAnnotationModel model= getAnnotationModel(fSourceViewer);
+        if (model is null)
+            return null;
+
+        Iterator e= model.getAnnotationIterator();
+        while (e.hasNext()) {
+            Annotation a= cast(Annotation) e.next();
+            if (isIncluded(a)) {
+                Position p= model.getPosition(a);
+                if (p !is null && p.overlapsWith(hoverRegion.getOffset(), hoverRegion.getLength())) {
+                    String msg= a.getText();
+                    if (msg !is null && msg.trim().length() > 0)
+                        return msg;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextHover#getHoverRegion(dwtx.jface.text.ITextViewer, int)
+     */
+    public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+        return findWord(textViewer.getDocument(), offset);
+    }
+
+    /**
+     * Tells whether the annotation should be included in
+     * the computation.
+     *
+     * @param annotation the annotation to test
+     * @return <code>true</code> if the annotation is included in the computation
+     */
+    protected bool isIncluded(Annotation annotation) {
+        return true;
+    }
+
+    private IAnnotationModel getAnnotationModel(ISourceViewer viewer) {
+        if (cast(ISourceViewerExtension2)viewer ) {
+            ISourceViewerExtension2 extension= cast(ISourceViewerExtension2) viewer;
+            return extension.getVisualAnnotationModel();
+        }
+        return viewer.getAnnotationModel();
+    }
+
+    private IRegion findWord(IDocument document, int offset) {
+        int start= -2;
+        int end= -1;
+
+implMissing(__FILE__,__LINE__);
+// DWT FIXME: unicode
+/+
+        try {
+            int pos= offset;
+            wchar c;
+
+            while (pos >= 0) {
+                c= document.getChar(pos);
+                if (!Character.isUnicodeIdentifierPart(c))
+                    break;
+                --pos;
+            }
+
+            start= pos;
+
+            pos= offset;
+            int length= document.getLength();
+
+            while (pos < length) {
+                c= document.getChar(pos);
+                if (!Character.isUnicodeIdentifierPart(c))
+                    break;
+                ++pos;
+            }
+
+            end= pos;
+
+        } catch (BadLocationException x) {
+        }
+
+        if (start >= -1 && end > -1) {
+            if (start is offset && end is offset)
+                return new Region(offset, 0);
+            else if (start is offset)
+                return new Region(start, end - start);
+            else
+                return new Region(start + 1, end - start - 1);
+        }
++/
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DefaultUndoManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1482 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.DefaultUndoManager;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.widgets.Event;
+import dwt.widgets.Display;
+import dwt.widgets.Shell;
+import dwtx.core.commands.ExecutionException;
+import dwtx.core.commands.operations.AbstractOperation;
+import dwtx.core.commands.operations.IOperationHistory;
+import dwtx.core.commands.operations.IOperationHistoryListener;
+import dwtx.core.commands.operations.IUndoContext;
+import dwtx.core.commands.operations.IUndoableOperation;
+import dwtx.core.commands.operations.ObjectUndoContext;
+import dwtx.core.commands.operations.OperationHistoryEvent;
+import dwtx.core.commands.operations.OperationHistoryFactory;
+import dwtx.core.runtime.IAdaptable;
+import dwtx.core.runtime.IProgressMonitor;
+import dwtx.core.runtime.IStatus;
+import dwtx.core.runtime.Status;
+import dwtx.jface.dialogs.MessageDialog;
+
+
+/**
+ * Standard implementation of {@link dwtx.jface.text.IUndoManager}.
+ * <p>
+ * It registers with the connected text viewer as text input listener and
+ * document listener and logs all changes. It also monitors mouse and keyboard
+ * activities in order to partition the stream of text changes into undo-able
+ * edit commands.
+ * </p>
+ * <p>
+ * Since 3.1 this undo manager is a facade to the global operation history.
+ * </p>
+ * <p>
+ * The usage of {@link dwtx.core.runtime.IAdaptable} in the JFace
+ * layer has been approved by Platform UI, see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=87669#c9
+ * </p>
+ * <p>
+ * This class is not intended to be subclassed.
+ * </p>
+ *
+ * @see dwtx.jface.text.ITextViewer
+ * @see dwtx.jface.text.ITextInputListener
+ * @see dwtx.jface.text.IDocumentListener
+ * @see dwtx.core.commands.operations.IUndoableOperation
+ * @see dwtx.core.commands.operations.IOperationHistory
+ * @see MouseListener
+ * @see KeyListener
+ * @deprecated As of 3.2, replaced by {@link TextViewerUndoManager}
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class DefaultUndoManager : IUndoManager, IUndoManagerExtension {
+
+    /**
+     * Represents an undo-able edit command.
+     * <p>
+     * Since 3.1 this implements the interface for IUndoableOperation.
+     * </p>
+     */
+    class TextCommand : AbstractOperation {
+
+        /** The start index of the replaced text. */
+        protected int fStart= -1;
+        /** The end index of the replaced text. */
+        protected int fEnd= -1;
+        /** The newly inserted text. */
+        protected String fText;
+        /** The replaced text. */
+        protected String fPreservedText;
+
+        /** The undo modification stamp. */
+        protected long fUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+        /** The redo modification stamp. */
+        protected long fRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+
+        /**
+         * Creates a new text command.
+         *
+         * @param context the undo context for this command
+         * @since 3.1
+         */
+        this(IUndoContext context) {
+            super(JFaceTextMessages.getString("DefaultUndoManager.operationLabel")); //$NON-NLS-1$
+            addContext(context);
+        }
+
+        /**
+         * Re-initializes this text command.
+         */
+        protected void reinitialize() {
+            fStart= fEnd= -1;
+            fText= fPreservedText= null;
+            fUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+            fRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+        }
+
+        /**
+         * Sets the start and the end index of this command.
+         *
+         * @param start the start index
+         * @param end the end index
+         */
+        protected void set(int start, int end) {
+            fStart= start;
+            fEnd= end;
+            fText= null;
+            fPreservedText= null;
+        }
+
+        /*
+         * @see dwtx.core.commands.operations.IUndoableOperation#dispose()
+         * @since 3.1
+         */
+        public void dispose() {
+            reinitialize();
+        }
+
+        /**
+         * Undo the change described by this command.
+         *
+         * @since 2.0
+         */
+        protected void undoTextChange() {
+            try {
+                IDocument document= fTextViewer.getDocument();
+                if ( cast(IDocumentExtension4)document )
+                    (cast(IDocumentExtension4)document).replace(fStart, fText.length(), fPreservedText, fUndoModificationStamp);
+                else
+                    document.replace(fStart, fText.length(), fPreservedText);
+            } catch (BadLocationException x) {
+            }
+        }
+
+        /*
+         * @see dwtx.core.commands.operations.IUndoableOperation#canUndo()
+         * @since 3.1
+         */
+        public bool canUndo() {
+
+            if (isConnected() && isValid()) {
+                IDocument doc= fTextViewer.getDocument();
+                if ( cast(IDocumentExtension4)doc ) {
+                    long docStamp= (cast(IDocumentExtension4)doc).getModificationStamp();
+
+                    // Normal case: an undo is valid if its redo will restore document
+                    // to its current modification stamp
+                    bool canUndo= docStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP ||
+                        docStamp is getRedoModificationStamp();
+
+                    /* Special case to check if the answer is false.
+                     * If the last document change was empty, then the document's
+                     * modification stamp was incremented but nothing was committed.
+                     * The operation being queried has an older stamp.  In this case only,
+                     * the comparison is different.  A sequence of document changes that
+                     * include an empty change is handled correctly when a valid commit
+                     * follows the empty change, but when #canUndo() is queried just after
+                     * an empty change, we must special case the check.  The check is very
+                     * specific to prevent false positives.
+                     * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=98245
+                     */
+                    if (!canUndo &&
+                            this is fHistory.getUndoOperation(fUndoContext)  &&  // this is the latest operation
+                            this !is fCurrent && // there is a more current operation not on the stack
+                            !fCurrent.isValid() &&  // the current operation is not a valid document modification
+                            fCurrent.fUndoModificationStamp !is // the invalid current operation has a document stamp
+                                IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) {
+                        canUndo= fCurrent.fRedoModificationStamp is docStamp;
+                    }
+                    /*
+                     * When the composite is the current command, it may hold the timestamp
+                     * of a no-op change.  We check this here rather than in an override of
+                     * canUndo() in CompoundTextCommand simply to keep all the special case checks
+                     * in one place.
+                     */
+                    if (!canUndo &&
+                            this is fHistory.getUndoOperation(fUndoContext)  &&  // this is the latest operation
+                            null !is cast(CompoundTextCommand)this &&
+                            this is fCurrent && // this is the current operation
+                            this.fStart is -1 &&  // the current operation text is not valid
+                            fCurrent.fRedoModificationStamp !is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) {  // but it has a redo stamp
+                        canUndo= fCurrent.fRedoModificationStamp is docStamp;
+                    }
+
+                }
+                // if there is no timestamp to check, simply return true per the 3.0.1 behavior
+                return true;
+            }
+            return false;
+        }
+
+        /*
+         * @see dwtx.core.commands.operations.IUndoableOperation#canRedo()
+         * @since 3.1
+         */
+        public bool canRedo() {
+            if (isConnected() && isValid()) {
+                IDocument doc= fTextViewer.getDocument();
+                if ( cast(IDocumentExtension4)doc ) {
+                    long docStamp= (cast(IDocumentExtension4)doc).getModificationStamp();
+                    return docStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP ||
+                        docStamp is getUndoModificationStamp();
+                }
+                // if there is no timestamp to check, simply return true per the 3.0.1 behavior
+                return true;
+            }
+            return false;
+        }
+
+        /*
+         * @see dwtx.core.commands.operations.IUndoableOperation#canExecute()
+         * @since 3.1
+         */
+        public bool canExecute() {
+            return isConnected();
+        }
+
+        /*
+         * @see dwtx.core.commands.operations.IUndoableOperation#execute(dwtx.core.runtime.IProgressMonitor, dwtx.core.runtime.IAdaptable)
+         * @since 3.1
+         */
+        public IStatus execute(IProgressMonitor monitor, IAdaptable uiInfo) {
+            // Text commands execute as they are typed, so executing one has no effect.
+            return Status.OK_STATUS;
+        }
+
+        /*
+         * Undo the change described by this command. Also selects and
+         * reveals the change.
+         */
+
+        /**
+         * Undo the change described by this command. Also selects and
+         * reveals the change.
+         *
+         * @param monitor   the progress monitor to use if necessary
+         * @param uiInfo    an adaptable that can provide UI info if needed
+         * @return the status
+         */
+        public IStatus undo(IProgressMonitor monitor, IAdaptable uiInfo) {
+            if (isValid()) {
+                undoTextChange();
+                selectAndReveal(fStart, fPreservedText is null ? 0 : fPreservedText.length());
+                resetProcessChangeSate();
+                return Status.OK_STATUS;
+            }
+            return IOperationHistory.OPERATION_INVALID_STATUS;
+        }
+
+        /**
+         * Re-applies the change described by this command.
+         *
+         * @since 2.0
+         */
+        protected void redoTextChange() {
+            try {
+                IDocument document= fTextViewer.getDocument();
+                if ( cast(IDocumentExtension4)document )
+                    (cast(IDocumentExtension4)document).replace(fStart, fEnd - fStart, fText, fRedoModificationStamp);
+                else
+                    fTextViewer.getDocument().replace(fStart, fEnd - fStart, fText);
+            } catch (BadLocationException x) {
+            }
+        }
+
+        /**
+         * Re-applies the change described by this command that previously been
+         * rolled back. Also selects and reveals the change.
+         *
+         * @param monitor   the progress monitor to use if necessary
+         * @param uiInfo    an adaptable that can provide UI info if needed
+         * @return the status
+         */
+        public IStatus redo(IProgressMonitor monitor, IAdaptable uiInfo) {
+            if (isValid()) {
+                redoTextChange();
+                resetProcessChangeSate();
+                selectAndReveal(fStart, fText is null ? 0 : fText.length());
+                return Status.OK_STATUS;
+            }
+            return IOperationHistory.OPERATION_INVALID_STATUS;
+        }
+
+        /**
+         * Update the command in response to a commit.
+         *
+         * @since 3.1
+         */
+
+        protected void updateCommand() {
+            fText= fTextBuffer.toString();
+            fTextBuffer.truncate(0);
+            fPreservedText= fPreservedTextBuffer.toString();
+            fPreservedTextBuffer.truncate(0);
+        }
+
+        /**
+         * Creates a new uncommitted text command depending on whether
+         * a compound change is currently being executed.
+         *
+         * @return a new, uncommitted text command or a compound text command
+         */
+        protected TextCommand createCurrent() {
+            return fFoldingIntoCompoundChange ? new CompoundTextCommand(fUndoContext) : new TextCommand(fUndoContext);
+        }
+
+        /**
+         * Commits the current change into this command.
+         */
+        protected void commit() {
+            if (fStart < 0) {
+                if (fFoldingIntoCompoundChange) {
+                    fCurrent= createCurrent();
+                } else {
+                    reinitialize();
+                }
+            } else {
+                updateCommand();
+                fCurrent= createCurrent();
+            }
+            resetProcessChangeSate();
+        }
+
+        /**
+         * Updates the text from the buffers without resetting
+         * the buffers or adding anything to the stack.
+         *
+         * @since 3.1
+         */
+        protected void pretendCommit() {
+            if (fStart > -1) {
+                fText= fTextBuffer.toString();
+                fPreservedText= fPreservedTextBuffer.toString();
+            }
+        }
+
+        /**
+         * Attempt a commit of this command and answer true if a new
+         * fCurrent was created as a result of the commit.
+         *
+         * @return true if the command was committed and created a
+         * new fCurrent, false if not.
+         * @since 3.1
+         */
+        protected bool attemptCommit() {
+            pretendCommit();
+            if (isValid()) {
+                this.outer.commit();
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Checks whether this text command is valid for undo or redo.
+         *
+         * @return <code>true</code> if the command is valid for undo or redo
+         * @since 3.1
+         */
+        protected bool isValid() {
+            return fStart > -1 &&
+                fEnd > -1 &&
+                fText !is null;
+        }
+
+        /*
+         * @see java.lang.Object#toString()
+         * @since 3.1
+         */
+        public override String toString() {
+            String delimiter= ", "; //$NON-NLS-1$
+            StringBuffer text= new StringBuffer(super.toString());
+            text.append("\n"); //$NON-NLS-1$
+            text.append(this.classinfo.name);
+            text.append(" undo modification stamp: "); //$NON-NLS-1$
+            text.append(fUndoModificationStamp);
+            text.append(" redo modification stamp: "); //$NON-NLS-1$
+            text.append(fRedoModificationStamp);
+            text.append(" start: "); //$NON-NLS-1$
+            text.append(fStart);
+            text.append(delimiter);
+            text.append("end: "); //$NON-NLS-1$
+            text.append(fEnd);
+            text.append(delimiter);
+            text.append("text: '"); //$NON-NLS-1$
+            text.append(fText);
+            text.append('\'');
+            text.append(delimiter);
+            text.append("preservedText: '"); //$NON-NLS-1$
+            text.append(fPreservedText);
+            text.append('\'');
+            return text.toString();
+        }
+
+        /**
+         * Return the undo modification stamp
+         *
+         * @return the undo modification stamp for this command
+         * @since 3.1
+         */
+        protected long getUndoModificationStamp() {
+            return fUndoModificationStamp;
+        }
+
+        /**
+         * Return the redo modification stamp
+         *
+         * @return the redo modification stamp for this command
+         * @since 3.1
+         */
+        protected long getRedoModificationStamp() {
+            return fRedoModificationStamp;
+        }
+    }
+
+    /**
+     * Represents an undo-able edit command consisting of several
+     * individual edit commands.
+     */
+    class CompoundTextCommand : TextCommand {
+
+        /** The list of individual commands */
+        private List fCommands;
+
+        /**
+         * Creates a new compound text command.
+         *
+         * @param context the undo context for this command
+         * @since 3.1
+         */
+        this(IUndoContext context) {
+            super(context);
+            fCommands= new ArrayList();
+        }
+
+        /**
+         * Adds a new individual command to this compound command.
+         *
+         * @param command the command to be added
+         */
+        protected void add(TextCommand command) {
+            fCommands.add(command);
+        }
+
+        /*
+         * @see dwtx.jface.text.DefaultUndoManager.TextCommand#undo()
+         */
+        public IStatus undo(IProgressMonitor monitor, IAdaptable uiInfo) {
+            resetProcessChangeSate();
+
+            int size= fCommands.size();
+            if (size > 0) {
+
+                TextCommand c;
+
+                for (int i= size -1; i > 0;  --i) {
+                    c= cast(TextCommand) fCommands.get(i);
+                    c.undoTextChange();
+                }
+
+                c= cast(TextCommand) fCommands.get(0);
+                c.undo(monitor, uiInfo);
+            }
+
+            return Status.OK_STATUS;
+        }
+
+        /*
+         * @see dwtx.jface.text.DefaultUndoManager.TextCommand#redo()
+         */
+        public IStatus redo(IProgressMonitor monitor, IAdaptable uiInfo) {
+            resetProcessChangeSate();
+
+            int size= fCommands.size();
+            if (size > 0) {
+
+                TextCommand c;
+
+                for (int i= 0; i < size -1;  ++i) {
+                    c= cast(TextCommand) fCommands.get(i);
+                    c.redoTextChange();
+                }
+
+                c= cast(TextCommand) fCommands.get(size -1);
+                c.redo(monitor, uiInfo);
+            }
+            return Status.OK_STATUS;
+        }
+
+        /*
+         * @see TextCommand#updateCommand
+
+         */
+
+        protected void updateCommand() {
+            // first gather the data from the buffers
+            super.updateCommand();
+
+            // the result of the command update is stored as a child command
+            TextCommand c= new TextCommand(fUndoContext);
+            c.fStart= fStart;
+            c.fEnd= fEnd;
+            c.fText= fText;
+            c.fPreservedText= fPreservedText;
+            c.fUndoModificationStamp= fUndoModificationStamp;
+            c.fRedoModificationStamp= fRedoModificationStamp;
+            add(c);
+
+            // clear out all indexes now that the child is added
+            reinitialize();
+        }
+
+        /*
+         * @see TextCommand#createCurrent
+         */
+        protected TextCommand createCurrent() {
+
+            if (!fFoldingIntoCompoundChange)
+                return new TextCommand(fUndoContext);
+
+            reinitialize();
+            return this;
+        }
+
+        /*
+         * @see dwtx.jface.text.DefaultUndoManager.TextCommand#commit()
+         */
+        protected void commit() {
+            // if there is pending data, update the command
+            if (fStart > -1)
+                updateCommand();
+            fCurrent= createCurrent();
+            resetProcessChangeSate();
+        }
+
+        /**
+         * Checks whether the command is valid for undo or redo.
+         *
+         * @return true if the command is valid.
+         * @since 3.1
+         */
+        protected bool isValid() {
+            if (isConnected())
+                return (fStart > -1 || fCommands.size() > 0);
+            return false;
+        }
+
+        /**
+         * Returns the undo modification stamp.
+         *
+         * @return the undo modification stamp
+         * @since 3.1
+         */
+        protected long getUndoModificationStamp() {
+            if (fStart > -1)
+                return super.getUndoModificationStamp();
+            else if (fCommands.size() > 0)
+                return (cast(TextCommand)fCommands.get(0)).getUndoModificationStamp();
+
+            return fUndoModificationStamp;
+        }
+
+        /**
+         * Returns the redo modification stamp.
+         *
+         * @return the redo modification stamp
+         * @since 3.1
+         */
+        protected long getRedoModificationStamp() {
+            if (fStart > -1)
+                return super.getRedoModificationStamp();
+            else if (fCommands.size() > 0)
+                return (cast(TextCommand)fCommands.get(fCommands.size()-1)).getRedoModificationStamp();
+
+            return fRedoModificationStamp;
+        }
+    }
+
+    /**
+     * Internal listener to mouse and key events.
+     */
+    class KeyAndMouseListener : MouseListener, KeyListener {
+
+        /*
+         * @see MouseListener#mouseDoubleClick
+         */
+        public void mouseDoubleClick(MouseEvent e) {
+        }
+
+        /*
+         * If the right mouse button is pressed, the current editing command is closed
+         * @see MouseListener#mouseDown
+         */
+        public void mouseDown(MouseEvent e) {
+            if (e.button is 1)
+                commit();
+        }
+
+        /*
+         * @see MouseListener#mouseUp
+         */
+        public void mouseUp(MouseEvent e) {
+        }
+
+        /*
+         * @see KeyListener#keyPressed
+         */
+        public void keyReleased(KeyEvent e) {
+        }
+
+        /*
+         * On cursor keys, the current editing command is closed
+         * @see KeyListener#keyPressed
+         */
+        public void keyPressed(KeyEvent e) {
+            switch (e.keyCode) {
+                case DWT.ARROW_UP:
+                case DWT.ARROW_DOWN:
+                case DWT.ARROW_LEFT:
+                case DWT.ARROW_RIGHT:
+                    commit();
+                    break;
+            }
+        }
+    }
+
+    /**
+     * Internal listener to document changes.
+     */
+    class DocumentListener : IDocumentListener {
+
+        private String fReplacedText;
+
+        /*
+         * @see dwtx.jface.text.IDocumentListener#documentAboutToBeChanged(dwtx.jface.text.DocumentEvent)
+         */
+        public void documentAboutToBeChanged(DocumentEvent event) {
+            try {
+                fReplacedText= event.getDocument().get(event.getOffset(), event.getLength());
+                fPreservedUndoModificationStamp= event.getModificationStamp();
+            } catch (BadLocationException x) {
+                fReplacedText= null;
+            }
+        }
+
+        /*
+         * @see dwtx.jface.text.IDocumentListener#documentChanged(dwtx.jface.text.DocumentEvent)
+         */
+        public void documentChanged(DocumentEvent event) {
+            fPreservedRedoModificationStamp= event.getModificationStamp();
+
+            // record the current valid state for the top operation in case it remains the
+            // top operation but changes state.
+            IUndoableOperation op= fHistory.getUndoOperation(fUndoContext);
+            bool wasValid= false;
+            if (op !is null)
+                wasValid= op.canUndo();
+            // Process the change, providing the before and after timestamps
+            processChange(event.getOffset(), event.getOffset() + event.getLength(), event.getText(), fReplacedText, fPreservedUndoModificationStamp, fPreservedRedoModificationStamp);
+
+            // now update fCurrent with the latest buffers from the document change.
+            fCurrent.pretendCommit();
+
+            if (op is fCurrent) {
+                // if the document change did not cause a new fCurrent to be created, then we should
+                // notify the history that the current operation changed if its validity has changed.
+                if (wasValid !is fCurrent.isValid())
+                    fHistory.operationChanged(op);
+            }
+            else {
+                // if the change created a new fCurrent that we did not yet add to the
+                // stack, do so if it's valid and we are not in the middle of a compound change.
+                if (fCurrent !is fLastAddedCommand && fCurrent.isValid()) {
+                    addToCommandStack(fCurrent);
+                }
+            }
+        }
+    }
+
+    /**
+     * Internal text input listener.
+     */
+    class TextInputListener : ITextInputListener {
+
+        /*
+         * @see dwtx.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument)
+         */
+        public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
+            if (oldInput !is null && fDocumentListener !is null) {
+                oldInput.removeDocumentListener(fDocumentListener);
+                commit();
+            }
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextInputListener#inputDocumentChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument)
+         */
+        public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+            if (newInput !is null) {
+                if (fDocumentListener is null)
+                    fDocumentListener= new DocumentListener();
+                newInput.addDocumentListener(fDocumentListener);
+            }
+        }
+
+    }
+
+    /*
+     * @see IOperationHistoryListener
+     * @since 3.1
+     */
+    class HistoryListener : IOperationHistoryListener {
+        private IUndoableOperation fOperation;
+
+        public void historyNotification(OperationHistoryEvent event) {
+            int type= event.getEventType();
+            switch (type) {
+            case OperationHistoryEvent.ABOUT_TO_UNDO:
+            case OperationHistoryEvent.ABOUT_TO_REDO:
+                // if this is one of our operations
+                if (event.getOperation().hasContext(fUndoContext)) {
+                    fTextViewer.getTextWidget().getDisplay().syncExec(dgRunnable((OperationHistoryEvent event_, int type_ ) {
+                        // if we are undoing/redoing a command we generated, then ignore
+                        // the document changes associated with this undo or redo.
+                        if (event_.getOperation() ) {
+                            if ( cast(TextViewer)fTextViewer )
+                                (cast(TextViewer)fTextViewer).ignoreAutoEditStrategies_package(true);
+                            listenToTextChanges(false);
+
+                            // in the undo case only, make sure compounds are closed
+                            if (type_ is OperationHistoryEvent.ABOUT_TO_UNDO) {
+                                if (fFoldingIntoCompoundChange) {
+                                    endCompoundChange();
+                                }
+                            }
+                        } else {
+                            // the undo or redo has our context, but it is not one of
+                            // our commands.  We will listen to the changes, but will
+                            // reset the state that tracks the undo/redo history.
+                            commit();
+                            fLastAddedCommand= null;
+                        }
+                    }, event, type ));
+                    fOperation= event.getOperation();
+                }
+                break;
+            case OperationHistoryEvent.UNDONE:
+            case OperationHistoryEvent.REDONE:
+            case OperationHistoryEvent.OPERATION_NOT_OK:
+                if (event.getOperation() is fOperation) {
+                    fTextViewer.getTextWidget().getDisplay().syncExec(new class()  Runnable {
+                        public void run() {
+                            listenToTextChanges(true);
+                            fOperation= null;
+                            if ( cast(TextViewer)fTextViewer )
+                                (cast(TextViewer)fTextViewer).ignoreAutoEditStrategies_package(false);
+                         }
+                    });
+                }
+                break;
+            }
+        }
+
+    }
+
+    /** Text buffer to collect text which is inserted into the viewer */
+    private StringBuffer fTextBuffer;
+    /** Text buffer to collect viewer content which has been replaced */
+    private StringBuffer fPreservedTextBuffer;
+    /** The document modification stamp for undo. */
+    protected long fPreservedUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+    /** The document modification stamp for redo. */
+    protected long fPreservedRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+    /** The internal key and mouse event listener */
+    private KeyAndMouseListener fKeyAndMouseListener;
+    /** The internal document listener */
+    private DocumentListener fDocumentListener;
+    /** The internal text input listener */
+    private TextInputListener fTextInputListener;
+
+
+    /** Indicates inserting state */
+    private bool fInserting= false;
+    /** Indicates overwriting state */
+    private bool fOverwriting= false;
+    /** Indicates whether the current change belongs to a compound change */
+    private bool fFoldingIntoCompoundChange= false;
+
+    /** The text viewer the undo manager is connected to */
+    private ITextViewer fTextViewer;
+
+    /** Supported undo level */
+    private int fUndoLevel;
+    /** The currently constructed edit command */
+    private TextCommand fCurrent;
+    /** The last delete edit command */
+    private TextCommand fPreviousDelete;
+
+    /**
+     * The undo context.
+     * @since 3.1
+     */
+    private IOperationHistory fHistory;
+    /**
+     * The operation history.
+     * @since 3.1
+     */
+    private IUndoContext fUndoContext;
+    /**
+     * The operation history listener used for managing undo and redo before
+     * and after the individual commands are performed.
+     * @since 3.1
+     */
+    private IOperationHistoryListener fHistoryListener;
+
+    /**
+     * The command last added to the operation history.  This must be tracked
+     * internally instead of asking the history, since outside parties may be placing
+     * items on our undo/redo history.
+     */
+    private TextCommand fLastAddedCommand= null;
+
+    /**
+     * Creates a new undo manager who remembers the specified number of edit commands.
+     *
+     * @param undoLevel the length of this manager's history
+     */
+    public this(int undoLevel) {
+        fTextBuffer= new StringBuffer();
+        fPreservedTextBuffer= new StringBuffer();
+
+        fHistoryListener= new HistoryListener();
+        fHistory= OperationHistoryFactory.getOperationHistory();
+        setMaximalUndoLevel(undoLevel);
+    }
+
+    /**
+     * Returns whether this undo manager is connected to a text viewer.
+     *
+     * @return <code>true</code> if connected, <code>false</code> otherwise
+     * @since 3.1
+     */
+    private bool isConnected() {
+        return fTextViewer !is null;
+    }
+
+    /*
+     * @see IUndoManager#beginCompoundChange
+     */
+    public void beginCompoundChange() {
+        if (isConnected()) {
+            fFoldingIntoCompoundChange= true;
+            commit();
+        }
+    }
+
+
+    /*
+     * @see IUndoManager#endCompoundChange
+     */
+    public void endCompoundChange() {
+        if (isConnected()) {
+            fFoldingIntoCompoundChange= false;
+            commit();
+        }
+    }
+
+    /**
+     * Registers all necessary listeners with the text viewer.
+     */
+    private void addListeners() {
+        StyledText text= fTextViewer.getTextWidget();
+        if (text !is null) {
+            fKeyAndMouseListener= new KeyAndMouseListener();
+            text.addMouseListener(fKeyAndMouseListener);
+            text.addKeyListener(fKeyAndMouseListener);
+            fTextInputListener= new TextInputListener();
+            fTextViewer.addTextInputListener(fTextInputListener);
+            fHistory.addOperationHistoryListener(fHistoryListener);
+            listenToTextChanges(true);
+        }
+    }
+
+    /**
+     * Unregister all previously installed listeners from the text viewer.
+     */
+    private void removeListeners() {
+        StyledText text= fTextViewer.getTextWidget();
+        if (text !is null) {
+            if (fKeyAndMouseListener !is null) {
+                text.removeMouseListener(fKeyAndMouseListener);
+                text.removeKeyListener(fKeyAndMouseListener);
+                fKeyAndMouseListener= null;
+            }
+            if (fTextInputListener !is null) {
+                fTextViewer.removeTextInputListener(fTextInputListener);
+                fTextInputListener= null;
+            }
+            listenToTextChanges(false);
+            fHistory.removeOperationHistoryListener(fHistoryListener);
+        }
+    }
+
+    /**
+     * Adds the given command to the operation history if it is not part of
+     * a compound change.
+     *
+     * @param command the command to be added
+     * @since 3.1
+     */
+    private void addToCommandStack(TextCommand command){
+        if (!fFoldingIntoCompoundChange || cast(CompoundTextCommand)command ) {
+            fHistory.add(command);
+            fLastAddedCommand= command;
+        }
+    }
+
+    /**
+     * Disposes the command stack.
+     *
+     * @since 3.1
+     */
+    private void disposeCommandStack() {
+        fHistory.dispose(fUndoContext, true, true, true);
+    }
+
+    /**
+     * Initializes the command stack.
+     *
+     * @since 3.1
+     */
+    private void initializeCommandStack() {
+        if (fHistory !is null && fUndoContext !is null)
+            fHistory.dispose(fUndoContext, true, true, false);
+
+    }
+
+    /**
+     * Switches the state of whether there is a text listener or not.
+     *
+     * @param listen the state which should be established
+     */
+    private void listenToTextChanges(bool listen) {
+        if (listen) {
+            if (fDocumentListener is null && fTextViewer.getDocument() !is null) {
+                fDocumentListener= new DocumentListener();
+                fTextViewer.getDocument().addDocumentListener(fDocumentListener);
+            }
+        } else if (!listen) {
+            if (fDocumentListener !is null && fTextViewer.getDocument() !is null) {
+                fTextViewer.getDocument().removeDocumentListener(fDocumentListener);
+                fDocumentListener= null;
+            }
+        }
+    }
+
+    /**
+     * Closes the current editing command and opens a new one.
+     */
+    private void commit() {
+        // if fCurrent has never been placed on the command stack, do so now.
+        // this can happen when there are multiple programmatically commits in a single
+        // document change.
+        if (fLastAddedCommand !is fCurrent) {
+            fCurrent.pretendCommit();
+            if (fCurrent.isValid())
+                addToCommandStack(fCurrent);
+        }
+        fCurrent.commit();
+    }
+
+    /**
+     * Reset processChange state.
+     *
+     * @since 3.2
+     */
+    private void resetProcessChangeSate() {
+        fInserting= false;
+        fOverwriting= false;
+        fPreviousDelete.reinitialize();
+    }
+
+    /**
+     * Checks whether the given text starts with a line delimiter and
+     * subsequently contains a white space only.
+     *
+     * @param text the text to check
+     * @return <code>true</code> if the text is a line delimiter followed by whitespace, <code>false</code> otherwise
+     */
+    private bool isWhitespaceText(String text) {
+
+        if (text is null || text.length() is 0)
+            return false;
+
+        String[] delimiters= fTextViewer.getDocument().getLegalLineDelimiters();
+        int index= TextUtilities.startsWith(delimiters, text);
+        if (index > -1) {
+            char c;
+            int length= text.length();
+            for (int i= delimiters[index].length; i < length; i++) {
+                c= text.charAt(i);
+                if (c !is ' ' && c !is '\t')
+                    return false;
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    private void processChange(int modelStart, int modelEnd, String insertedText, String replacedText, long beforeChangeModificationStamp, long afterChangeModificationStamp) {
+
+        if (insertedText is null)
+            insertedText= ""; //$NON-NLS-1$
+
+        if (replacedText is null)
+            replacedText= ""; //$NON-NLS-1$
+
+        int length= insertedText.length();
+        int diff= modelEnd - modelStart;
+
+        if (fCurrent.fUndoModificationStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP)
+            fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+        // normalize
+        if (diff < 0) {
+            int tmp= modelEnd;
+            modelEnd= modelStart;
+            modelStart= tmp;
+        }
+
+        if (modelStart is modelEnd) {
+            // text will be inserted
+            if ((length is 1) || isWhitespaceText(insertedText)) {
+                // by typing or whitespace
+                if (!fInserting || (modelStart !is fCurrent.fStart + fTextBuffer.length())) {
+                    fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
+                    if (fCurrent.attemptCommit())
+                        fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+                    fInserting= true;
+                }
+                if (fCurrent.fStart < 0)
+                    fCurrent.fStart= fCurrent.fEnd= modelStart;
+                if (length > 0)
+                    fTextBuffer.append(insertedText);
+            } else if (length >= 0) {
+                // by pasting or model manipulation
+                fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
+                if (fCurrent.attemptCommit())
+                    fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+                fCurrent.fStart= fCurrent.fEnd= modelStart;
+                fTextBuffer.append(insertedText);
+                fCurrent.fRedoModificationStamp= afterChangeModificationStamp;
+                if (fCurrent.attemptCommit())
+                    fCurrent.fUndoModificationStamp= afterChangeModificationStamp;
+
+            }
+        } else {
+            if (length is 0) {
+                // text will be deleted by backspace or DEL key or empty clipboard
+                length= replacedText.length;
+                String[] delimiters= fTextViewer.getDocument().getLegalLineDelimiters();
+
+                if ((length is 1) || TextUtilities.equals(delimiters, replacedText) > -1) {
+
+                    // whereby selection is empty
+
+                    if (fPreviousDelete.fStart is modelStart && fPreviousDelete.fEnd is modelEnd) {
+                        // repeated DEL
+
+                            // correct wrong settings of fCurrent
+                        if (fCurrent.fStart is modelEnd && fCurrent.fEnd is modelStart) {
+                            fCurrent.fStart= modelStart;
+                            fCurrent.fEnd= modelEnd;
+                        }
+                            // append to buffer && extend command range
+                        fPreservedTextBuffer.append(replacedText);
+                        ++fCurrent.fEnd;
+
+                    } else if (fPreviousDelete.fStart is modelEnd) {
+                        // repeated backspace
+
+                            // insert in buffer and extend command range
+                        fPreservedTextBuffer.select(0, 0);
+                        fPreservedTextBuffer.replace(replacedText);
+                        fCurrent.fStart= modelStart;
+
+                    } else {
+                        // either DEL or backspace for the first time
+
+                        fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
+                        if (fCurrent.attemptCommit())
+                            fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+                        // as we can not decide whether it was DEL or backspace we initialize for backspace
+                        fPreservedTextBuffer.append(replacedText);
+                        fCurrent.fStart= modelStart;
+                        fCurrent.fEnd= modelEnd;
+                    }
+
+                    fPreviousDelete.set(modelStart, modelEnd);
+
+                } else if (length > 0) {
+                    // whereby selection is not empty
+                    fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
+                    if (fCurrent.attemptCommit())
+                        fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+                    fCurrent.fStart= modelStart;
+                    fCurrent.fEnd= modelEnd;
+                    fPreservedTextBuffer.append(replacedText);
+                }
+            } else {
+                // text will be replaced
+
+                if (length is 1) {
+                    length= replacedText.length;
+                    String[] delimiters= fTextViewer.getDocument().getLegalLineDelimiters();
+
+                    if ((length is 1) || TextUtilities.equals(delimiters, replacedText) > -1) {
+                        // because of overwrite mode or model manipulation
+                        if (!fOverwriting || (modelStart !is fCurrent.fStart +  fTextBuffer.length())) {
+                            fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
+                            if (fCurrent.attemptCommit())
+                                fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+                            fOverwriting= true;
+                        }
+
+                        if (fCurrent.fStart < 0)
+                            fCurrent.fStart= modelStart;
+
+                        fCurrent.fEnd= modelEnd;
+                        fTextBuffer.append(insertedText);
+                        fPreservedTextBuffer.append(replacedText);
+                        fCurrent.fRedoModificationStamp= afterChangeModificationStamp;
+                        return;
+                    }
+                }
+                // because of typing or pasting whereby selection is not empty
+                fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
+                if (fCurrent.attemptCommit())
+                    fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+                fCurrent.fStart= modelStart;
+                fCurrent.fEnd= modelEnd;
+                fTextBuffer.append(insertedText);
+                fPreservedTextBuffer.append(replacedText);
+            }
+        }
+        // in all cases, the redo modification stamp is updated on the open command
+        fCurrent.fRedoModificationStamp= afterChangeModificationStamp;
+    }
+
+    /**
+     * Shows the given exception in an error dialog.
+     *
+     * @param title the dialog title
+     * @param ex the exception
+     * @since 3.1
+     */
+    private void openErrorDialog(String title, Exception ex) {
+        Shell shell= null;
+        if (isConnected()) {
+            StyledText st= fTextViewer.getTextWidget();
+            if (st !is null && !st.isDisposed())
+                shell= st.getShell();
+        }
+        if (Display.getCurrent() !is null)
+            MessageDialog.openError(shell, title, ex.msg/+getLocalizedMessage()+/);
+        else {
+            Display display;
+            Shell finalShell= shell;
+            if (finalShell !is null)
+                display= finalShell.getDisplay();
+            else
+                display= Display.getDefault();
+            display.syncExec(dgRunnable( {
+                MessageDialog.openError(finalShell, title, ex.msg/+getLocalizedMessage()+/);
+            }));
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#setMaximalUndoLevel(int)
+     */
+    public void setMaximalUndoLevel(int undoLevel) {
+        fUndoLevel= Math.max(0, undoLevel);
+        if (isConnected()) {
+            fHistory.setLimit(fUndoContext, fUndoLevel);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#connect(dwtx.jface.text.ITextViewer)
+     */
+    public void connect(ITextViewer textViewer) {
+        if (!isConnected() && textViewer !is null) {
+            fTextViewer= textViewer;
+            if (fUndoContext is null)
+                fUndoContext= new ObjectUndoContext(this);
+
+            fHistory.setLimit(fUndoContext, fUndoLevel);
+
+            initializeCommandStack();
+
+            // open up the current command
+            fCurrent= new TextCommand(fUndoContext);
+
+            fPreviousDelete= new TextCommand(fUndoContext);
+            addListeners();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#disconnect()
+     */
+    public void disconnect() {
+        if (isConnected()) {
+
+            removeListeners();
+
+            fCurrent= null;
+            fTextViewer= null;
+            disposeCommandStack();
+            fTextBuffer.clear();
+            fPreservedTextBuffer.clear();
+            fUndoContext= null;
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#reset()
+     */
+    public void reset() {
+        if (isConnected()) {
+            initializeCommandStack();
+            fCurrent= new TextCommand(fUndoContext);
+            fFoldingIntoCompoundChange= false;
+            fInserting= false;
+            fOverwriting= false;
+            fTextBuffer.truncate(0);
+            fPreservedTextBuffer.truncate(0);
+            fPreservedUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+            fPreservedRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#redoable()
+     */
+    public bool redoable() {
+        return fHistory.canRedo(fUndoContext);
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#undoable()
+     */
+    public bool undoable() {
+        return fHistory.canUndo(fUndoContext);
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#redo()
+     */
+    public void redo() {
+        if (isConnected() && redoable()) {
+            try {
+                fHistory.redo(fUndoContext, null, null);
+            } catch (ExecutionException ex) {
+                openErrorDialog(JFaceTextMessages.getString("DefaultUndoManager.error.redoFailed.title"), ex); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#undo()
+     */
+    public void undo() {
+        if (isConnected() && undoable()) {
+            try {
+                fHistory.undo(fUndoContext, null, null);
+            } catch (ExecutionException ex) {
+                openErrorDialog(JFaceTextMessages.getString("DefaultUndoManager.error.undoFailed.title"), ex); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /**
+     * Selects and reveals the specified range.
+     *
+     * @param offset the offset of the range
+     * @param length the length of the range
+     * @since 3.0
+     */
+    protected void selectAndReveal(int offset, int length) {
+        if ( cast(ITextViewerExtension5)fTextViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer;
+            extension.exposeModelRange(new Region(offset, length));
+        } else if (!fTextViewer.overlapsWithVisibleRegion(offset, length))
+            fTextViewer.resetVisibleRegion();
+
+        fTextViewer.setSelectedRange(offset, length);
+        fTextViewer.revealRange(offset, length);
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManagerExtension#getUndoContext()
+     * @since 3.1
+     */
+    public IUndoContext getUndoContext() {
+        return fUndoContext;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/Document.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,267 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.Document;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Default document implementation. Uses a {@link dwtx.jface.text.GapTextStore} wrapped
+ * inside a {@link dwtx.jface.text.CopyOnWriteTextStore} as text store.
+ * <p>
+ * The used line tracker considers the following strings as line delimiters: "\n", "\r", "\r\n".
+ * </p>
+ * <p>
+ * The document is ready to use. It has a default position category for which a default position
+ * updater is installed.
+ * </p>
+ * <p>
+ * <strong>Performance:</strong> The implementation should perform reasonably well for typical
+ * source code documents. It is not designed for very large documents of a size of several
+ * megabytes. Space-saving implementations are initially used for both the text store and the line
+ * tracker; the first modification after a {@link #set(String) set} incurs the cost to transform the
+ * document structures to efficiently handle updates.
+ * </p>
+ * <p>
+ * See {@link GapTextStore} and <code>TreeLineTracker</code> for algorithmic behavior of the used
+ * document structures.
+ * </p>
+ *
+ * @see dwtx.jface.text.GapTextStore
+ * @see dwtx.jface.text.CopyOnWriteTextStore
+ */
+public class Document : AbstractDocument {
+    /**
+     * Creates a new empty document.
+     */
+    public this() {
+        super();
+        setTextStore(new CopyOnWriteTextStore(new GapTextStore()));
+        setLineTracker(new DefaultLineTracker());
+        completeInitialization();
+    }
+
+    /**
+     * Creates a new document with the given initial content.
+     *
+     * @param initialContent the document's initial content
+     */
+    public this(String initialContent) {
+        super();
+        setTextStore(new CopyOnWriteTextStore(new GapTextStore()));
+        setLineTracker(new DefaultLineTracker());
+        getStore().set(initialContent);
+        getTracker().set(initialContent);
+        completeInitialization();
+    }
+
+    /*
+     * @see dwtx.jface.text.IRepairableDocumentExtension#isLineInformationRepairNeeded(int, int, java.lang.String)
+     * @since 3.4
+     */
+    public bool isLineInformationRepairNeeded(int offset, int length, String text)  {
+        if ((0 > offset) || (0 > length) || (offset + length > getLength()))
+            throw new BadLocationException();
+
+        return isLineInformationRepairNeeded(text) || isLineInformationRepairNeeded(get(offset, length));
+    }
+
+    /**
+     * Checks whether the line information needs to be repaired.
+     *
+     * @param text the text to check
+     * @return <code>true</code> if the line information must be repaired
+     * @since 3.4
+     */
+    private bool isLineInformationRepairNeeded(String text) {
+        if (text is null)
+            return false;
+
+        int length= text.length();
+        if (length is 0)
+            return false;
+
+        int rIndex= text.indexOf('\r');
+        int nIndex= text.indexOf('\n');
+        if (rIndex is -1 && nIndex is -1)
+            return false;
+
+        if (rIndex > 0 && rIndex < length-1 && nIndex > 1 && rIndex < length-2)
+            return false;
+
+        String defaultLD= null;
+        try {
+            defaultLD= getLineDelimiter(0);
+        } catch (BadLocationException x) {
+            return true;
+        }
+
+        if (defaultLD is null)
+            return false;
+
+        defaultLD= getDefaultLineDelimiter();
+
+        if (defaultLD.length is 1) {
+            if (rIndex !is -1 && !"\r".equals(defaultLD)) //$NON-NLS-1$
+                return true;
+            if (nIndex !is -1 && !"\n".equals(defaultLD)) //$NON-NLS-1$
+                return true;
+        } else if (defaultLD.length is 2)
+            return rIndex is -1 || nIndex - rIndex !is 1;
+
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DocumentClone.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,232 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.DocumentClone;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * An {@link dwtx.jface.text.IDocument} that is a read-only clone of another document.
+ *
+ * @since 3.0
+ */
+class DocumentClone : AbstractDocument {
+
+    private static class StringTextStore : ITextStore {
+
+        private String fContent;
+
+        /**
+         * Creates a new string text store with the given content.
+         *
+         * @param content the content
+         */
+        public this(String content) {
+            //Assert.isNotNull(content);
+            fContent= content;
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextStore#get(int)
+         */
+        public char get(int offset) {
+            return fContent.charAt(offset);
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextStore#get(int, int)
+         */
+        public String get(int offset, int length) {
+            return fContent.substring(offset, offset + length);
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextStore#getLength()
+         */
+        public int getLength() {
+            return fContent.length();
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextStore#replace(int, int, java.lang.String)
+         */
+        public void replace(int offset, int length, String text) {
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextStore#set(java.lang.String)
+         */
+        public void set(String text) {
+        }
+
+    }
+
+    /**
+     * Creates a new document clone with the given content.
+     *
+     * @param content the content
+     * @param lineDelimiters the line delimiters
+     */
+    public this(String content, String[] lineDelimiters) {
+        super();
+        setTextStore(new StringTextStore(content));
+        ConfigurableLineTracker tracker= new ConfigurableLineTracker(lineDelimiters);
+        setLineTracker(tracker);
+        getTracker().set(content);
+        completeInitialization();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DocumentCommand.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,478 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.DocumentCommand;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.core.Exception;
+
+import dwt.events.VerifyEvent;
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Represents a text modification as a document replace command. The text
+ * modification is given as a {@link dwt.events.VerifyEvent} and
+ * translated into a document replace command relative to a given offset. A
+ * document command can also be used to initialize a given
+ * <code>VerifyEvent</code>.
+ * <p>
+ * A document command can also represent a list of related changes.</p>
+ */
+public class DocumentCommand {
+
+    /**
+     * A command which is added to document commands.
+     * @since 2.1
+     */
+    private static class Command : Comparable {
+        /** The offset of the range to be replaced */
+        private const int fOffset;
+        /** The length of the range to be replaced. */
+        private const int fLength;
+        /** The replacement text */
+        private const String fText;
+        /** The listener who owns this command */
+        private const IDocumentListener fOwner;
+
+        /**
+         * Creates a new command with the given specification.
+         *
+         * @param offset the offset of the replace command
+         * @param length the length of the replace command
+         * @param text the text to replace with, may be <code>null</code>
+         * @param owner the document command owner, may be <code>null</code>
+         * @since 3.0
+         */
+        public this(int offset, int length, String text, IDocumentListener owner) {
+            if (offset < 0 || length < 0)
+                throw new IllegalArgumentException(null);
+            fOffset= offset;
+            fLength= length;
+            fText= text;
+            fOwner= owner;
+        }
+
+        /**
+         * Returns the length delta for this command.
+         *
+         * @return the length delta for this command
+         */
+        public int getDeltaLength() {
+            return (fText is null ? 0 : fText.length) - fLength;
+        }
+
+        /**
+         * Executes the document command on the specified document.
+         *
+         * @param document the document on which to execute the command.
+         * @throws BadLocationException in case this commands cannot be executed
+         */
+        public void execute(IDocument document)  {
+
+            if (fLength is 0 && fText is null)
+                return;
+
+            if (fOwner !is null)
+                document.removeDocumentListener(fOwner);
+
+            document.replace(fOffset, fLength, fText);
+
+            if (fOwner !is null)
+                document.addDocumentListener(fOwner);
+        }
+
+        /*
+         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+         */
+        public int compareTo(Object object) {
+            if (isEqual(object))
+                return 0;
+
+            final Command command= cast(Command) object;
+
+            // diff middle points if not intersecting
+            if (fOffset + fLength <= command.fOffset || command.fOffset + command.fLength <= fOffset) {
+                int value= (2 * fOffset + fLength) - (2 * command.fOffset + command.fLength);
+                if (value !is 0)
+                    return value;
+            }
+            // the answer
+            return 42;
+        }
+
+        private bool isEqual(Object object) {
+            if (object is this)
+                return true;
+            if (!( cast(Command)object ))
+                return false;
+            final Command command= cast(Command) object;
+            return command.fOffset is fOffset && command.fLength is fLength;
+        }
+    }
+
+    /**
+     * An iterator, which iterates in reverse over a list.
+     */
+    private static class ReverseListIterator : Iterator {
+
+        /** The list iterator. */
+        private const ListIterator fListIterator;
+
+        /**
+         * Creates a reverse list iterator.
+         * @param listIterator the iterator that this reverse iterator is based upon
+         */
+        public this(ListIterator listIterator) {
+            if (listIterator is null)
+                throw new IllegalArgumentException(null);
+            fListIterator= listIterator;
+        }
+
+        /*
+         * @see java.util.Iterator#hasNext()
+         */
+        public bool hasNext() {
+            return fListIterator.hasPrevious();
+        }
+
+        /*
+         * @see java.util.Iterator#next()
+         */
+        public Object next() {
+            return fListIterator.previous();
+        }
+
+        /*
+         * @see java.util.Iterator#remove()
+         */
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    /**
+     * A command iterator.
+     */
+    private static class CommandIterator : Iterator {
+
+        /** The command iterator. */
+        private const Iterator fIterator;
+
+        /** The original command. */
+        private Command fCommand;
+
+        /** A flag indicating the direction of iteration. */
+        private bool fForward;
+
+        /**
+         * Creates a command iterator.
+         *
+         * @param commands an ascending ordered list of commands
+         * @param command the original command
+         * @param forward the direction
+         */
+        public this(List commands, Command command, bool forward) {
+            if (commands is null || command is null)
+                throw new IllegalArgumentException(null);
+            fIterator= forward ? commands.iterator() : new ReverseListIterator(commands.listIterator(commands.size()));
+            fCommand= command;
+            fForward= forward;
+        }
+
+        /*
+         * @see java.util.Iterator#hasNext()
+         */
+        public bool hasNext() {
+            return fCommand !is null || fIterator.hasNext();
+        }
+
+        /*
+         * @see java.util.Iterator#next()
+         */
+        public Object next() {
+
+            if (!hasNext())
+                throw new NoSuchElementException(null);
+
+            if (fCommand is null)
+                return fIterator.next();
+
+            if (!fIterator.hasNext()) {
+                final Command tempCommand= fCommand;
+                fCommand= null;
+                return tempCommand;
+            }
+
+            final Command command= cast(Command) fIterator.next();
+            final int compareValue= command.compareTo(fCommand);
+
+            if ((compareValue < 0) ^ !fForward) {
+                return command;
+
+            } else if ((compareValue > 0) ^ !fForward) {
+                final Command tempCommand= fCommand;
+                fCommand= command;
+                return tempCommand;
+
+            } else {
+                throw new IllegalArgumentException(null);
+            }
+        }
+
+        /*
+         * @see java.util.Iterator#remove()
+         */
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    /** Must the command be updated */
+    public bool doit= false;
+    /** The offset of the command. */
+    public int offset;
+    /** The length of the command */
+    public int length;
+    /** The text to be inserted */
+    public String text;
+    /**
+     * The owner of the document command which will not be notified.
+     * @since 2.1
+     */
+    public IDocumentListener owner;
+    /**
+     * The caret offset with respect to the document before the document command is executed.
+     * @since 2.1
+     */
+    public int caretOffset;
+    /**
+     * Additional document commands.
+     * @since 2.1
+     */
+    private const List fCommands;
+    /**
+     * Indicates whether the caret should be shifted by this command.
+     * @since 3.0
+     */
+    public bool shiftsCaret;
+
+
+    /**
+     * Creates a new document command.
+     */
+    /+protected+/ this() {
+        fCommands= new ArrayList();
+    }
+
+    /**
+     * Translates a verify event into a document replace command using the given offset.
+     *
+     * @param event the event to be translated
+     * @param modelRange the event range as model range
+     */
+    void setEvent(VerifyEvent event, IRegion modelRange) {
+
+        doit= true;
+        text= event.text;
+
+        offset= modelRange.getOffset();
+        length= modelRange.getLength();
+
+        owner= null;
+        caretOffset= -1;
+        shiftsCaret= true;
+        fCommands.clear();
+    }
+
+    /**
+     * Fills the given verify event with the replace text and the <code>doit</code>
+     * flag of this document command. Returns whether the document command
+     * covers the same range as the verify event considering the given offset.
+     *
+     * @param event the event to be changed
+     * @param modelRange to be considered for range comparison
+     * @return <code>true</code> if this command and the event cover the same range
+     */
+    bool fillEvent(VerifyEvent event, IRegion modelRange) {
+        event.text= text;
+        event.doit= (offset is modelRange.getOffset() && length is modelRange.getLength() && doit && caretOffset is -1);
+        return event.doit;
+    }
+
+    /**
+     * Adds an additional replace command. The added replace command must not overlap
+     * with existing ones. If the document command owner is not <code>null</code>, it will not
+     * get document change notifications for the particular command.
+     *
+     * @param commandOffset the offset of the region to replace
+     * @param commandLength the length of the region to replace
+     * @param commandText the text to replace with, may be <code>null</code>
+     * @param commandOwner the command owner, may be <code>null</code>
+     * @throws BadLocationException if the added command intersects with an existing one
+     * @since 2.1
+     */
+    public void addCommand(int commandOffset, int commandLength, String commandText, IDocumentListener commandOwner)  {
+        final Command command= new Command(commandOffset, commandLength, commandText, commandOwner);
+
+        if (intersects(command))
+            throw new BadLocationException();
+
+        final int index= Collections.binarySearch(fCommands, command);
+
+        // a command with exactly the same ranges exists already
+        if (index >= 0)
+            throw new BadLocationException();
+
+        // binary search result is defined as (-(insertionIndex) - 1)
+        final int insertionIndex= -(index + 1);
+
+        // overlaps to the right?
+        if (insertionIndex !is fCommands.size() && intersects(cast(Command) fCommands.get(insertionIndex), command))
+            throw new BadLocationException();
+
+        // overlaps to the left?
+        if (insertionIndex !is 0 && intersects(cast(Command) fCommands.get(insertionIndex - 1), command))
+            throw new BadLocationException();
+
+        fCommands.add(insertionIndex, command);
+    }
+
+    /**
+     * Returns an iterator over the commands in ascending position order.
+     * The iterator includes the original document command.
+     * Commands cannot be removed.
+     *
+     * @return returns the command iterator
+     */
+    public Iterator getCommandIterator() {
+        Command command= new Command(offset, length, text, owner);
+        return new CommandIterator(fCommands, command, true);
+    }
+
+    /**
+     * Returns the number of commands including the original document command.
+     *
+     * @return returns the number of commands
+     * @since 2.1
+     */
+    public int getCommandCount() {
+        return 1 + fCommands.size();
+    }
+
+    /**
+     * Returns whether the two given commands intersect.
+     *
+     * @param command0 the first command
+     * @param command1 the second command
+     * @return <code>true</code> if the commands intersect
+     * @since 2.1
+     */
+    private bool intersects(Command command0, Command command1) {
+        // diff middle points if not intersecting
+        if (command0.fOffset + command0.fLength <= command1.fOffset || command1.fOffset + command1.fLength <= command0.fOffset)
+            return (2 * command0.fOffset + command0.fLength) - (2 * command1.fOffset + command1.fLength) is 0;
+        return true;
+    }
+
+    /**
+     * Returns whether the given command intersects with this command.
+     *
+     * @param command the command
+     * @return <code>true</code> if the command intersects with this command
+     * @since 2.1
+     */
+    private bool intersects(Command command) {
+        // diff middle points if not intersecting
+        if (offset + length <= command.fOffset || command.fOffset + command.fLength <= offset)
+            return (2 * offset + length) - (2 * command.fOffset + command.fLength) is 0;
+        return true;
+    }
+
+    /**
+     * Executes the document commands on a document.
+     *
+     * @param document the document on which to execute the commands
+     * @throws BadLocationException in case access to the given document fails
+     * @since 2.1
+     */
+    void execute(IDocument document)  {
+
+        if (length is 0 && text is null && fCommands.size() is 0)
+            return;
+
+        DefaultPositionUpdater updater= new DefaultPositionUpdater(getCategory());
+        Position caretPosition= null;
+        try {
+            if (updateCaret()) {
+                document.addPositionCategory(getCategory());
+                document.addPositionUpdater(updater);
+                caretPosition= new Position(caretOffset);
+                document.addPosition(getCategory(), caretPosition);
+            }
+
+            final Command originalCommand= new Command(offset, length, text, owner);
+            for (final Iterator iterator= new CommandIterator(fCommands, originalCommand, false); iterator.hasNext(); )
+                (cast(Command) iterator.next()).execute(document);
+
+        } catch (BadLocationException e) {
+            // ignore
+        } catch (BadPositionCategoryException e) {
+            // ignore
+        } finally {
+            delegate(){
+            if (updateCaret()) {
+                document.removePositionUpdater(updater);
+                try {
+                    document.removePositionCategory(getCategory());
+                } catch (BadPositionCategoryException e) {
+                    Assert.isTrue(false);
+                }
+                caretOffset= caretPosition.getOffset();
+            }
+            }();
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if the caret offset should be updated, <code>false</code> otherwise.
+     *
+     * @return <code>true</code> if the caret offset should be updated, <code>false</code> otherwise
+     * @since 3.0
+     */
+    private bool updateCaret() {
+        return shiftsCaret && caretOffset !is -1;
+    }
+
+    /**
+     * Returns the position category for the caret offset position.
+     *
+     * @return the position category for the caret offset position
+     * @since 3.0
+     */
+    private String getCategory() {
+        return toString();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DocumentEvent.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,303 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.DocumentEvent;
+
+// import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+// import dwtx.jface.text.DefaultTextHover; // packageimport
+// import dwtx.jface.text.AbstractInformationControl; // packageimport
+// import dwtx.jface.text.TextUtilities; // packageimport
+// import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+// import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+// import dwtx.jface.text.ITextViewerExtension2; // packageimport
+// import dwtx.jface.text.IDocumentPartitioner; // packageimport
+// import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+// import dwtx.jface.text.ITextSelection; // packageimport
+// import dwtx.jface.text.Document; // packageimport
+// import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+// import dwtx.jface.text.ITextListener; // packageimport
+// import dwtx.jface.text.BadPartitioningException; // packageimport
+// import dwtx.jface.text.ITextViewerExtension5; // packageimport
+// import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+// import dwtx.jface.text.IUndoManager; // packageimport
+// import dwtx.jface.text.ITextHoverExtension2; // packageimport
+// import dwtx.jface.text.IRepairableDocument; // packageimport
+// import dwtx.jface.text.IRewriteTarget; // packageimport
+// import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+// import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+// import dwtx.jface.text.TextViewerHoverManager; // packageimport
+// import dwtx.jface.text.DocumentRewriteSession; // packageimport
+// import dwtx.jface.text.TextViewer; // packageimport
+// import dwtx.jface.text.ITextViewerExtension8; // packageimport
+// import dwtx.jface.text.RegExMessages; // packageimport
+// import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+// import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+// import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+// import dwtx.jface.text.IViewportListener; // packageimport
+// import dwtx.jface.text.GapTextStore; // packageimport
+// import dwtx.jface.text.MarkSelection; // packageimport
+// import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+// import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+// import dwtx.jface.text.IInformationControlExtension; // packageimport
+// import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+// import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+// import dwtx.jface.text.ITextViewerExtension3; // packageimport
+// import dwtx.jface.text.IInformationControlCreator; // packageimport
+// import dwtx.jface.text.TypedRegion; // packageimport
+// import dwtx.jface.text.ISynchronizable; // packageimport
+// import dwtx.jface.text.IMarkRegionTarget; // packageimport
+// import dwtx.jface.text.TextViewerUndoManager; // packageimport
+// import dwtx.jface.text.IRegion; // packageimport
+// import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+// import dwtx.jface.text.IDocumentExtension2; // packageimport
+// import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+// import dwtx.jface.text.Assert; // packageimport
+// import dwtx.jface.text.DefaultInformationControl; // packageimport
+// import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+// import dwtx.jface.text.DocumentClone; // packageimport
+// import dwtx.jface.text.DefaultUndoManager; // packageimport
+// import dwtx.jface.text.IFindReplaceTarget; // packageimport
+// import dwtx.jface.text.IAutoEditStrategy; // packageimport
+// import dwtx.jface.text.ILineTrackerExtension; // packageimport
+// import dwtx.jface.text.IUndoManagerExtension; // packageimport
+// import dwtx.jface.text.TextSelection; // packageimport
+// import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+// import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+// import dwtx.jface.text.IPainter; // packageimport
+// import dwtx.jface.text.IInformationControl; // packageimport
+// import dwtx.jface.text.IInformationControlExtension3; // packageimport
+// import dwtx.jface.text.ITextViewerExtension6; // packageimport
+// import dwtx.jface.text.IInformationControlExtension4; // packageimport
+// import dwtx.jface.text.DefaultLineTracker; // packageimport
+// import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+// import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+// import dwtx.jface.text.ITextHover; // packageimport
+// import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+// import dwtx.jface.text.ILineTracker; // packageimport
+// import dwtx.jface.text.Line; // packageimport
+// import dwtx.jface.text.ITextViewerExtension; // packageimport
+// import dwtx.jface.text.IDocumentAdapter; // packageimport
+// import dwtx.jface.text.TextEvent; // packageimport
+// import dwtx.jface.text.BadLocationException; // packageimport
+// import dwtx.jface.text.AbstractDocument; // packageimport
+// import dwtx.jface.text.AbstractLineTracker; // packageimport
+// import dwtx.jface.text.TreeLineTracker; // packageimport
+// import dwtx.jface.text.ITextPresentationListener; // packageimport
+// import dwtx.jface.text.Region; // packageimport
+// import dwtx.jface.text.ITextViewer; // packageimport
+// import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+// import dwtx.jface.text.MarginPainter; // packageimport
+// import dwtx.jface.text.IPaintPositionManager; // packageimport
+// import dwtx.jface.text.TextPresentation; // packageimport
+// import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+// import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+// import dwtx.jface.text.ISelectionValidator; // packageimport
+// import dwtx.jface.text.IDocumentExtension; // packageimport
+// import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+// import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+// import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+// import dwtx.jface.text.IDocumentListener; // packageimport
+// import dwtx.jface.text.PaintManager; // packageimport
+// import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+// import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+// import dwtx.jface.text.IDocumentExtension3; // packageimport
+// import dwtx.jface.text.Position; // packageimport
+// import dwtx.jface.text.TextMessages; // packageimport
+// import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+// import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+// import dwtx.jface.text.IPositionUpdater; // packageimport
+// import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+// import dwtx.jface.text.ListLineTracker; // packageimport
+// import dwtx.jface.text.ITextInputListener; // packageimport
+// import dwtx.jface.text.BadPositionCategoryException; // packageimport
+// import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+// import dwtx.jface.text.IInputChangedListener; // packageimport
+// import dwtx.jface.text.ITextOperationTarget; // packageimport
+// import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+// import dwtx.jface.text.ITextViewerExtension7; // packageimport
+// import dwtx.jface.text.IInformationControlExtension5; // packageimport
+// import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+// import dwtx.jface.text.JFaceTextUtil; // packageimport
+// import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+// import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+// import dwtx.jface.text.CursorLinePainter; // packageimport
+// import dwtx.jface.text.ITextHoverExtension; // packageimport
+// import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+// import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+// import dwtx.jface.text.DocumentCommand; // packageimport
+// import dwtx.jface.text.TypedPosition; // packageimport
+// import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+// import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+// import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+// import dwtx.jface.text.IEditingSupport; // packageimport
+// import dwtx.jface.text.IMarkSelection; // packageimport
+// import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+// import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+// import dwtx.jface.text.ITextStore; // packageimport
+// import dwtx.jface.text.JFaceTextMessages; // packageimport
+// import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+// import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+// import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+// import dwtx.jface.text.TextAttribute; // packageimport
+// import dwtx.jface.text.ITextViewerExtension4; // packageimport
+// import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Specification of changes applied to documents. All changes are represented as
+ * replace commands, i.e. specifying a document range whose text gets replaced
+ * with different text. In addition to this information, the event also contains
+ * the changed document.
+ *
+ * @see dwtx.jface.text.IDocument
+ */
+public class DocumentEvent {
+
+    /**
+     * Debug option for asserting that text is not null.
+     * If the <code>dwtx.text/debug/DocumentEvent/assertTextNotNull</code>
+     * system property is <code>true</code>
+     *
+     * @since 3.3
+     */
+    private static bool ASSERT_TEXT_NOT_NULL_init = false;
+    private static bool ASSERT_TEXT_NOT_NULL_;
+    private static bool ASSERT_TEXT_NOT_NULL(){
+        if( !ASSERT_TEXT_NOT_NULL_init ){
+            ASSERT_TEXT_NOT_NULL_init = true;
+            ASSERT_TEXT_NOT_NULL_= Boolean.getBoolean("dwtx.text/debug/DocumentEvent/assertTextNotNull"); //$NON-NLS-1$
+        }
+        return ASSERT_TEXT_NOT_NULL_;
+    }
+
+    /** The changed document */
+    public IDocument fDocument;
+    /** The document offset */
+    public int fOffset;
+    /** Length of the replaced document text */
+    public int fLength;
+    /** Text inserted into the document */
+    public String fText= ""; //$NON-NLS-1$
+    /**
+     * The modification stamp of the document when firing this event.
+     * @since 3.1 and public since 3.3
+     */
+    public long fModificationStamp;
+
+    /**
+     * Creates a new document event.
+     *
+     * @param doc the changed document
+     * @param offset the offset of the replaced text
+     * @param length the length of the replaced text
+     * @param text the substitution text
+     */
+    public this(IDocument doc, int offset, int length, String text) {
+
+        Assert.isNotNull(cast(Object)doc);
+        Assert.isTrue(offset >= 0);
+        Assert.isTrue(length >= 0);
+
+        if (ASSERT_TEXT_NOT_NULL)
+            Assert.isNotNull(text);
+
+        fDocument= doc;
+        fOffset= offset;
+        fLength= length;
+        fText= text;
+
+        if ( cast(IDocumentExtension4)fDocument )
+            fModificationStamp= (cast(IDocumentExtension4)fDocument).getModificationStamp();
+        else
+            fModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+    }
+
+    /**
+     * Creates a new, not initialized document event.
+     */
+    public this() {
+    }
+
+    /**
+     * Returns the changed document.
+     *
+     * @return the changed document
+     */
+    public IDocument getDocument() {
+        return fDocument;
+    }
+
+    /**
+     * Returns the offset of the change.
+     *
+     * @return the offset of the change
+     */
+    public int getOffset() {
+        return fOffset;
+    }
+
+    /**
+     * Returns the length of the replaced text.
+     *
+     * @return the length of the replaced text
+     */
+    public int getLength() {
+        return fLength;
+    }
+
+    /**
+     * Returns the text that has been inserted.
+     *
+     * @return the text that has been inserted
+     */
+    public String getText() {
+        return fText;
+    }
+
+    /**
+     * Returns the document's modification stamp at the
+     * time when this event was sent.
+     *
+     * @return the modification stamp or {@link IDocumentExtension4#UNKNOWN_MODIFICATION_STAMP}.
+     * @see IDocumentExtension4#getModificationStamp()
+     * @since 3.1
+     */
+    public long getModificationStamp() {
+        return fModificationStamp;
+    }
+
+    /*
+     * @see java.lang.Object#toString()
+     * @since 3.4
+     */
+    public override String toString() {
+        StringBuffer buffer= new StringBuffer();
+        buffer.append("offset: " ); //$NON-NLS-1$
+        buffer.append(fOffset);
+        buffer.append(", length: " ); //$NON-NLS-1$
+        buffer.append(fLength);
+        buffer.append(", timestamp: " ); //$NON-NLS-1$
+        buffer.append(fModificationStamp);
+        buffer.append("\ntext:>" ); //$NON-NLS-1$
+        buffer.append(fText);
+        buffer.append("<\n" ); //$NON-NLS-1$
+        return buffer.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DocumentPartitioningChangedEvent.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,267 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.DocumentPartitioningChangedEvent;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+import dwtx.core.runtime.Assert;
+
+/**
+ * Event describing the change of document partitionings.
+ *
+ * @see dwtx.jface.text.IDocumentExtension3
+ * @since 3.0
+ */
+public class DocumentPartitioningChangedEvent {
+
+    /** The document whose partitionings changed */
+    private const IDocument fDocument;
+    /** The map of partitionings to changed regions. */
+    private const Map fMap;
+
+
+    /**
+     * Creates a new document partitioning changed event for the given document.
+     * Initially this event is empty, i.e. does not describe any change.
+     *
+     * @param document the changed document
+     */
+    public this(IDocument document) {
+        fMap= new HashMap();
+        fDocument= document;
+    }
+
+    /**
+     * Returns the changed document.
+     *
+     * @return the changed document
+     */
+    public IDocument getDocument() {
+        return fDocument;
+    }
+
+    /**
+     * Returns the changed region of the given partitioning or <code>null</code>
+     * if the given partitioning did not change.
+     *
+     * @param partitioning the partitioning
+     * @return the changed region of the given partitioning or <code>null</code>
+     */
+    public IRegion getChangedRegion(String partitioning) {
+        return cast(IRegion) fMap.get(partitioning);
+    }
+
+    /**
+     * Returns the set of changed partitionings.
+     *
+     * @return the set of changed partitionings
+     */
+    public String[] getChangedPartitionings() {
+        return stringcast(fMap.keySet().toArray());
+    }
+
+    /**
+     * Sets the specified range as changed region for the given partitioning.
+     *
+     * @param partitioning the partitioning
+     * @param offset the region offset
+     * @param length the region length
+     */
+    public void setPartitionChange(String partitioning, int offset, int length) {
+        //Assert.isNotNull(partitioning);
+        fMap.put(partitioning, new Region(offset, length));
+    }
+
+    /**
+     * Returns <code>true</code> if the set of changed partitionings is empty,
+     * <code>false</code> otherwise.
+     *
+     * @return <code>true</code> if the set of changed partitionings is empty
+     */
+    public bool isEmpty() {
+        return fMap.isEmpty();
+    }
+
+    /**
+     * Returns the coverage of this event. This is the minimal region that
+     * contains all changed regions of all changed partitionings.
+     *
+     * @return the coverage of this event
+     */
+    public IRegion getCoverage() {
+        if (fMap.isEmpty())
+            return new Region(0, 0);
+
+        int offset= -1;
+        int endOffset= -1;
+        Iterator e= fMap.values().iterator();
+        while (e.hasNext()) {
+            IRegion r= cast(IRegion) e.next();
+
+            if (offset < 0 || r.getOffset() < offset)
+                offset= r.getOffset();
+
+            int end= r.getOffset() + r.getLength();
+            if (end > endOffset)
+                endOffset= end;
+        }
+
+        return new Region(offset, endOffset - offset);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DocumentRewriteSession.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.DocumentRewriteSession;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A document rewrite session.
+ *
+ * @see dwtx.jface.text.IDocument
+ * @see dwtx.jface.text.IDocumentExtension4
+ * @see dwtx.jface.text.IDocumentRewriteSessionListener
+ * @since 3.1
+ */
+public class DocumentRewriteSession {
+
+    private DocumentRewriteSessionType fSessionType;
+
+    /**
+     * Prohibit package external object creation.
+     *
+     * @param sessionType the type of this session
+     */
+    /+protected+/ this(DocumentRewriteSessionType sessionType) {
+        fSessionType= sessionType;
+    }
+
+    /**
+     * Returns the type of this session.
+     *
+     * @return the type of this session
+     */
+    public DocumentRewriteSessionType getSessionType() {
+        return fSessionType;
+    }
+
+    /*
+     * @see java.lang.Object#toString()
+     */
+    public override String toString() {
+        static assert( hash_t.sizeof is 4 );
+        return (new StringBuffer()).append(Integer.toString(toHash())).toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DocumentRewriteSessionEvent.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.DocumentRewriteSessionEvent;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Description of the state of document rewrite sessions.
+ *
+ * @see dwtx.jface.text.IDocument
+ * @see dwtx.jface.text.IDocumentExtension4
+ * @see dwtx.jface.text.IDocumentRewriteSessionListener
+ * @since 3.1
+ */
+public class DocumentRewriteSessionEvent {
+
+    private static Object SESSION_START_;
+    public static Object SESSION_START(){
+        if( SESSION_START_ is null ){
+            synchronized(DocumentRewriteSessionEvent.classinfo){
+                if( SESSION_START_ is null ){
+                    SESSION_START_ = new Object();
+                }
+            }
+        }
+        return SESSION_START_;
+    }
+    private static Object SESSION_STOP_;
+    public static Object SESSION_STOP(){
+        if( SESSION_STOP_ is null ){
+            synchronized(DocumentRewriteSessionEvent.classinfo){
+                if( SESSION_STOP_ is null ){
+                    SESSION_STOP_ = new Object();
+                }
+            }
+        }
+        return SESSION_STOP_;
+    }
+
+    /** The changed document */
+    public IDocument fDocument;
+    /** The session */
+    public DocumentRewriteSession fSession;
+    /** The change type */
+    public Object fChangeType;
+
+    /**
+     * Creates a new document event.
+     *
+     * @param doc the changed document
+     * @param session the session
+     * @param changeType the change type. This is either
+     *            {@link DocumentRewriteSessionEvent#SESSION_START} or
+     *            {@link DocumentRewriteSessionEvent#SESSION_STOP}.
+     */
+    public this(IDocument doc, DocumentRewriteSession session, Object changeType) {
+        Assert.isNotNull(cast(Object)doc);
+        Assert.isNotNull(session);
+
+        fDocument= doc;
+        fSession= session;
+        fChangeType= changeType;
+    }
+
+    /**
+     * Returns the changed document.
+     *
+     * @return the changed document
+     */
+    public IDocument getDocument() {
+        return fDocument;
+    }
+
+    /**
+     * Returns the change type of this event. This is either
+     * {@link DocumentRewriteSessionEvent#SESSION_START}or
+     * {@link DocumentRewriteSessionEvent#SESSION_STOP}.
+     *
+     * @return the change type of this event
+     */
+    public Object getChangeType() {
+        return fChangeType;
+    }
+
+    /**
+     * Returns the rewrite session.
+     *
+     * @return the rewrite session
+     */
+    public DocumentRewriteSession getSession() {
+        return fSession;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/DocumentRewriteSessionType.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.DocumentRewriteSessionType;
+
+import dwt.dwthelper.utils;
+
+/**
+ * A document rewrite session type.
+ * <p>
+ * Allowed values are:
+ * <ul>
+ *  <li>{@link DocumentRewriteSessionType#UNRESTRICTED}</li>
+ *  <li>{@link DocumentRewriteSessionType#UNRESTRICTED_SMALL} (since 3.3)</li>
+ *  <li>{@link DocumentRewriteSessionType#SEQUENTIAL}</li>
+ *  <li>{@link DocumentRewriteSessionType#STRICTLY_SEQUENTIAL}</li>
+ * </ul>
+ * </p>
+ *
+ * @see dwtx.jface.text.IDocument
+ * @see dwtx.jface.text.IDocumentExtension4
+ * @see dwtx.jface.text.IDocumentRewriteSessionListener
+ * @since 3.1
+ */
+public class DocumentRewriteSessionType {
+
+    static this(){
+        UNRESTRICTED= new DocumentRewriteSessionType();
+        UNRESTRICTED_SMALL= new DocumentRewriteSessionType();
+        SEQUENTIAL= new DocumentRewriteSessionType();
+        STRICTLY_SEQUENTIAL= new DocumentRewriteSessionType();
+    }
+
+    /**
+     * An unrestricted rewrite session is a sequence of unrestricted replace operations. This
+     * session type should only be used for <em>large</em> operations that touch more than about
+     * fifty lines. Use {@link #UNRESTRICTED_SMALL} for small operations.
+     */
+    public const static DocumentRewriteSessionType UNRESTRICTED;
+    /**
+     * An small unrestricted rewrite session is a short sequence of unrestricted replace operations.
+     * This should be used for changes that touch less than about fifty lines.
+     *
+     * @since 3.3
+     */
+    public const static DocumentRewriteSessionType UNRESTRICTED_SMALL;
+    /**
+     * A sequential rewrite session is a sequence of non-overlapping replace
+     * operations starting at an arbitrary document offset.
+     */
+    public const static DocumentRewriteSessionType SEQUENTIAL;
+    /**
+     * A strictly sequential rewrite session is a sequence of non-overlapping
+     * replace operations from the start of the document to its end.
+     */
+    public const static DocumentRewriteSessionType STRICTLY_SEQUENTIAL;
+
+
+    /**
+     * Prohibit external object creation.
+     */
+    private this() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/FindReplaceDocumentAdapter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,822 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Cagatay Calli <ccalli@gmail.com> - [find/replace] retain caps when replacing - https://bugs.eclipse.org/bugs/show_bug.cgi?id=28949
+ *     Cagatay Calli <ccalli@gmail.com> - [find/replace] define & fix behavior of retain caps with other escapes and text before \C - https://bugs.eclipse.org/bugs/show_bug.cgi?id=217061
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.FindReplaceDocumentAdapter;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.regex;
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Provides search and replace operations on
+ * {@link dwtx.jface.text.IDocument}.
+ * <p>
+ * Replaces
+ * {@link dwtx.jface.text.IDocument#search(int, String, bool, bool, bool)}.
+ *
+ * @since 3.0
+ */
+public class FindReplaceDocumentAdapter : CharSequence {
+
+    /**
+     * Internal type for operation codes.
+     */
+    private static class FindReplaceOperationCode {
+    }
+
+    // Find/replace operation codes.
+    private static FindReplaceOperationCode FIND_FIRST_;
+    private static FindReplaceOperationCode FIND_FIRST(){
+        if( FIND_FIRST_ is null ){
+            synchronized( FindReplaceDocumentAdapter.classinfo ){
+                if( FIND_FIRST_ is null ){
+                    FIND_FIRST_ = new FindReplaceOperationCode();
+                }
+            }
+        }
+        return FIND_FIRST_;
+    }
+
+    private static FindReplaceOperationCode FIND_NEXT_;
+    private static FindReplaceOperationCode FIND_NEXT(){
+        if( FIND_NEXT_ is null ){
+            synchronized( FindReplaceDocumentAdapter.classinfo ){
+                if( FIND_NEXT_ is null ){
+                    FIND_NEXT_ = new FindReplaceOperationCode();
+                }
+            }
+        }
+        return FIND_NEXT_;
+    }
+    private static FindReplaceOperationCode REPLACE_;
+    private static FindReplaceOperationCode REPLACE(){
+        if( REPLACE_ is null ){
+            synchronized( FindReplaceDocumentAdapter.classinfo ){
+                if( REPLACE_ is null ){
+                    REPLACE_ = new FindReplaceOperationCode();
+                }
+            }
+        }
+        return REPLACE_;
+    }
+    private static FindReplaceOperationCode REPLACE_FIND_NEXT_;
+    private static FindReplaceOperationCode REPLACE_FIND_NEXT(){
+        if( REPLACE_FIND_NEXT_ is null ){
+            synchronized( FindReplaceDocumentAdapter.classinfo ){
+                if( REPLACE_FIND_NEXT_ is null ){
+                    REPLACE_FIND_NEXT_ = new FindReplaceOperationCode();
+                }
+            }
+        }
+        return REPLACE_FIND_NEXT_;
+    }
+
+    /**
+     * Retain case mode constants.
+     * @since 3.4
+     */
+    private static const int RC_MIXED= 0;
+    private static const int RC_UPPER= 1;
+    private static const int RC_LOWER= 2;
+    private static const int RC_FIRSTUPPER= 3;
+
+
+    /**
+     * The adapted document.
+     */
+    private IDocument fDocument;
+
+    /**
+     * State for findReplace.
+     */
+    private FindReplaceOperationCode fFindReplaceState= null;
+
+    /**
+     * The matcher used in findReplace.
+     */
+    private Matcher fFindReplaceMatcher;
+
+    /**
+     * The match offset from the last findReplace call.
+     */
+    private int fFindReplaceMatchOffset;
+
+    /**
+     * Retain case mode
+     */
+    private int fRetainCaseMode;
+
+    /**
+     * Constructs a new find replace document adapter.
+     *
+     * @param document the adapted document
+     */
+    public this(IDocument document) {
+        Assert.isNotNull(cast(Object)document);
+        fDocument= document;
+    }
+
+    /**
+     * Returns the location of a given string in this adapter's document based on a set of search criteria.
+     *
+     * @param startOffset document offset at which search starts
+     * @param findString the string to find
+     * @param forwardSearch the search direction
+     * @param caseSensitive indicates whether lower and upper case should be distinguished
+     * @param wholeWord indicates whether the findString should be limited by white spaces as
+     *          defined by Character.isWhiteSpace. Must not be used in combination with <code>regExSearch</code>.
+     * @param regExSearch if <code>true</code> findString represents a regular expression
+     *          Must not be used in combination with <code>wholeWord</code>.
+     * @return the find or replace region or <code>null</code> if there was no match
+     * @throws BadLocationException if startOffset is an invalid document offset
+     * @throws PatternSyntaxException if a regular expression has invalid syntax
+     */
+    public IRegion find(int startOffset, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord, bool regExSearch)  {
+        Assert.isTrue(!(regExSearch && wholeWord));
+
+        // Adjust offset to special meaning of -1
+        if (startOffset is -1 && forwardSearch)
+            startOffset= 0;
+        if (startOffset is -1 && !forwardSearch)
+            startOffset= length() - 1;
+
+        return findReplace(FIND_FIRST, startOffset, findString, null, forwardSearch, caseSensitive, wholeWord, regExSearch);
+    }
+
+    /**
+     * Stateful findReplace executes a FIND, REPLACE, REPLACE_FIND or FIND_FIRST operation.
+     * In case of REPLACE and REPLACE_FIND it sends a <code>DocumentEvent</code> to all
+     * registered <code>IDocumentListener</code>.
+     *
+     * @param startOffset document offset at which search starts
+     *          this value is only used in the FIND_FIRST operation and otherwise ignored
+     * @param findString the string to find
+     *          this value is only used in the FIND_FIRST operation and otherwise ignored
+     * @param replaceText the string to replace the current match
+     *          this value is only used in the REPLACE and REPLACE_FIND operations and otherwise ignored
+     * @param forwardSearch the search direction
+     * @param caseSensitive indicates whether lower and upper case should be distinguished
+     * @param wholeWord indicates whether the findString should be limited by white spaces as
+     *          defined by Character.isWhiteSpace. Must not be used in combination with <code>regExSearch</code>.
+     * @param regExSearch if <code>true</code> this operation represents a regular expression
+     *          Must not be used in combination with <code>wholeWord</code>.
+     * @param operationCode specifies what kind of operation is executed
+     * @return the find or replace region or <code>null</code> if there was no match
+     * @throws BadLocationException if startOffset is an invalid document offset
+     * @throws IllegalStateException if a REPLACE or REPLACE_FIND operation is not preceded by a successful FIND operation
+     * @throws PatternSyntaxException if a regular expression has invalid syntax
+     */
+    private IRegion findReplace(FindReplaceOperationCode operationCode, int startOffset, String findString, String replaceText, bool forwardSearch, bool caseSensitive, bool wholeWord, bool regExSearch)  {
+
+        // Validate option combinations
+        Assert.isTrue(!(regExSearch && wholeWord));
+
+        // Validate state
+        if ((operationCode is REPLACE || operationCode is REPLACE_FIND_NEXT) && (fFindReplaceState !is FIND_FIRST && fFindReplaceState !is FIND_NEXT))
+            throw new IllegalStateException("illegal findReplace state: cannot replace without preceding find"); //$NON-NLS-1$
+
+        if (operationCode is FIND_FIRST) {
+            // Reset
+
+            if (findString is null || findString.length is 0)
+                return null;
+
+            // Validate start offset
+            if (startOffset < 0 || startOffset >= length())
+                throw new BadLocationException();
+
+            int patternFlags= 0;
+
+            if (regExSearch) {
+                patternFlags |= Pattern.MULTILINE;
+                findString= substituteLinebreak(findString);
+            }
+
+            if (!caseSensitive)
+                patternFlags |= Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE;
+
+            if (wholeWord)
+                findString= "\\b" ~ findString ~ "\\b"; //$NON-NLS-1$ //$NON-NLS-2$
+
+            if (!regExSearch && !wholeWord)
+                findString= asRegPattern(findString);
+
+            fFindReplaceMatchOffset= startOffset;
+            if (fFindReplaceMatcher !is null && fFindReplaceMatcher.pattern().pattern().equals(findString) && fFindReplaceMatcher.pattern().flags() is patternFlags) {
+                /*
+                 * Commented out for optimization:
+                 * The call is not needed since FIND_FIRST uses find(int) which resets the matcher
+                 */
+                // fFindReplaceMatcher.reset();
+            } else {
+                Pattern pattern= Pattern.compile(findString, patternFlags);
+                fFindReplaceMatcher= pattern.matcher(this);
+            }
+        }
+
+        // Set state
+        fFindReplaceState= operationCode;
+
+        if (operationCode is REPLACE || operationCode is REPLACE_FIND_NEXT) {
+            if (regExSearch) {
+                Pattern pattern= fFindReplaceMatcher.pattern();
+                String prevMatch= fFindReplaceMatcher.group();
+                try {
+                    replaceText= interpretReplaceEscapes(replaceText, prevMatch);
+                    Matcher replaceTextMatcher= pattern.matcher(prevMatch);
+                    replaceText= replaceTextMatcher.replaceFirst(replaceText);
+                } catch (IndexOutOfBoundsException ex) {
+                    throw new PatternSyntaxException(ex.msg/+getLocalizedMessage()+/, replaceText, -1);
+                }
+            }
+
+            int offset= fFindReplaceMatcher.start();
+            int length= fFindReplaceMatcher.group().length;
+
+            if (cast(IRepairableDocumentExtension)fDocument
+                    && (cast(IRepairableDocumentExtension)fDocument).isLineInformationRepairNeeded(offset, length, replaceText)) {
+                String message= TextMessages.getString("FindReplaceDocumentAdapter.incompatibleLineDelimiter"); //$NON-NLS-1$
+                throw new PatternSyntaxException(message, replaceText, offset);
+            }
+
+            fDocument.replace(offset, length, replaceText);
+
+            if (operationCode is REPLACE) {
+                return new Region(offset, replaceText.length);
+            }
+        }
+
+        if (operationCode !is REPLACE) {
+            if (forwardSearch) {
+
+                bool found= false;
+                if (operationCode is FIND_FIRST)
+                    found= fFindReplaceMatcher.find(startOffset);
+                else
+                    found= fFindReplaceMatcher.find();
+
+                if (operationCode is REPLACE_FIND_NEXT)
+                    fFindReplaceState= FIND_NEXT;
+
+                if (found && fFindReplaceMatcher.group().length > 0)
+                    return new Region(fFindReplaceMatcher.start(), fFindReplaceMatcher.group().length);
+                return null;
+            }
+
+            // backward search
+            bool found= fFindReplaceMatcher.find(0);
+            int index= -1;
+            int length= -1;
+            while (found && fFindReplaceMatcher.start() + fFindReplaceMatcher.group().length <= fFindReplaceMatchOffset + 1) {
+                index= fFindReplaceMatcher.start();
+                length= fFindReplaceMatcher.group().length;
+                found= fFindReplaceMatcher.find(index + 1);
+            }
+            fFindReplaceMatchOffset= index;
+            if (index > -1) {
+                // must set matcher to correct position
+                fFindReplaceMatcher.find(index);
+                return new Region(index, length);
+            }
+            return null;
+        }
+
+        return null;
+    }
+
+    /**
+     * Substitutes \R in a regex find pattern with (?>\r\n?|\n)
+     *
+     * @param findString the original find pattern
+     * @return the transformed find pattern
+     * @throws PatternSyntaxException if \R is added at an illegal position (e.g. in a character set)
+     * @since 3.4
+     */
+    private String substituteLinebreak(String findString)  {
+        int length= findString.length;
+        StringBuffer buf= new StringBuffer(length);
+
+        int inCharGroup= 0;
+        int inBraces= 0;
+        bool inQuote= false;
+        for (int i= 0; i < length; i++) {
+            char ch= .charAt(findString, i);
+            switch (ch) {
+                case '[':
+                    buf.append(ch);
+                    if (! inQuote)
+                        inCharGroup++;
+                    break;
+
+                case ']':
+                    buf.append(ch);
+                    if (! inQuote)
+                        inCharGroup--;
+                    break;
+
+                case '{':
+                    buf.append(ch);
+                    if (! inQuote && inCharGroup is 0)
+                        inBraces++;
+                    break;
+
+                case '}':
+                    buf.append(ch);
+                    if (! inQuote && inCharGroup is 0)
+                        inBraces--;
+                    break;
+
+                case '\\':
+                    if (i + 1 < length) {
+                        char ch1= .charAt(findString, i + 1);
+                        if (inQuote) {
+                            if (ch1 is 'E')
+                                inQuote= false;
+                            buf.append(ch).append(ch1);
+                            i++;
+
+                        } else if (ch1 is 'R') {
+                            if (inCharGroup > 0 || inBraces > 0) {
+                                String msg= TextMessages.getString("FindReplaceDocumentAdapter.illegalLinebreak"); //$NON-NLS-1$
+                                throw new PatternSyntaxException(msg, findString, i);
+                            }
+                            buf.append("(?>\\r\\n?|\\n)"); //$NON-NLS-1$
+                            i++;
+
+                        } else {
+                            if (ch1 is 'Q') {
+                                inQuote= true;
+                            }
+                            buf.append(ch).append(ch1);
+                            i++;
+                        }
+                    } else {
+                        buf.append(ch);
+                    }
+                    break;
+
+                default:
+                    buf.append(ch);
+                    break;
+            }
+
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Interprets current Retain Case mode (all upper-case,all lower-case,capitalized or mixed)
+     * and appends the character <code>ch</code> to <code>buf</code> after processing.
+     *
+     * @param buf the output buffer
+     * @param ch the character to process
+     * @since 3.4
+     */
+    private void interpretRetainCase(StringBuffer buf, dchar ch) {
+        if (fRetainCaseMode is RC_UPPER)
+            buf.append(dcharToString(Character.toUpperCase(ch)));
+        else if (fRetainCaseMode is RC_LOWER)
+            buf.append(dcharToString(Character.toLowerCase(ch)));
+        else if (fRetainCaseMode is RC_FIRSTUPPER) {
+            buf.append(dcharToString(Character.toUpperCase(ch)));
+            fRetainCaseMode= RC_MIXED;
+        } else
+            buf.append(dcharToString(ch));
+    }
+
+    /**
+     * Interprets escaped characters in the given replace pattern.
+     *
+     * @param replaceText the replace pattern
+     * @param foundText the found pattern to be replaced
+     * @return a replace pattern with escaped characters substituted by the respective characters
+     * @since 3.4
+     */
+    private String interpretReplaceEscapes(String replaceText, String foundText) {
+        int length= replaceText.length;
+        bool inEscape= false;
+        StringBuffer buf= new StringBuffer(length);
+
+        /* every string we did not check looks mixed at first
+         * so initialize retain case mode with RC_MIXED
+         */
+        fRetainCaseMode= RC_MIXED;
+
+        for (int i= 0; i < length; i++) {
+            char ch= .charAt(replaceText, i);
+            if (inEscape) {
+                i= interpretReplaceEscape(ch, i, buf, replaceText, foundText);
+                inEscape= false;
+
+            } else if (ch is '\\') {
+                inEscape= true;
+
+            } else if (ch is '$') {
+                buf.append(ch);
+
+                /*
+                 * Feature in java.util.regex.Matcher#replaceFirst(String):
+                 * $00, $000, etc. are interpreted as $0 and
+                 * $01, $001, etc. are interpreted as $1, etc. .
+                 * If we support \0 as replacement pattern for capturing group 0,
+                 * it would not be possible any more to write a replacement pattern
+                 * that appends 0 to a capturing group (like $0\0).
+                 * The fix is to interpret \00 and $00 as $0\0, and
+                 * \01 and $01 as $0\1, etc.
+                 */
+                if (i + 2 < length) {
+                    char ch1= .charAt(replaceText, i + 1);
+                    char ch2= .charAt(replaceText, i + 2);
+                    if (ch1 is '0' && '0' <= ch2 && ch2 <= '9') {
+                        buf.append("0\\"); //$NON-NLS-1$
+                        i++; // consume the 0
+                    }
+                }
+            } else {
+                interpretRetainCase(buf, ch);
+            }
+        }
+
+        if (inEscape) {
+            // '\' as last character is invalid, but we still add it to get an error message
+            buf.append('\\');
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Interprets the escaped character <code>ch</code> at offset <code>i</code>
+     * of the <code>replaceText</code> and appends the interpretation to <code>buf</code>.
+     *
+     * @param ch the escaped character
+     * @param i the offset
+     * @param buf the output buffer
+     * @param replaceText the original replace pattern
+     * @param foundText the found pattern to be replaced
+     * @return the new offset
+     * @since 3.4
+     */
+    private int interpretReplaceEscape(char ch, int i, StringBuffer buf, String replaceText, String foundText) {
+        int length= replaceText.length;
+        switch (ch) {
+            case 'r':
+                buf.append('\r');
+                break;
+            case 'n':
+                buf.append('\n');
+                break;
+            case 't':
+                buf.append('\t');
+                break;
+            case 'f':
+                buf.append('\f');
+                break;
+            case 'a':
+                buf.append("\u0007"c);
+                break;
+            case 'e':
+                buf.append("\u001B"c);
+                break;
+            case 'R': //see http://www.unicode.org/unicode/reports/tr18/#Line_Boundaries
+                buf.append(TextUtilities.getDefaultLineDelimiter(fDocument));
+                break;
+            /*
+             * \0 for octal is not supported in replace string, since it
+             * would conflict with capturing group \0, etc.
+             */
+            case '0':
+                buf.append('$').append(ch);
+                /*
+                 * See explanation in "Feature in java.util.regex.Matcher#replaceFirst(String)"
+                 * in interpretReplaceEscape(String) above.
+                 */
+                if (i + 1 < length) {
+                    char ch1= .charAt(replaceText, i + 1);
+                    if ('0' <= ch1 && ch1 <= '9') {
+                        buf.append('\\');
+                    }
+                }
+                break;
+
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+                buf.append('$').append(ch);
+                break;
+
+            case 'c':
+                if (i + 1 < length) {
+                    char ch1= .charAt(replaceText, i + 1);
+                    interpretRetainCase(buf, cast(wchar)(ch1 ^ 64));
+                    i++;
+                } else {
+                    String msg= TextMessages.getFormattedString("FindReplaceDocumentAdapter.illegalControlEscape", stringcast("\\c")); //$NON-NLS-1$ //$NON-NLS-2$
+                    throw new PatternSyntaxException(msg, replaceText, i);
+                }
+                break;
+
+            case 'x':
+                if (i + 2 < length) {
+                    int parsedInt;
+                    try {
+                        parsedInt= Integer.parseInt(replaceText.substring(i + 1, i + 3), 16);
+                        if (parsedInt < 0)
+                            throw new NumberFormatException("");
+                    } catch (NumberFormatException e) {
+                        String msg= TextMessages.getFormattedString("FindReplaceDocumentAdapter.illegalHexEscape", stringcast(replaceText.substring(i - 1, i + 3))); //$NON-NLS-1$
+                        throw new PatternSyntaxException(msg, replaceText, i);
+                    }
+                    interpretRetainCase(buf, cast(wchar) parsedInt);
+                    i+= 2;
+                } else {
+                    String msg= TextMessages.getFormattedString("FindReplaceDocumentAdapter.illegalHexEscape", stringcast(replaceText.substring(i - 1, length))); //$NON-NLS-1$
+                    throw new PatternSyntaxException(msg, replaceText, i);
+                }
+                break;
+
+            case 'u':
+                if (i + 4 < length) {
+                    int parsedInt;
+                    try {
+                        parsedInt= Integer.parseInt(replaceText.substring(i + 1, i + 5), 16);
+                        if (parsedInt < 0)
+                            throw new NumberFormatException("");
+                    } catch (NumberFormatException e) {
+                        String msg= TextMessages.getFormattedString("FindReplaceDocumentAdapter.illegalUnicodeEscape", stringcast(replaceText.substring(i - 1, i + 5))); //$NON-NLS-1$
+                        throw new PatternSyntaxException(msg, replaceText, i);
+                    }
+                    interpretRetainCase(buf, cast(wchar) parsedInt);
+                    i+= 4;
+                } else {
+                    String msg= TextMessages.getFormattedString("FindReplaceDocumentAdapter.illegalUnicodeEscape", stringcast(replaceText.substring(i - 1, length))); //$NON-NLS-1$
+                    throw new PatternSyntaxException(msg, replaceText, i);
+                }
+                break;
+
+            case 'C':
+                if(foundText.toUpperCase().equals(foundText)) // is whole match upper-case?
+                    fRetainCaseMode= RC_UPPER;
+                else if (foundText.toLowerCase().equals(foundText)) // is whole match lower-case?
+                    fRetainCaseMode= RC_LOWER;
+                else if(Character.isUpperCase(.charAt(foundText,0))) // is first character upper-case?
+                    fRetainCaseMode= RC_FIRSTUPPER;
+                else
+                    fRetainCaseMode= RC_MIXED;
+                break;
+
+            default:
+                // unknown escape k: append uninterpreted \k
+                buf.append('\\').append(ch);
+                break;
+        }
+        return i;
+    }
+
+    /**
+     * Converts a non-regex string to a pattern
+     * that can be used with the regex search engine.
+     *
+     * @param string the non-regex pattern
+     * @return the string converted to a regex pattern
+     */
+    private String asRegPattern(String string) {
+        StringBuffer out_= new StringBuffer(string.length);
+        bool quoting= false;
+
+        for (int i= 0, length= string.length; i < length; i++) {
+            char ch= .charAt(string, i);
+            if (ch is '\\') {
+                if (quoting) {
+                    out_.append("\\E"); //$NON-NLS-1$
+                    quoting= false;
+                }
+                out_.append("\\\\"); //$NON-NLS-1$
+                continue;
+            }
+            if (!quoting) {
+                out_.append("\\Q"); //$NON-NLS-1$
+                quoting= true;
+            }
+            out_.append(ch);
+        }
+        if (quoting)
+            out_.append("\\E"); //$NON-NLS-1$
+
+        return out_.toString();
+    }
+
+    /**
+     * Substitutes the previous match with the given text.
+     * Sends a <code>DocumentEvent</code> to all registered <code>IDocumentListener</code>.
+     *
+     * @param text the substitution text
+     * @param regExReplace if <code>true</code> <code>text</code> represents a regular expression
+     * @return the replace region or <code>null</code> if there was no match
+     * @throws BadLocationException if startOffset is an invalid document offset
+     * @throws IllegalStateException if a REPLACE or REPLACE_FIND operation is not preceded by a successful FIND operation
+     * @throws PatternSyntaxException if a regular expression has invalid syntax
+     *
+     * @see DocumentEvent
+     * @see IDocumentListener
+     */
+    public IRegion replace(String text, bool regExReplace)  {
+        return findReplace(REPLACE, -1, null, text, false, false, false, regExReplace);
+    }
+
+    // ---------- CharSequence implementation ----------
+
+    /*
+     * @see java.lang.CharSequence#length()
+     */
+    public int length() {
+        return fDocument.getLength();
+    }
+
+    /*
+     * @see java.lang.CharSequence#charAt(int)
+     */
+    public override char charAt(int index) {
+        try {
+            return fDocument.getChar(index);
+        } catch (BadLocationException e) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /*
+     * @see java.lang.CharSequence#subSequence(int, int)
+     */
+    public CharSequence subSequence(int start, int end) {
+        try {
+            return new StringCharSequence(fDocument.get(start, end - start));
+        } catch (BadLocationException e) {
+            throw new IndexOutOfBoundsException();
+        }
+    }
+
+    /*
+     * @see java.lang.Object#toString()
+     */
+    public override String toString() {
+        return fDocument.get();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/FindReplaceDocumentAdapterContentProposalProvider.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,523 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Cagatay Calli <ccalli@gmail.com> - [find/replace] retain caps when replacing - https://bugs.eclipse.org/bugs/show_bug.cgi?id=28949
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+import dwtx.jface.fieldassist.IContentProposal;
+import dwtx.jface.fieldassist.IContentProposalProvider;
+
+
+/**
+ * Content assist proposal provider for the {@link FindReplaceDocumentAdapter}.
+ * <p>
+ * Clients can subclass to provide additional proposals in case they are supported
+ * by their own find/replace mechanism.
+ * </p>
+ * <p>
+ * <strong>Note:</strong> Clients must not make any assumptions about the returned
+ * proposals. This can change from release to release to adapt to
+ * changes made in {@link FindReplaceDocumentAdapter}.
+ * </p>
+ *
+ * @since 3.4
+ */
+public class FindReplaceDocumentAdapterContentProposalProvider : IContentProposalProvider {
+
+
+    /**
+     * Proposal computer.
+     */
+    private static class ProposalComputer {
+
+        private static class Proposal : IContentProposal {
+
+            private String fContent;
+            private String fLabel;
+            private String fDescription;
+            private int fCursorPosition;
+
+            this(String content, String label, String description, int cursorPosition) {
+                fContent= content;
+                fLabel= label;
+                fDescription= description;
+                fCursorPosition= cursorPosition;
+            }
+
+            public String getContent() {
+                return fContent;
+            }
+
+            public String getLabel() {
+                return fLabel;
+            }
+
+            public String getDescription() {
+                return fDescription;
+            }
+
+            public int getCursorPosition() {
+                return fCursorPosition;
+            }
+        }
+
+
+        /**
+         * The whole regular expression.
+         */
+        private const String fExpression;
+        /**
+         * The document offset.
+         */
+        private const int fDocumentOffset;
+        /**
+         * The high-priority proposals.
+         */
+        private const ArrayList fPriorityProposals;
+        /**
+         * The low-priority proposals.
+         */
+        private const ArrayList fProposals;
+        /**
+         * <code>true</code> iff <code>fExpression</code> ends with an open escape.
+         */
+        private const bool fIsEscape;
+
+        /**
+         * Creates a new Proposal Computer.
+         * @param contents the contents of the subject control
+         * @param position the cursor position
+         */
+        public this(String contents, int position) {
+            fExpression= contents;
+            fDocumentOffset= position;
+            fPriorityProposals= new ArrayList();
+            fProposals= new ArrayList();
+
+            bool isEscape= false;
+            esc: for (int i= position - 1; i >= 0; i--) {
+                if (fExpression.charAt(i) is '\\')
+                    isEscape= !isEscape;
+                else
+                    break esc;
+            }
+            fIsEscape= isEscape;
+        }
+
+        /**
+         * Computes applicable proposals for the find field.
+         * @return the proposals
+         */
+        public IContentProposal[] computeFindProposals() {
+            //characters
+            addBsProposal("\\\\", RegExMessages.getString("displayString_bs_bs"), RegExMessages.getString("additionalInfo_bs_bs")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBracketProposal("\\0", 2, RegExMessages.getString("displayString_bs_0"), RegExMessages.getString("additionalInfo_bs_0")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBracketProposal("\\x", 2, RegExMessages.getString("displayString_bs_x"), RegExMessages.getString("additionalInfo_bs_x")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBracketProposal("\\u", 2, RegExMessages.getString("displayString_bs_u"), RegExMessages.getString("additionalInfo_bs_u")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\t", RegExMessages.getString("displayString_bs_t"), RegExMessages.getString("additionalInfo_bs_t")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\R", RegExMessages.getString("displayString_bs_R"), RegExMessages.getString("additionalInfo_bs_R")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\n", RegExMessages.getString("displayString_bs_n"), RegExMessages.getString("additionalInfo_bs_n")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\r", RegExMessages.getString("displayString_bs_r"), RegExMessages.getString("additionalInfo_bs_r")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\f", RegExMessages.getString("displayString_bs_f"), RegExMessages.getString("additionalInfo_bs_f")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\a", RegExMessages.getString("displayString_bs_a"), RegExMessages.getString("additionalInfo_bs_a")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\e", RegExMessages.getString("displayString_bs_e"), RegExMessages.getString("additionalInfo_bs_e")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBracketProposal("\\c", 2, RegExMessages.getString("displayString_bs_c"), RegExMessages.getString("additionalInfo_bs_c")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+            if (! fIsEscape)
+                addBracketProposal(".", 1, RegExMessages.getString("displayString_dot"), RegExMessages.getString("additionalInfo_dot")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\d", RegExMessages.getString("displayString_bs_d"), RegExMessages.getString("additionalInfo_bs_d")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\D", RegExMessages.getString("displayString_bs_D"), RegExMessages.getString("additionalInfo_bs_D")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\s", RegExMessages.getString("displayString_bs_s"), RegExMessages.getString("additionalInfo_bs_s")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\S", RegExMessages.getString("displayString_bs_S"), RegExMessages.getString("additionalInfo_bs_S")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\w", RegExMessages.getString("displayString_bs_w"), RegExMessages.getString("additionalInfo_bs_w")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\W", RegExMessages.getString("displayString_bs_W"), RegExMessages.getString("additionalInfo_bs_W")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+            // back reference
+            addBsProposal("\\", RegExMessages.getString("displayString_bs_i"), RegExMessages.getString("additionalInfo_bs_i")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+            //quoting
+            addBsProposal("\\", RegExMessages.getString("displayString_bs"), RegExMessages.getString("additionalInfo_bs")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\Q", RegExMessages.getString("displayString_bs_Q"), RegExMessages.getString("additionalInfo_bs_Q")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\E", RegExMessages.getString("displayString_bs_E"), RegExMessages.getString("additionalInfo_bs_E")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+            //character sets
+            if (! fIsEscape) {
+                addBracketProposal("[]", 1, RegExMessages.getString("displayString_set"), RegExMessages.getString("additionalInfo_set")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("[^]", 2, RegExMessages.getString("displayString_setExcl"), RegExMessages.getString("additionalInfo_setExcl")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("[-]", 1, RegExMessages.getString("displayString_setRange"), RegExMessages.getString("additionalInfo_setRange")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addProposal("&&", RegExMessages.getString("displayString_setInter"), RegExMessages.getString("additionalInfo_setInter")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            }
+            if (! fIsEscape && fDocumentOffset > 0 && fExpression.charAt(fDocumentOffset - 1) is '\\') {
+                addProposal("\\p{}", 3, RegExMessages.getString("displayString_posix"), RegExMessages.getString("additionalInfo_posix")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addProposal("\\P{}", 3, RegExMessages.getString("displayString_posixNot"), RegExMessages.getString("additionalInfo_posixNot")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            } else {
+                addBracketProposal("\\p{}", 3, RegExMessages.getString("displayString_posix"), RegExMessages.getString("additionalInfo_posix")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("\\P{}", 3, RegExMessages.getString("displayString_posixNot"), RegExMessages.getString("additionalInfo_posixNot")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            }
+
+            //boundary matchers
+            if (fDocumentOffset is 0) {
+                addPriorityProposal("^", RegExMessages.getString("displayString_start"), RegExMessages.getString("additionalInfo_start")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            } else if (fDocumentOffset is 1 && fExpression.charAt(0) is '^') {
+                addBracketProposal("^", 1, RegExMessages.getString("displayString_start"), RegExMessages.getString("additionalInfo_start")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            }
+            if (fDocumentOffset is fExpression.length()) {
+                addProposal("$", RegExMessages.getString("displayString_end"), RegExMessages.getString("additionalInfo_end")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            }
+            addBsProposal("\\b", RegExMessages.getString("displayString_bs_b"), RegExMessages.getString("additionalInfo_bs_b")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\B", RegExMessages.getString("displayString_bs_B"), RegExMessages.getString("additionalInfo_bs_B")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\A", RegExMessages.getString("displayString_bs_A"), RegExMessages.getString("additionalInfo_bs_A")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\G", RegExMessages.getString("displayString_bs_G"), RegExMessages.getString("additionalInfo_bs_G")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\Z", RegExMessages.getString("displayString_bs_Z"), RegExMessages.getString("additionalInfo_bs_Z")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            addBsProposal("\\z", RegExMessages.getString("displayString_bs_z"), RegExMessages.getString("additionalInfo_bs_z")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+            if (! fIsEscape) {
+                //capturing groups
+                addBracketProposal("()", 1, RegExMessages.getString("displayString_group"), RegExMessages.getString("additionalInfo_group")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+                //flags
+                addBracketProposal("(?)", 2, RegExMessages.getString("displayString_flag"), RegExMessages.getString("additionalInfo_flag")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("(?:)", 3, RegExMessages.getString("displayString_flagExpr"), RegExMessages.getString("additionalInfo_flagExpr")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+                //non-capturing group
+                addBracketProposal("(?:)", 3, RegExMessages.getString("displayString_nonCap"), RegExMessages.getString("additionalInfo_nonCap")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("(?>)", 3, RegExMessages.getString("displayString_atomicCap"), RegExMessages.getString("additionalInfo_atomicCap")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+                //look around
+                addBracketProposal("(?=)", 3, RegExMessages.getString("displayString_posLookahead"), RegExMessages.getString("additionalInfo_posLookahead")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("(?!)", 3, RegExMessages.getString("displayString_negLookahead"), RegExMessages.getString("additionalInfo_negLookahead")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("(?<=)", 4, RegExMessages.getString("displayString_posLookbehind"), RegExMessages.getString("additionalInfo_posLookbehind")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("(?<!)", 4, RegExMessages.getString("displayString_negLookbehind"), RegExMessages.getString("additionalInfo_negLookbehind")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+                //greedy quantifiers
+                addBracketProposal("?", 1, RegExMessages.getString("displayString_quest"), RegExMessages.getString("additionalInfo_quest")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("*", 1, RegExMessages.getString("displayString_star"), RegExMessages.getString("additionalInfo_star")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("+", 1, RegExMessages.getString("displayString_plus"), RegExMessages.getString("additionalInfo_plus")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("{}", 1, RegExMessages.getString("displayString_exact"), RegExMessages.getString("additionalInfo_exact")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("{,}", 1, RegExMessages.getString("displayString_least"), RegExMessages.getString("additionalInfo_least")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("{,}", 1, RegExMessages.getString("displayString_count"), RegExMessages.getString("additionalInfo_count")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+                //lazy quantifiers
+                addBracketProposal("??", 1, RegExMessages.getString("displayString_questLazy"), RegExMessages.getString("additionalInfo_questLazy")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("*?", 1, RegExMessages.getString("displayString_starLazy"), RegExMessages.getString("additionalInfo_starLazy")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("+?", 1, RegExMessages.getString("displayString_plusLazy"), RegExMessages.getString("additionalInfo_plusLazy")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("{}?", 1, RegExMessages.getString("displayString_exactLazy"), RegExMessages.getString("additionalInfo_exactLazy")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("{,}?", 1, RegExMessages.getString("displayString_leastLazy"), RegExMessages.getString("additionalInfo_leastLazy")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("{,}?", 1, RegExMessages.getString("displayString_countLazy"), RegExMessages.getString("additionalInfo_countLazy")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+                //possessive quantifiers
+                addBracketProposal("?+", 1, RegExMessages.getString("displayString_questPoss"), RegExMessages.getString("additionalInfo_questPoss")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("*+", 1, RegExMessages.getString("displayString_starPoss"), RegExMessages.getString("additionalInfo_starPoss")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("++", 1, RegExMessages.getString("displayString_plusPoss"), RegExMessages.getString("additionalInfo_plusPoss")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("{}+", 1, RegExMessages.getString("displayString_exactPoss"), RegExMessages.getString("additionalInfo_exactPoss")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("{,}+", 1, RegExMessages.getString("displayString_leastPoss"), RegExMessages.getString("additionalInfo_leastPoss")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("{,}+", 1, RegExMessages.getString("displayString_countPoss"), RegExMessages.getString("additionalInfo_countPoss")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+                //alternative
+                addBracketProposal("|", 1, RegExMessages.getString("displayString_alt"), RegExMessages.getString("additionalInfo_alt")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            }
+
+            fPriorityProposals.addAll(fProposals);
+            return arraycast!(IContentProposal)( fPriorityProposals.toArray());
+        }
+
+        /**
+         * Computes applicable proposals for the replace field.
+         * @return the proposals
+         */
+        public IContentProposal[] computeReplaceProposals() {
+            if (fDocumentOffset > 0 && '$' is fExpression.charAt(fDocumentOffset - 1)) {
+                addProposal("", RegExMessages.getString("displayString_dollar"), RegExMessages.getString("additionalInfo_dollar")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            } else {
+                if (! fIsEscape)
+                    addProposal("$", RegExMessages.getString("displayString_dollar"), RegExMessages.getString("additionalInfo_dollar")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBsProposal("\\", RegExMessages.getString("displayString_replace_cap"), RegExMessages.getString("additionalInfo_replace_cap")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBsProposal("\\", RegExMessages.getString("displayString_replace_bs"), RegExMessages.getString("additionalInfo_replace_bs")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBsProposal("\\R", RegExMessages.getString("displayString_replace_bs_R"), RegExMessages.getString("additionalInfo_replace_bs_R")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("\\x", 2, RegExMessages.getString("displayString_bs_x"), RegExMessages.getString("additionalInfo_bs_x")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("\\u", 2, RegExMessages.getString("displayString_bs_u"), RegExMessages.getString("additionalInfo_bs_u")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBsProposal("\\t", RegExMessages.getString("displayString_bs_t"), RegExMessages.getString("additionalInfo_bs_t")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBsProposal("\\n", RegExMessages.getString("displayString_replace_bs_n"), RegExMessages.getString("additionalInfo_replace_bs_n")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBsProposal("\\r", RegExMessages.getString("displayString_replace_bs_r"), RegExMessages.getString("additionalInfo_replace_bs_r")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBsProposal("\\f", RegExMessages.getString("displayString_bs_f"), RegExMessages.getString("additionalInfo_bs_f")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBsProposal("\\a", RegExMessages.getString("displayString_bs_a"), RegExMessages.getString("additionalInfo_bs_a")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBsProposal("\\e", RegExMessages.getString("displayString_bs_e"), RegExMessages.getString("additionalInfo_bs_e")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBracketProposal("\\c", 2, RegExMessages.getString("displayString_bs_c"), RegExMessages.getString("additionalInfo_bs_c")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                addBsProposal("\\C", RegExMessages.getString("displayString_replace_bs_C"), RegExMessages.getString("additionalInfo_replace_bs_C")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+            }
+            fPriorityProposals.addAll(fProposals);
+            return arraycast!(IContentProposal)( fPriorityProposals.toArray());
+        }
+
+        /**
+         * Adds a proposal.
+         *
+         * @param proposal the string to be inserted
+         * @param displayString the proposal's label
+         * @param additionalInfo the additional information
+         */
+        private void addProposal(String proposal, String displayString, String additionalInfo) {
+            fProposals.add(new Proposal(proposal, displayString, additionalInfo, proposal.length()));
+        }
+
+        /**
+         * Adds a proposal.
+         *
+         * @param proposal the string to be inserted
+         * @param cursorPosition the cursor position after insertion,
+         *      relative to the start of the proposal
+         * @param displayString the proposal's label
+         * @param additionalInfo the additional information
+         */
+        private void addProposal(String proposal, int cursorPosition, String displayString, String additionalInfo) {
+            fProposals.add(new Proposal(proposal, displayString, additionalInfo, cursorPosition));
+        }
+
+        /**
+         * Adds a proposal to the priority proposals list.
+         *
+         * @param proposal the string to be inserted
+         * @param displayString the proposal's label
+         * @param additionalInfo the additional information
+         */
+        private void addPriorityProposal(String proposal, String displayString, String additionalInfo) {
+            fPriorityProposals.add(new Proposal(proposal, displayString, additionalInfo, proposal.length()));
+        }
+
+        /**
+         * Adds a proposal. Ensures that existing pre- and postfixes are not duplicated.
+         *
+         * @param proposal the string to be inserted
+         * @param cursorPosition the cursor position after insertion,
+         *      relative to the start of the proposal
+         * @param displayString the proposal's label
+         * @param additionalInfo the additional information
+         */
+        private void addBracketProposal(String proposal, int cursorPosition, String displayString, String additionalInfo) {
+            String prolog= fExpression.substring(0, fDocumentOffset);
+            if (! fIsEscape && prolog.endsWith("\\") && proposal.startsWith("\\")) { //$NON-NLS-1$//$NON-NLS-2$
+                fProposals.add(new Proposal(proposal, displayString, additionalInfo, cursorPosition));
+                return;
+            }
+            for (int i= 1; i <= cursorPosition; i++) {
+                String prefix= proposal.substring(0, i);
+                if (prolog.endsWith(prefix)) {
+                    String postfix= proposal.substring(cursorPosition);
+                    String epilog= fExpression.substring(fDocumentOffset);
+                    if (epilog.startsWith(postfix)) {
+                        fPriorityProposals.add(new Proposal(proposal.substring(i, cursorPosition), displayString, additionalInfo, cursorPosition-i));
+                    } else {
+                        fPriorityProposals.add(new Proposal(proposal.substring(i), displayString, additionalInfo, cursorPosition-i));
+                    }
+                    return;
+                }
+            }
+            fProposals.add(new Proposal(proposal, displayString, additionalInfo, cursorPosition));
+        }
+
+        /**
+         * Adds a proposal that starts with a backslash.
+         * Ensures that the backslash is not repeated if already typed.
+         *
+         * @param proposal the string to be inserted
+         * @param displayString the proposal's label
+         * @param additionalInfo the additional information
+         */
+        private void addBsProposal(String proposal, String displayString, String additionalInfo) {
+            String prolog= fExpression.substring(0, fDocumentOffset);
+            int position= proposal.length();
+            // If the string already contains the backslash, do not include in the proposal
+            if (prolog.endsWith("\\")) { //$NON-NLS-1$
+                position--;
+                proposal= proposal.substring(1);
+            }
+
+            if (fIsEscape) {
+                fPriorityProposals.add(new Proposal(proposal, displayString, additionalInfo, position));
+            } else {
+                addProposal(proposal, position, displayString, additionalInfo);
+            }
+        }
+    }
+
+    /**
+     * <code>true</code> iff the processor is for the find field.
+     * <code>false</code> iff the processor is for the replace field.
+     */
+    private const bool fIsFind;
+
+
+    /**
+     * Creates a new completion proposal provider.
+     *
+     * @param isFind <code>true</code> if the provider is used for the 'find' field
+     *                  <code>false</code> if the provider is used for the 'replace' field
+     */
+    public this(bool isFind) {
+        fIsFind= isFind;
+    }
+
+    /*
+     * @see dwtx.jface.fieldassist.IContentProposalProvider#getProposals(java.lang.String, int)
+     */
+    public IContentProposal [] getProposals(String contents, int position) {
+        if (fIsFind)
+            return (new ProposalComputer(contents, position)).computeFindProposals();
+        return (new ProposalComputer(contents, position)).computeReplaceProposals();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/GapTextStore.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,536 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.GapTextStore;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Implements a gap managing text store. The gap text store relies on the assumption that
+ * consecutive changes to a document are co-located. The start of the gap is always moved to the
+ * location of the last change.
+ * <p>
+ * <strong>Performance:</strong> Typing-style changes perform in constant time unless re-allocation
+ * becomes necessary. Generally, a change that does not cause re-allocation will cause at most one
+ * {@linkplain System#arraycopy(Object, int, Object, int, int) arraycopy} operation of a length of
+ * about <var>d</var>, where <var>d</var> is the distance from the previous change. Let <var>a(x)</var>
+ * be the algorithmic performance of an <code>arraycopy</code> operation of the length <var>x</var>,
+ * then such a change then performs in <i>O(a(x))</i>,
+ * {@linkplain #get(int, int) get(int, <var>length</var>)} performs in <i>O(a(length))</i>,
+ * {@link #get(int)} in <i>O(1)</i>.
+ * <p>
+ * How frequently the array needs re-allocation is controlled by the constructor parameters.
+ * </p>
+ * <p>
+ * This class is not intended to be subclassed.
+ * </p>
+ *
+ * @see CopyOnWriteTextStore for a copy-on-write text store wrapper
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class GapTextStore : ITextStore {
+    /**
+     * The minimum gap size allocated when re-allocation occurs.
+     * @since 3.3
+     */
+    private const int fMinGapSize;
+    /**
+     * The maximum gap size allocated when re-allocation occurs.
+     * @since 3.3
+     */
+    private const int fMaxGapSize;
+    /**
+     * The multiplier to compute the array size from the content length
+     * (1&nbsp;&lt;=&nbsp;fSizeMultiplier&nbsp;&lt;=&nbsp;2).
+     *
+     * @since 3.3
+     */
+    private const float fSizeMultiplier;
+
+    /** The store's content */
+    private char[] fContent;
+    /** Starting index of the gap */
+    private int fGapStart= 0;
+    /** End index of the gap */
+    private int fGapEnd= 0;
+    /**
+     * The current high water mark. If a change would cause the gap to grow larger than this, the
+     * array is re-allocated.
+     * @since 3.3
+     */
+    private int fThreshold= 0;
+
+    /**
+     * Creates a new empty text store using the specified low and high watermarks.
+     *
+     * @param lowWatermark unused - at the lower bound, the array is only resized when the content
+     *        does not fit
+     * @param highWatermark if the gap is ever larger than this, it will automatically be shrunken
+     *        (&gt;=&nbsp;0)
+     * @deprecated use {@link GapTextStore#GapTextStore(int, int, float)} instead
+     */
+    public this(int lowWatermark, int highWatermark) {
+        /*
+         * Legacy constructor. The API contract states that highWatermark is the upper bound for the
+         * gap size. Albeit this contract was not previously adhered to, it is now: The allocated
+         * gap size is fixed at half the highWatermark. Since the threshold is always twice the
+         * allocated gap size, the gap will never grow larger than highWatermark. Previously, the
+         * gap size was initialized to highWatermark, causing re-allocation if the content length
+         * shrunk right after allocation. The fixed gap size is now only half of the previous value,
+         * circumventing that problem (there was no API contract specifying the initial gap size).
+         *
+         * The previous implementation did not allow the gap size to become smaller than
+         * lowWatermark, which doesn't make any sense: that area of the gap was simply never ever
+         * used.
+         */
+        this(highWatermark / 2, highWatermark / 2, 0f);
+    }
+
+    /**
+     * Equivalent to
+     * {@linkplain GapTextStore#GapTextStore(int, int, float) new GapTextStore(256, 4096, 0.1f)}.
+     *
+     * @since 3.3
+     */
+    public this() {
+        this(256, 4096, 0.1f);
+    }
+
+    /**
+     * Creates an empty text store that uses re-allocation thresholds relative to the content
+     * length. Re-allocation is controlled by the <em>gap factor</em>, which is the quotient of
+     * the gap size and the array size. Re-allocation occurs if a change causes the gap factor to go
+     * outside <code>[0,&nbsp;maxGapFactor]</code>. When re-allocation occurs, the array is sized
+     * such that the gap factor is <code>0.5 * maxGapFactor</code>. The gap size computed in this
+     * manner is bounded by the <code>minSize</code> and <code>maxSize</code> parameters.
+     * <p>
+     * A <code>maxGapFactor</code> of <code>0</code> creates a text store that never has a gap
+     * at all (if <code>minSize</code> is 0); a <code>maxGapFactor</code> of <code>1</code>
+     * creates a text store that doubles its size with every re-allocation and that never shrinks.
+     * </p>
+     * <p>
+     * The <code>minSize</code> and <code>maxSize</code> parameters are absolute bounds to the
+     * allocated gap size. Use <code>minSize</code> to avoid frequent re-allocation for small
+     * documents. Use <code>maxSize</code> to avoid a huge gap being allocated for large
+     * documents.
+     * </p>
+     *
+     * @param minSize the minimum gap size to allocate (&gt;=&nbsp;0; use 0 for no minimum)
+     * @param maxSize the maximum gap size to allocate (&gt;=&nbsp;minSize; use
+     *        {@link Integer#MAX_VALUE} for no maximum)
+     * @param maxGapFactor is the maximum fraction of the array that is occupied by the gap (<code>0&nbsp;&lt;=&nbsp;maxGapFactor&nbsp;&lt;=&nbsp;1</code>)
+     * @since 3.3
+     */
+    public this(int minSize, int maxSize, float maxGapFactor) {
+        Assert.isLegal(0f <= maxGapFactor && maxGapFactor <= 1f);
+        Assert.isLegal(0 <= minSize && minSize <= maxSize);
+        fMinGapSize= minSize;
+        fMaxGapSize= maxSize;
+        fSizeMultiplier= 1 / (1 - maxGapFactor / 2);
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#get(int)
+     */
+    public final char get(int offset) {
+        if (offset < fGapStart)
+            return fContent[offset];
+
+        return fContent[offset + gapSize()];
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#get(int, int)
+     */
+    public final String get(int offset, int length) {
+        if (fGapStart <= offset)
+            return new_String(fContent, offset + gapSize() , length);
+
+        final int end= offset + length;
+
+        if (end <= fGapStart)
+            return new_String(fContent, offset, length);
+
+        StringBuffer buf= new StringBuffer(length);
+        buf.append(fContent[ offset .. fGapStart ]);
+        buf.append(fContent[ fGapEnd .. end - fGapStart + fGapEnd ]);
+        return buf.toString();
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#getLength()
+     */
+    public final int getLength() {
+        return fContent.length - gapSize();
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#set(java.lang.String)
+     */
+    public final void set(String text) {
+        /*
+         * Moves the gap to the end of the content. There is no sensible prediction of where the
+         * next change will occur, but at least the next change will not trigger re-allocation. This
+         * is especially important when using the GapTextStore within a CopyOnWriteTextStore, where
+         * the GTS is only initialized right before a modification.
+         */
+        replace(0, getLength(), text);
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#replace(int, int, java.lang.String)
+     */
+    public final void replace(int offset, int length, String text) {
+        if (text is null) {
+            adjustGap(offset, length, 0);
+        } else {
+            int textLength= text.length;
+            adjustGap(offset, length, textLength);
+            if (textLength !is 0)
+                text.getChars(0, textLength, fContent, offset);
+        }
+    }
+
+    /**
+     * Moves the gap to <code>offset + add</code>, moving any content after
+     * <code>offset + remove</code> behind the gap. The gap size is kept between 0 and
+     * {@link #fThreshold}, leading to re-allocation if needed. The content between
+     * <code>offset</code> and <code>offset + add</code> is undefined after this operation.
+     *
+     * @param offset the offset at which a change happens
+     * @param remove the number of character which are removed or overwritten at <code>offset</code>
+     * @param add the number of character which are inserted or overwriting at <code>offset</code>
+     */
+    private void adjustGap(int offset, int remove, int add) {
+        final int oldGapSize= gapSize();
+        final int newGapSize= oldGapSize - add + remove;
+        final bool reuseArray= 0 <= newGapSize && newGapSize <= fThreshold;
+
+        final int newGapStart= offset + add;
+        int newGapEnd;
+
+        if (reuseArray)
+            newGapEnd= moveGap(offset, remove, oldGapSize, newGapSize, newGapStart);
+        else
+            newGapEnd= reallocate(offset, remove, oldGapSize, newGapSize, newGapStart);
+
+        fGapStart= newGapStart;
+        fGapEnd= newGapEnd;
+    }
+
+    /**
+     * Moves the gap to <code>newGapStart</code>.
+     *
+     * @param offset the change offset
+     * @param remove the number of removed / overwritten characters
+     * @param oldGapSize the old gap size
+     * @param newGapSize the gap size after the change
+     * @param newGapStart the offset in the array to move the gap to
+     * @return the new gap end
+     * @since 3.3
+     */
+    private int moveGap(int offset, int remove, int oldGapSize, int newGapSize, int newGapStart) {
+        /*
+         * No re-allocation necessary. The area between the change offset and gap can be copied
+         * in at most one operation. Don't copy parts that will be overwritten anyway.
+         */
+        final int newGapEnd= newGapStart + newGapSize;
+        if (offset < fGapStart) {
+            int afterRemove= offset + remove;
+            if (afterRemove < fGapStart) {
+                final int betweenSize= fGapStart - afterRemove;
+                arrayCopy(afterRemove, fContent, newGapEnd, betweenSize);
+            }
+            // otherwise, only the gap gets enlarged
+        } else {
+            final int offsetShifted= offset + oldGapSize;
+            final int betweenSize= offsetShifted - fGapEnd; // in the typing case, betweenSize is 0
+            arrayCopy(fGapEnd, fContent, fGapStart, betweenSize);
+        }
+        return newGapEnd;
+    }
+
+    /**
+     * Reallocates a new array and copies the data from the previous one.
+     *
+     * @param offset the change offset
+     * @param remove the number of removed / overwritten characters
+     * @param oldGapSize the old gap size
+     * @param newGapSize the gap size after the change if no re-allocation would occur (can be negative)
+     * @param newGapStart the offset in the array to move the gap to
+     * @return the new gap end
+     * @since 3.3
+     */
+    private int reallocate(int offset, int remove, int oldGapSize, int newGapSize, int newGapStart) {
+        // the new content length (without any gap)
+        final int newLength= fContent.length - newGapSize;
+        // the new array size based on the gap factor
+        int newArraySize= cast(int) (newLength * fSizeMultiplier);
+        newGapSize= newArraySize - newLength;
+
+        // bound the gap size within min/max
+        if (newGapSize < fMinGapSize) {
+            newGapSize= fMinGapSize;
+            newArraySize= newLength + newGapSize;
+        } else if (newGapSize > fMaxGapSize) {
+            newGapSize= fMaxGapSize;
+            newArraySize= newLength + newGapSize;
+        }
+
+        // the upper threshold is always twice the gapsize
+        fThreshold= newGapSize * 2;
+        final char[] newContent= allocate(newArraySize);
+        final int newGapEnd= newGapStart + newGapSize;
+
+        /*
+         * Re-allocation: The old content can be copied in at most 3 operations to the newly allocated
+         * array. Either one of change offset and the gap may come first.
+         * - unchanged area before the change offset / gap
+         * - area between the change offset and the gap (either one may be first)
+         * - rest area after the change offset / after the gap
+         */
+        if (offset < fGapStart) {
+            // change comes before gap
+            arrayCopy(0, newContent, 0, offset);
+            int afterRemove= offset + remove;
+            if (afterRemove < fGapStart) {
+                // removal is completely before the gap
+                final int betweenSize= fGapStart - afterRemove;
+                arrayCopy(afterRemove, newContent, newGapEnd, betweenSize);
+                final int restSize= fContent.length - fGapEnd;
+                arrayCopy(fGapEnd, newContent, newGapEnd + betweenSize, restSize);
+            } else {
+                // removal encompasses the gap
+                afterRemove += oldGapSize;
+                final int restSize= fContent.length - afterRemove;
+                arrayCopy(afterRemove, newContent, newGapEnd, restSize);
+            }
+        } else {
+            // gap comes before change
+            arrayCopy(0, newContent, 0, fGapStart);
+            final int offsetShifted= offset + oldGapSize;
+            final int betweenSize= offsetShifted - fGapEnd;
+            arrayCopy(fGapEnd, newContent, fGapStart, betweenSize);
+            final int afterRemove= offsetShifted + remove;
+            final int restSize= fContent.length - afterRemove;
+            arrayCopy(afterRemove, newContent, newGapEnd, restSize);
+        }
+
+        fContent= newContent;
+        return newGapEnd;
+    }
+
+    /**
+     * Allocates a new <code>char[size]</code>.
+     *
+     * @param size the length of the new array.
+     * @return a newly allocated char array
+     * @since 3.3
+     */
+    private char[] allocate(int size) {
+        return new char[size];
+    }
+
+    /*
+     * Executes System.arraycopy if length !is 0. A length < 0 cannot happen -> don't hide coding
+     * errors by checking for negative lengths.
+     * @since 3.3
+     */
+    private void arrayCopy(int srcPos, char[] dest, int destPos, int length) {
+        if (length !is 0)
+            System.arraycopy(fContent, srcPos, dest, destPos, length);
+    }
+
+    /**
+     * Returns the gap size.
+     *
+     * @return the gap size
+     * @since 3.3
+     */
+    private int gapSize() {
+        return fGapEnd - fGapStart;
+    }
+
+    /**
+     * Returns a copy of the content of this text store.
+     * For internal use only.
+     *
+     * @return a copy of the content of this text store
+     */
+    protected String getContentAsString() {
+        return new_String(fContent);
+    }
+
+    /**
+     * Returns the start index of the gap managed by this text store.
+     * For internal use only.
+     *
+     * @return the start index of the gap managed by this text store
+     */
+    protected int getGapStartIndex() {
+        return fGapStart;
+    }
+
+    /**
+     * Returns the end index of the gap managed by this text store.
+     * For internal use only.
+     *
+     * @return the end index of the gap managed by this text store
+     */
+    protected int getGapEndIndex() {
+        return fGapEnd;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IAutoEditStrategy.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IAutoEditStrategy;
+
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * An auto edit strategy can adapt changes that will be applied to
+ * a text viewer's document. The strategy is informed by the text viewer
+ * about each upcoming change in form of a document command. By manipulating
+ * this document command, the strategy can influence in which way the text
+ * viewer's document is changed. Clients may implement this interface.
+ *
+ * @since 2.1
+ */
+public interface IAutoEditStrategy {
+
+    /**
+     * Allows the strategy to manipulate the document command.
+     *
+     * @param document the document that will be changed
+     * @param command the document command describing the change
+     */
+    void customizeDocumentCommand(IDocument document, DocumentCommand command);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IAutoIndentStrategy.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IAutoIndentStrategy;
+
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Exists for backward compatibility.
+ *
+ * @deprecated since 3.0, use <code>IAutoEditStrategy</code> directly
+ */
+public interface IAutoIndentStrategy : IAutoEditStrategy {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDelayedInputChangeProvider.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IDelayedInputChangeProvider;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A delayed input change provider notifies the registered
+ * {@link IInputChangedListener} about input changes that occur after the normal
+ * operation of the provider.
+ * <p>
+ * Clients can implement that interface and its extension interfaces.</p>
+ * 
+ * @since 3.4
+ */
+public interface IDelayedInputChangeProvider {
+
+    /**
+     * Sets or clears the delayed input change listener.
+     * 
+     * @param inputChangeListener the new delayed input change listener, or
+     *        <code>null</code> if none
+     * @since 3.4
+     */
+    void setDelayedInputChangeListener(IInputChangedListener inputChangeListener);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocument.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,663 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IDocument;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * An <code>IDocument</code> represents text providing support for
+ * <ul>
+ * <li> text manipulation
+ * <li> positions
+ * <li> partitions
+ * <li> line information
+ * <li> document change listeners
+ * <li> document partition change listeners
+ * </ul>
+ *
+ * A document allows to set its content and to manipulate it. For manipulation
+ * a document provides the <code>replace</code> method which substitutes a given
+ * string for a specified text range in the document. On each document change, all
+ * registered document listeners are informed exactly once.
+ * <p>
+ * Positions are stickers to the document's text that are updated when the
+ * document is changed. Positions are updated by {@link dwtx.jface.text.IPositionUpdater}s. Position
+ * updaters are managed as a list. The list defines the sequence in which position
+ * updaters are invoked. This way, position updaters may rely on each other.
+ * Positions are grouped into categories.  A category is a ordered list of positions.
+ * the document defines the order of position in a category based on the position's offset
+ * based on the implementation of the method <code>computeIndexInCategory</code>.
+ * Each document must support a default position category whose name is specified by this
+ * interface.</p>
+ * <p>
+ * A document can be considered consisting of a sequence of not overlapping partitions.
+ * A partition is defined by its offset, its length, and its type. Partitions are
+ * updated on every document manipulation and ensured to be up-to-date when the document
+ * listeners are informed. A document uses an <code>IDocumentPartitioner</code> to
+ * manage its partitions. A document may be unpartitioned which happens when there is no
+ * partitioner. In this case, the document is considered as one single partition of a
+ * default type. The default type is specified by this interface. If a document change
+ * changes the document's partitioning all registered partitioning listeners are
+ * informed exactly once. The extension interface {@link dwtx.jface.text.IDocumentExtension3}
+ * introduced in version 3.0 extends the concept of partitions and allows a document to
+ * not only manage one but multiple partitioning. Each partitioning has an id which must
+ * be used to refer to a particular partitioning.</p>
+ * <p>
+ * An <code>IDocument</code> provides methods to map line numbers and character
+ * positions onto each other based on the document's line delimiters. When moving text
+ * between documents using different line delimiters, the text must be converted to
+ * use the target document's line delimiters.</p>
+ * <p>
+ * An <code>IDocument</code> does not care about mixed line delimiters. Clients who
+ * want to ensure a single line delimiter in their document should use the line
+ * delimiter returned by {@link dwtx.jface.text.TextUtilities#getDefaultLineDelimiter(IDocument)}.</p>
+ * <p>
+ * <code>IDocument</code> throws <code>BadLocationException</code> if the parameters of
+ * queries or manipulation requests are not inside the bounds of the document. The purpose
+ * of this style of exception handling is
+ * <ul>
+ * <li> prepare document for multi-thread access
+ * <li> allow clients to implement backtracking recovery methods
+ * <li> prevent clients from up-front contract checking when dealing with documents.
+ * </ul></p>
+ * <p>
+ * A document support for searching has deprecated since version 3.0. The recommended way
+ * for searching is to use a {@link dwtx.jface.text.FindReplaceDocumentAdapter}.</p>
+ * <p>
+ * In order to provide backward compatibility for clients of <code>IDocument</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces
+ * exist:
+ * <ul>
+ * <li> {@link dwtx.jface.text.IDocumentExtension} since version 2.0 introducing the concept
+ *      of post notification replaces in order to allow document listeners to manipulate the document
+ *      while receiving a document change notification </li>
+ * <li> {@link dwtx.jface.text.IDocumentExtension2} since version 2.1 introducing configuration
+ *      methods for post notification replaces and document change notification. </li>
+ * <li> {@link dwtx.jface.text.IDocumentExtension3} since version 3.0 replacing the original
+ *      partitioning concept by allowing multiple partitionings at the same time and introducing zero-
+ *      length partitions in conjunction with the distinction between open and closed partitions. </li>
+ * <li> {@link dwtx.jface.text.IDocumentExtension4} since version 3.1 introducing the
+ *      concept of rewrite sessions. A rewrite session is a sequence of document replace operations
+ *      that form a semantic unit. It also introduces a modification stamp and the ability to
+ *      set the initial line delimiter and to query the default line delimiter.</li>
+ * </ul></p>
+ * <p>
+ * Clients may implement this interface and its extension interfaces or use the default
+ * implementation provided by <code>AbstractDocument</code> and <code>Document</code>.</p>
+ *
+ * @see dwtx.jface.text.IDocumentExtension
+ * @see dwtx.jface.text.IDocumentExtension2
+ * @see dwtx.jface.text.IDocumentExtension3
+ * @see dwtx.jface.text.IDocumentExtension4
+ * @see dwtx.jface.text.Position
+ * @see dwtx.jface.text.IPositionUpdater
+ * @see dwtx.jface.text.IDocumentPartitioner
+ * @see dwtx.jface.text.ILineTracker
+ * @see dwtx.jface.text.IDocumentListener
+ * @see dwtx.jface.text.IDocumentPartitioningListener
+ */
+public interface IDocument {
+
+
+    /**
+     * The identifier of the default position category.
+     */
+    final static String DEFAULT_CATEGORY= "__dflt_position_category"; //$NON-NLS-1$
+
+    /**
+     * The identifier of the default partition content type.
+     */
+    final static String DEFAULT_CONTENT_TYPE= "__dftl_partition_content_type"; //$NON-NLS-1$
+
+
+
+
+    /* --------------- text access and manipulation --------------------------- */
+
+    /**
+     * Returns the character at the given document offset in this document.
+     *
+     * @param offset a document offset
+     * @return the character at the offset
+     * @exception BadLocationException if the offset is invalid in this document
+     */
+    char getChar(int offset) ;
+
+    /**
+     * Returns the number of characters in this document.
+     *
+     * @return the number of characters in this document
+     */
+    int getLength();
+
+    /**
+     * Returns this document's complete text.
+     *
+     * @return the document's complete text
+     */
+    String get();
+
+    /**
+     * Returns this document's text for the specified range.
+     *
+     * @param offset the document offset
+     * @param length the length of the specified range
+     * @return the document's text for the specified range
+     * @exception BadLocationException if the range is invalid in this document
+     */
+    String get(int offset, int length) ;
+
+    /**
+     * Replaces the content of the document with the given text.
+     * Sends a <code>DocumentEvent</code> to all registered <code>IDocumentListener</code>.
+     * This method is a convenience method for <code>replace(0, getLength(), text)</code>.
+     *
+     * @param text the new content of the document
+     *
+     * @see DocumentEvent
+     * @see IDocumentListener
+     */
+    void set(String text);
+
+    /**
+     * Substitutes the given text for the specified document range.
+     * Sends a <code>DocumentEvent</code> to all registered <code>IDocumentListener</code>.
+     *
+     * @param offset the document offset
+     * @param length the length of the specified range
+     * @param text the substitution text
+     * @exception BadLocationException if the offset is invalid in this document
+     *
+     * @see DocumentEvent
+     * @see IDocumentListener
+     */
+    void replace(int offset, int length, String text) ;
+
+    /**
+     * Registers the document listener with the document. After registration
+     * the IDocumentListener is informed about each change of this document.
+     * If the listener is already registered nothing happens.<p>
+     * An <code>IDocumentListener</code> may call back to this method
+     * when being inside a document notification.
+     *
+     * @param listener the listener to be registered
+     */
+    void addDocumentListener(IDocumentListener listener);
+
+    /**
+     * Removes the listener from the document's list of document listeners.
+     * If the listener is not registered with the document nothing happens.<p>
+     * An <code>IDocumentListener</code> may call back to this method
+     * when being inside a document notification.
+     *
+     * @param listener the listener to be removed
+     */
+    void removeDocumentListener(IDocumentListener listener);
+
+    /**
+     * Adds the given document listener as one which is notified before
+     * those document listeners added with <code>addDocumentListener</code>
+     * are notified. If the given listener is also registered using
+     * <code>addDocumentListener</code> it will be notified twice.
+     * If the listener is already registered nothing happens.<p>
+     *
+     * This method is not for public use.
+     *
+     * @param documentAdapter the listener to be added as pre-notified document listener
+     *
+     * @see #removePrenotifiedDocumentListener(IDocumentListener)
+     */
+    void addPrenotifiedDocumentListener(IDocumentListener documentAdapter);
+
+    /**
+     * Removes the given document listener from the document's list of
+     * pre-notified document listeners. If the listener is not registered
+     * with the document nothing happens. <p>
+     *
+     * This method is not for public use.
+     *
+     * @param documentAdapter the listener to be removed
+     *
+     * @see #addPrenotifiedDocumentListener(IDocumentListener)
+     */
+    void removePrenotifiedDocumentListener(IDocumentListener documentAdapter);
+
+
+
+    /* -------------------------- positions ----------------------------------- */
+
+    /**
+     * Adds a new position category to the document. If the position category
+     * already exists nothing happens.
+     *
+     * @param category the category to be added
+     */
+    void addPositionCategory(String category);
+
+    /**
+     * Deletes the position category from the document. All positions
+     * in this category are thus deleted as well.
+     *
+     * @param category the category to be removed
+     * @exception BadPositionCategoryException if category is undefined in this document
+     */
+    void removePositionCategory(String category) ;
+
+    /**
+     * Returns all position categories of this document. This
+     * includes the default position category.
+     *
+     * @return the document's position categories
+     */
+    String[] getPositionCategories();
+
+    /**
+     * Checks the presence of the specified position category.
+     *
+     * @param category the category to check
+     * @return <code>true</code> if category is defined
+     */
+    bool containsPositionCategory(String category);
+
+    /**
+     * Adds the position to the document's default position category.
+     * This is a convenience method for <code>addPosition(DEFAULT_CATEGORY, position)</code>.
+     *
+     * @param position the position to be added
+     * @exception BadLocationException if position describes an invalid range in this document
+     */
+    void addPosition(Position position) ;
+
+    /**
+     * Removes the given position from the document's default position category.
+     * This is a convenience method for <code>removePosition(DEFAULT_CATEGORY, position)</code>.
+     *
+     * @param position the position to be removed
+     */
+    void removePosition(Position position);
+
+    /**
+     * Adds the position to the specified position category of the document.
+     * Positions may be added multiple times. The order of the category is
+     * maintained.
+     * <p>
+     * <strong>Note:</strong> The position is only updated on each change
+     * applied to the document if a {@link IPositionUpdater} has been
+     * registered that handles the given category.
+     * </p>
+     *
+     * @param category the category to which to add
+     * @param position the position to be added
+     * @throws BadLocationException if position describes an invalid range in this document
+     * @throws BadPositionCategoryException if the category is undefined in this document
+     */
+    void addPosition(String category, Position position);
+
+    /**
+     * Removes the given position from the specified position category.
+     * If the position is not part of the specified category nothing happens.
+     * If the position has been added multiple times, only the first occurrence is deleted.
+     *
+     * @param category the category from which to delete
+     * @param position the position to be deleted
+     * @exception BadPositionCategoryException if category is undefined in this document
+     */
+    void removePosition(String category, Position position) ;
+
+    /**
+     * Returns all positions of the given position category.
+     * The positions are ordered according to the category's order.
+     * Manipulating this list does not affect the document, but manipulating the
+     * position does affect the document.
+     *
+     * @param category the category
+     * @return the list of all positions
+     * @exception BadPositionCategoryException if category is undefined in this document
+     */
+    Position[] getPositions(String category) ;
+
+    /**
+     * Determines whether a position described by the parameters is managed by this document.
+     *
+     * @param category the category to check
+     * @param offset the offset of the position to find
+     * @param length the length of the position to find
+     * @return <code>true</code> if position is found
+     */
+    bool containsPosition(String category, int offset, int length);
+
+    /**
+     * Computes the index at which a <code>Position</code> with the
+     * specified offset would be inserted into the given category. As the
+     * ordering inside a category only depends on the offset, the index must be
+     * chosen to be the first of all positions with the same offset.
+     *
+     * @param category the category in which would be added
+     * @param offset the position offset to be considered
+     * @return the index into the category
+     * @exception BadLocationException if offset is invalid in this document
+     * @exception BadPositionCategoryException if category is undefined in this document
+     */
+    int computeIndexInCategory(String category, int offset);
+
+    /**
+     * Appends a new position updater to the document's list of position updaters.
+     * Position updaters may be added multiple times.<p>
+     * An <code>IPositionUpdater</code> may call back to this method
+     * when being inside a document notification.
+     *
+     * @param updater the updater to be added
+     */
+    void addPositionUpdater(IPositionUpdater updater);
+
+    /**
+     * Removes the position updater from the document's list of position updaters.
+     * If the position updater has multiple occurrences only the first occurrence is
+     * removed. If the position updater is not registered with this document, nothing
+     * happens.<p>
+     * An <code>IPositionUpdater</code> may call back to this method
+     * when being inside a document notification.
+     *
+     * @param updater the updater to be removed
+     */
+    void removePositionUpdater(IPositionUpdater updater);
+
+    /**
+     * Inserts the position updater at the specified index in the document's
+     * list of position updaters. Positions updaters may be inserted multiple times.<p>
+     * An <code>IPositionUpdater</code> may call back to this method
+     * when being inside a document notification.
+     *
+     * @param updater the updater to be inserted
+     * @param index the index in the document's updater list
+     */
+    void insertPositionUpdater(IPositionUpdater updater, int index);
+
+    /**
+     * Returns the list of position updaters attached to the document.
+     *
+     * @return the list of position updaters
+     */
+    IPositionUpdater[] getPositionUpdaters();
+
+
+
+
+    /* -------------------------- partitions ---------------------------------- */
+
+    /**
+     * Returns the set of legal content types of document partitions.
+     * This set can be empty. The set can contain more content types than
+     * contained by the result of <code>getPartitioning(0, getLength())</code>.
+     * <p>
+     * Use {@link IDocumentExtension3#getLegalContentTypes(String)} when the document
+     * supports multiple partitionings. In that case this method is equivalent to:
+     * <pre>
+     *    IDocumentExtension3 extension= cast(IDocumentExtension3) document;
+     *    return extension.getLegalContentTypes(IDocumentExtension3.DEFAULT_PARTITIONING);
+     * </pre>
+     *
+     * @return the set of legal content types
+     */
+    String[] getLegalContentTypes();
+
+    /**
+     * Returns the type of the document partition containing the given offset.
+     * This is a convenience method for <code>getPartition(offset).getType()</code>.
+     * <p>
+     * Use {@link IDocumentExtension3#getContentType(String, int, bool)} when
+     * the document supports multiple partitionings. In that case this method is
+     * equivalent to:
+     * <pre>
+     *    IDocumentExtension3 extension= cast(IDocumentExtension3) document;
+     *    return extension.getContentType(IDocumentExtension3.DEFAULT_PARTITIONING, offset, false);
+     * </pre>
+     *
+     * @param offset the document offset
+     * @return the partition type
+     * @exception BadLocationException if offset is invalid in this document
+     */
+    String getContentType(int offset) ;
+
+    /**
+     * Returns the document partition in which the position is located.
+     * <p>
+     * Use {@link IDocumentExtension3#getPartition(String, int, bool)} when
+     * the document supports multiple partitionings. In that case this method is
+     * equivalent:
+     * <pre>
+     *    IDocumentExtension3 extension= cast(IDocumentExtension3) document;
+     *    return extension.getPartition(IDocumentExtension3.DEFAULT_PARTITIONING, offset, false);
+     * </pre>
+     *
+     * @param offset the document offset
+     * @return a specification of the partition
+     * @exception BadLocationException if offset is invalid in this document
+     */
+    ITypedRegion getPartition(int offset) ;
+
+    /**
+     * Computes the partitioning of the given document range using the
+     * document's partitioner.
+     * <p>
+     * Use {@link IDocumentExtension3#computePartitioning(String, int, int, bool)} when
+     * the document supports multiple partitionings. In that case this method is
+     * equivalent:
+     * <pre>
+     *    IDocumentExtension3 extension= cast(IDocumentExtension3) document;
+     *    return extension.computePartitioning(IDocumentExtension3.DEFAULT_PARTITIONING, offset, length, false);
+     * </pre>
+     *
+     * @param offset the document offset at which the range starts
+     * @param length the length of the document range
+     * @return a specification of the range's partitioning
+     * @exception BadLocationException if the range is invalid in this document
+     */
+    ITypedRegion[] computePartitioning(int offset, int length) ;
+
+    /**
+     * Registers the document partitioning listener with the document. After registration
+     * the document partitioning listener is informed about each partition change
+     * cause by a document manipulation or by changing the document's partitioner.
+     * If a document partitioning listener is also
+     * a document listener, the following notification sequence is guaranteed if a
+     * document manipulation changes the document partitioning:
+     * <ul>
+     * <li>listener.documentAboutToBeChanged(DocumentEvent);
+     * <li>listener.documentPartitioningChanged();
+     * <li>listener.documentChanged(DocumentEvent);
+     * </ul>
+     * If the listener is already registered nothing happens.<p>
+     * An <code>IDocumentPartitioningListener</code> may call back to this method
+     * when being inside a document notification.
+     *
+     * @param listener the listener to be added
+     */
+    void addDocumentPartitioningListener(IDocumentPartitioningListener listener);
+
+    /**
+     * Removes the listener from this document's list of document partitioning
+     * listeners. If the listener is not registered with the document nothing
+     * happens.<p>
+     * An <code>IDocumentPartitioningListener</code> may call back to this method
+     * when being inside a document notification.
+     *
+     * @param listener the listener to be removed
+     */
+    void removeDocumentPartitioningListener(IDocumentPartitioningListener listener);
+
+    /**
+     * Sets this document's partitioner. The caller of this method is responsible for
+     * disconnecting the document's old partitioner from the document and to
+     * connect the new partitioner to the document. Informs all document partitioning
+     * listeners about this change.
+     * <p>
+     * Use {@link IDocumentExtension3#setDocumentPartitioner(String, IDocumentPartitioner)} when
+     * the document supports multiple partitionings. In that case this method is equivalent to:
+     * <pre>
+     *    IDocumentExtension3 extension= cast(IDocumentExtension3) document;
+     *    extension.setDocumentPartitioner(IDocumentExtension3.DEFAULT_PARTITIONING, partitioner);
+     * </pre>
+     *
+     * @param partitioner the document's new partitioner
+     *
+     * @see IDocumentPartitioningListener
+     */
+    void setDocumentPartitioner(IDocumentPartitioner partitioner);
+
+    /**
+     * Returns this document's partitioner.
+     * <p>
+     * Use {@link IDocumentExtension3#getDocumentPartitioner(String)} when
+     * the document supports multiple partitionings. In that case this method is
+     * equivalent to:
+     * <pre>
+     *    IDocumentExtension3 extension= cast(IDocumentExtension3) document;
+     *    return extension.getDocumentPartitioner(IDocumentExtension3.DEFAULT_PARTITIONING);
+     * </pre>
+     *
+     * @return this document's partitioner
+     */
+    IDocumentPartitioner getDocumentPartitioner();
+
+
+
+    /* ---------------------- line information -------------------------------- */
+
+    /**
+     * Returns the length of the given line including the line's delimiter.
+     *
+     * @param line the line of interest
+     * @return the length of the line
+     * @exception BadLocationException if the line number is invalid in this document
+     */
+    int getLineLength(int line) ;
+
+    /**
+     * Returns the number of the line at which the character of the specified position is located.
+     * The first line has the line number 0. A new line starts directly after a line
+     * delimiter. <code>(offset is document length)</code> is a valid argument although there is no
+     * corresponding character.
+     *
+     * @param offset the document offset
+     * @return the number of the line
+     * @exception BadLocationException if the offset is invalid in this document
+     */
+    int getLineOfOffset(int offset) ;
+
+    /**
+     * Determines the offset of the first character of the given line.
+     *
+     * @param line the line of interest
+     * @return the document offset
+     * @exception BadLocationException if the line number is invalid in this document
+     */
+    int getLineOffset(int line) ;
+
+    /**
+     * Returns a description of the specified line. The line is described by its
+     * offset and its length excluding the line's delimiter.
+     *
+     * @param line the line of interest
+     * @return a line description
+     * @exception BadLocationException if the line number is invalid in this document
+     */
+    IRegion getLineInformation(int line) ;
+
+    /**
+     * Returns a description of the line at the given offset.
+     * The description contains the offset and the length of the line
+     * excluding the line's delimiter.
+     *
+     * @param offset the offset whose line should be described
+     * @return a region describing the line
+     * @exception BadLocationException if offset is invalid in this document
+     */
+    IRegion getLineInformationOfOffset(int offset) ;
+
+    /**
+     * Returns the number of lines in this document
+     *
+     * @return the number of lines in this document
+     */
+    int getNumberOfLines();
+
+    /**
+     * Returns the number of lines which are occupied by a given text range.
+     *
+     * @param offset the offset of the specified text range
+     * @param length the length of the specified text range
+     * @return the number of lines occupied by the specified range
+     * @exception BadLocationException if specified range is invalid in this tracker
+     */
+    int getNumberOfLines(int offset, int length) ;
+
+    /**
+     * Computes the number of lines in the given text. For a given
+     * implementer of this interface this method returns the same
+     * result as <code>set(text); getNumberOfLines()</code>.
+     *
+     * @param text the text whose number of lines should be computed
+     * @return the number of lines in the given text
+     */
+    int computeNumberOfLines(String text);
+
+
+    /* ------------------ line delimiter conversion --------------------------- */
+
+    /**
+     * Returns the document's legal line delimiters.
+     *
+     * @return the document's legal line delimiters
+     */
+    String[] getLegalLineDelimiters();
+
+    /**
+     * Returns the line delimiter of that line or <code>null</code> if the
+     * line is not closed with a line delimiter.
+     *
+     * @param line the line of interest
+     * @return the line's delimiter or <code>null</code> if line does not have a delimiter
+     * @exception BadLocationException if the line number is invalid in this document
+     */
+    String getLineDelimiter(int line) ;
+
+
+    /* ---------------------------- search ------------------------------------ */
+
+    /**
+     * Returns the offset of a given search string in the document based on a set of search criteria.
+     *
+     * @param startOffset document offset at which search starts
+     * @param findString the string to find
+     * @param forwardSearch the search direction
+     * @param caseSensitive indicates whether lower and upper case should be distinguished
+     * @param wholeWord indicates whether the findString should be limited by white spaces as
+     *      defined by Character.isWhiteSpace
+     * @return the offset of the first occurrence of findString based on the parameters or -1 if no match is found
+     * @exception BadLocationException if startOffset is an invalid document offset
+     * @deprecated as of 3.0 search is provided by {@link FindReplaceDocumentAdapter}
+     */
+    int search(int startOffset, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord) ;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentAdapter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IDocumentAdapter;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwt.custom.StyledTextContent;
+
+
+/**
+ * Adapts an {@link dwtx.jface.text.IDocument}to the
+ * {@link dwt.custom.StyledTextContent} interface. The document
+ * adapter is used by {@link dwtx.jface.text.TextViewer} to translate
+ * document changes into styled text content changes and vice versa.
+ * <p>
+ * Clients may implement this interface and override
+ * <code>TextViewer.createDocumentAdapter</code> if they want to intercept the
+ * communication between the viewer's text widget and the viewer's document.
+ * <p>
+ * In order to provide backward compatibility for clients of
+ * <code>IDocumentAdapter</code>, extension interfaces are used as a means of
+ * evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.IDocumentAdapterExtension} since version
+ *     2.0 introducing a way of batching a sequence of document changes into a
+ *     single styled text content notification</li>
+ * </ul>
+ *
+ * @see dwtx.jface.text.IDocumentAdapterExtension
+ * @see dwtx.jface.text.IDocument
+ */
+public interface IDocumentAdapter : StyledTextContent {
+
+    /**
+     * Sets the adapters document.
+     *
+     * @param document the document to be adapted
+     */
+    void setDocument(IDocument document);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentAdapterExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IDocumentAdapterExtension;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IDocumentAdapter}.
+ * <p>
+ * Introduces the concepts of batching a series of document changes into a
+ * single styled text content change notification. Batching start when a client
+ * calls <code>stopForwardingDocumentChanges</code>. After that call this
+ * document adapter does not send out styled text content change notifications
+ * until <code>resumeForwardingDocumentChanges</code> is called. On
+ * <code>resumeForwardingDocumentChanges</code>, it sends out one styled text
+ * content change notification that covers all changes that have been applied to
+ * the document since calling <code>stopForwardingDocumentChanges</code>.
+ *
+ * @since 2.0
+ */
+public interface IDocumentAdapterExtension {
+
+    /**
+     * Stops forwarding document changes to the styled text.
+     */
+    void stopForwardingDocumentChanges();
+
+    /**
+     * Resumes forwarding document changes to the styled text.
+     * Also forces the styled text to catch up with all the changes
+     * that have been applied since <code>stopForwardingDocumentChanges</code>
+     * has been called.
+     */
+    void resumeForwardingDocumentChanges();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IDocumentExtension;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IDocument}.<p>
+ *
+ * It introduces the notion of sequentially rewriting a document. This is to tell a
+ * document that a sequence of non-overlapping replace operation is about to be
+ * performed. Implementers can use this knowledge for internal optimization.<p>
+ *
+ * Is also introduces the concept of post notification replaces. This is, a document
+ * listener who is informed about a document change can cause a derived document
+ * change. As the listener is not allowed to directly modify the document, it can
+ * register a replace operation that is performed directly after all document listeners
+ * have been notified.
+ *
+ * @since 2.0
+ */
+public interface IDocumentExtension {
+
+    /**
+     * Interface for a post notification replace operation.
+     */
+    public interface IReplace {
+
+        /**
+         * Executes the replace operation on the given document.
+         *
+         * @param document the document to be changed
+         * @param owner the owner of this replace operation
+         */
+        void perform(IDocument document, IDocumentListener owner);
+    }
+
+    /**
+     * Callback for document listeners to be used inside <code>documentChanged</code>
+     * to register a post notification replace operation on the document notifying them.
+     *
+     * @param owner the owner of the replace operation
+     * @param replace the replace operation to be executed
+     * @exception UnsupportedOperationException if <code>registerPostNotificationReplace</code>
+     *  is not supported by this document
+     */
+    void registerPostNotificationReplace(IDocumentListener owner, IReplace replace) ;
+
+    /**
+     * Stops the processing of registered post notification replace operations until
+     * <code>resumePostNotificationProcessing</code> is called.
+     */
+    void stopPostNotificationProcessing();
+
+    /**
+     * Resumes the processing of post notification replace operations. If the queue of registered
+     * <code>IDocumentExtension.IReplace</code> objects is not empty, they are immediately processed if the
+     * document is not inside a replace operation. If the document is inside a replace operation,
+     * they are processed directly after the replace operation has finished.
+     */
+    void resumePostNotificationProcessing();
+
+    /**
+     * Tells the document that it is about to be sequentially rewritten. That is a
+     * sequence of non-overlapping replace operations will be performed on it. The
+     * <code>normalize</code> flag indicates whether the rewrite is performed from
+     * the start of the document to its end or from an arbitrary start offset. <p>
+     *
+     * The document is considered being in sequential rewrite mode as long as
+     * <code>stopSequentialRewrite</code> has not been called.
+     *
+     * @param normalize <code>true</code> if performed from the start to the end of the document
+     * @deprecated since 3.1. Use {@link IDocumentExtension4#startRewriteSession(DocumentRewriteSessionType)} instead.
+     */
+    void startSequentialRewrite(bool normalize);
+
+    /**
+     * Tells the document that the sequential rewrite has been finished. This method
+     * has only any effect if <code>startSequentialRewrite</code> has been called before.
+     * @deprecated since 3.1. Use {@link IDocumentExtension4#stopRewriteSession(DocumentRewriteSession)} instead.
+     */
+    void stopSequentialRewrite();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IDocumentExtension2;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IDocument}.<p>
+ *
+ * It adds configuration methods to post notification replaces and document
+ * listener notification.
+ *
+ * @since 2.1
+ */
+public interface IDocumentExtension2 {
+
+    /**
+     * Tells the receiver to ignore calls to
+     * <code>registerPostNotificationReplace</code> until
+     * <code>acceptPostNotificationReplaces</code> is called.
+     */
+    void ignorePostNotificationReplaces();
+
+    /**
+     * Tells the receiver to accept calls to
+     * <code>registerPostNotificationReplace</code> until
+     * <code>ignorePostNotificationReplaces</code> is called.
+     */
+    void acceptPostNotificationReplaces();
+
+    /**
+     * Can be called prior to a <code>replace</code> operation. After the
+     * <code>replace</code> <code>resumeListenerNotification</code> must be
+     * called. The affect of these calls is that no document listener is notified
+     * until <code>resumeListenerNotification</code> is called. This allows clients
+     * to update structure before any listener is informed about the change.<p>
+     * Listener notification can only be stopped for a single <code>replace</code> operation.
+     * Otherwise, document change notifications will be lost.
+     */
+    void stopListenerNotification();
+
+    /**
+     * Resumes the notification of document listeners which must previously
+     * have been stopped by a call to <code>stopListenerNotification</code>.
+     */
+    void resumeListenerNotification();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentExtension3.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IDocumentExtension3;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IDocument}.
+ * <p>
+ * Adds the concept of multiple partitionings and the concept of zero-length
+ * partitions in conjunction with open and delimited partitions. A delimited
+ * partition has a well defined start delimiter and a well defined end
+ * delimiter. Between two delimited partitions there may be an open partition of
+ * length zero.
+ * <p>
+ *
+ * In order to fulfill the contract of this interface, the document must be
+ * configured with a document partitioner implementing
+ * {@link dwtx.jface.text.IDocumentPartitionerExtension2}.
+ *
+ * @see dwtx.jface.text.IDocumentPartitionerExtension2
+ * @since 3.0
+ */
+public interface IDocumentExtension3 {
+
+    /**
+     * The identifier of the default partitioning.
+     */
+    final static String DEFAULT_PARTITIONING= "__dftl_partitioning"; //$NON-NLS-1$
+
+
+    /**
+     * Returns the existing partitionings for this document. This includes
+     * the default partitioning.
+     *
+     * @return the existing partitionings for this document
+     */
+    String[] getPartitionings();
+
+    /**
+     * Returns the set of legal content types of document partitions for the given partitioning
+     * This set can be empty. The set can contain more content types than  contained by the
+     * result of <code>getPartitioning(partitioning, 0, getLength())</code>.
+     *
+     * @param partitioning the partitioning for which to return the legal content types
+     * @return the set of legal content types
+     * @exception BadPartitioningException if partitioning is invalid for this document
+     */
+    String[] getLegalContentTypes(String partitioning) ;
+
+
+    /**
+     * Returns the type of the document partition containing the given offset
+     * for the given partitioning. This is a convenience method for
+     * <code>getPartition(partitioning, offset, bool).getType()</code>.
+     * <p>
+     * If <code>preferOpenPartitions</code> is <code>true</code>,
+     * precedence is given to an open partition ending at <code>offset</code>
+     * over a delimited partition starting at <code>offset</code>. If it is
+     * <code>false</code>, precedence is given to the partition that does not
+     * end at <code>offset</code>.
+     * </p>
+     * This is only supported if the connected <code>IDocumentPartitioner</code>
+     * supports it, i.e. implements <code>IDocumentPartitionerExtension2</code>.
+     * Otherwise, <code>preferOpenPartitions</code> is ignored.
+     * </p>
+     *
+     * @param partitioning the partitioning
+     * @param offset the document offset
+     * @param preferOpenPartitions <code>true</code> if precedence should be
+     *        given to a open partition ending at <code>offset</code> over a
+     *        closed partition starting at <code>offset</code>
+     * @return the partition type
+     * @exception BadLocationException if offset is invalid in this document
+     * @exception BadPartitioningException if partitioning is invalid for this document
+     */
+    String getContentType(String partitioning, int offset, bool preferOpenPartitions);
+
+    /**
+     * Returns the document partition of the given partitioning in which the
+     * given offset is located.
+     * <p>
+     * If <code>preferOpenPartitions</code> is <code>true</code>,
+     * precedence is given to an open partition ending at <code>offset</code>
+     * over a delimited partition starting at <code>offset</code>. If it is
+     * <code>false</code>, precedence is given to the partition that does not
+     * end at <code>offset</code>.
+     * </p>
+     * This is only supported if the connected <code>IDocumentPartitioner</code>
+     * supports it, i.e. implements <code>IDocumentPartitionerExtension2</code>.
+     * Otherwise, <code>preferOpenPartitions</code> is ignored.
+     * </p>
+     *
+     * @param partitioning the partitioning
+     * @param offset the document offset
+     * @param preferOpenPartitions <code>true</code> if precedence should be
+     *        given to a open partition ending at <code>offset</code> over a
+     *        closed partition starting at <code>offset</code>
+     * @return a specification of the partition
+     * @exception BadLocationException if offset is invalid in this document
+     * @exception BadPartitioningException if partitioning is invalid for this document
+     */
+    ITypedRegion getPartition(String partitioning, int offset, bool preferOpenPartitions);
+
+    /**
+     * Computes the partitioning of the given document range based on the given
+     * partitioning type.
+     * <p>
+     * If <code>includeZeroLengthPartitions</code> is <code>true</code>, a
+     * zero-length partition of an open partition type (usually the default
+     * partition) is included between two closed partitions. If it is
+     * <code>false</code>, no zero-length partitions are included.
+     * </p>
+     * This is only supported if the connected <code>IDocumentPartitioner</code>
+     * supports it, i.e. implements <code>IDocumentPartitionerExtension2</code>.
+     * Otherwise, <code>includeZeroLengthPartitions</code> is ignored.
+     * </p>
+     *
+     * @param partitioning the document's partitioning type
+     * @param offset the document offset at which the range starts
+     * @param length the length of the document range
+     * @param includeZeroLengthPartitions <code>true</code> if zero-length
+     *        partitions should be returned as part of the computed partitioning
+     * @return a specification of the range's partitioning
+     * @exception BadLocationException if the range is invalid in this document$
+     * @exception BadPartitioningException if partitioning is invalid for this document
+     */
+    ITypedRegion[] computePartitioning(String partitioning, int offset, int length, bool includeZeroLengthPartitions);
+
+    /**
+     * Sets this document's partitioner. The caller of this method is responsible for
+     * disconnecting the document's old partitioner from the document and to
+     * connect the new partitioner to the document. Informs all document partitioning
+     * listeners about this change.
+     *
+     * @param  partitioning the partitioning for which to set the partitioner
+     * @param partitioner the document's new partitioner
+     * @see IDocumentPartitioningListener
+     */
+    void setDocumentPartitioner(String partitioning, IDocumentPartitioner partitioner);
+
+    /**
+     * Returns the partitioner for the given partitioning or <code>null</code> if
+     * no partitioner is registered.
+     *
+     * @param  partitioning the partitioning for which to set the partitioner
+     * @return the partitioner for the given partitioning
+     */
+    IDocumentPartitioner getDocumentPartitioner(String partitioning);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentExtension4.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,299 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IDocumentExtension4;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IDocument}. It adds the
+ * following concepts:
+ * <ul>
+ *   <li>Rewrite sessions. A rewrite session is a sequence of replace operations
+ *       that form a semantic unit.</li>
+ *   <li>A modification stamp on the document</li>
+ *   <li>The ability to set the initial line delimiter and to query the default
+ *       line delimiter</li>
+ * </ul>
+ *
+ * @since 3.1
+ */
+public interface IDocumentExtension4 {
+
+    /**
+     * Tells the document that it is about to be rewritten. That is, a sequence
+     * of replace operations that form a semantic unit will be performed on this
+     * document. A specification of the nature of the operation sequence is
+     * given in form of the session type.
+     * <p>
+     * The document is considered being in rewrite mode as long as
+     * <code>stopRewriteSession</code> has not been called.
+     *
+     * @param sessionType the session type
+     * @return the started rewrite session
+     * @throws IllegalStateException in case there is already an active rewrite session
+     */
+    DocumentRewriteSession startRewriteSession(DocumentRewriteSessionType sessionType) ;
+
+    /**
+     * Tells the document to stop the rewrite session. This method has only any
+     * effect if <code>startRewriteSession</code> has been called before.
+     * <p>
+     * This method does not have any effect if the given session is not the
+     * active rewrite session.
+     *
+     * @param session the session to stop
+     */
+    void stopRewriteSession(DocumentRewriteSession session);
+
+    /**
+     * Returns the active rewrite session of this document or <code>null</code>.
+     *
+     * @return the active rewrite session or <code>null</code>
+     */
+    DocumentRewriteSession getActiveRewriteSession();
+
+    /**
+     * Registers the document rewrite session listener with the document. After
+     * registration the <code>IDocumentRewriteSessionListener</code> is
+     * informed about each state change of rewrite sessions performed on this
+     * document.
+     * <p>
+     * If the listener is already registered nothing happens.
+     * <p>
+     * An <code>IRewriteSessionDocumentListener</code> may call back to this
+     * document when being inside a document notification.
+     *
+     * @param listener the listener to be registered
+     */
+    void addDocumentRewriteSessionListener(IDocumentRewriteSessionListener listener);
+
+    /**
+     * Removes the listener from the document's list of document rewrite session
+     * listeners. If the listener is not registered with the document nothing
+     * happens.
+     * <p>
+     * An <code>IDocumentRewriteSessionListener</code> may call back to this
+     * document when being inside a document notification.
+     *
+     * @param listener the listener to be removed
+     */
+    void removeDocumentRewriteSessionListener(IDocumentRewriteSessionListener listener);
+
+    /**
+     * Substitutes the given text for the specified document range.
+     * Sends a <code>DocumentEvent</code> to all registered <code>IDocumentListener</code>.
+     *
+     * @param offset the document offset
+     * @param length the length of the specified range
+     * @param text the substitution text
+     * @param modificationStamp of the document after replacing
+     * @exception BadLocationException if the offset is invalid in this document
+     *
+     * @see DocumentEvent
+     * @see IDocumentListener
+     */
+    void replace(int offset, int length, String text, long modificationStamp) ;
+
+    /**
+     * Replaces the content of the document with the given text.
+     * Sends a <code>DocumentEvent</code> to all registered <code>IDocumentListener</code>.
+     * This method is a convenience method for <code>replace(0, getLength(), text)</code>.
+     *
+     * @param text the new content of the document
+     * @param modificationStamp of the document after setting the content
+     *
+     * @see DocumentEvent
+     * @see IDocumentListener
+     */
+    void set(String text, long modificationStamp);
+
+    /**
+     * The unknown modification stamp.
+     */
+    static const long UNKNOWN_MODIFICATION_STAMP= -1;
+
+    /**
+     * Returns the modification stamp of this document. The modification stamp
+     * is updated each time a modifying operation is called on this document. If
+     * two modification stamps of the same document are identical then the document
+     * content is too, however, same content does not imply same modification stamp.
+     * <p>
+     * The magnitude or sign of the numerical difference between two modification stamps
+     * is not significant.
+     * </p>
+     *
+     * @return the modification stamp of this document or <code>UNKNOWN_MODIFICATION_STAMP</code>
+     */
+    long getModificationStamp();
+
+    /**
+     * Returns this document's default line delimiter.
+     * <p>
+     * This default line delimiter should be used by clients who
+     * want unique delimiters (e.g. 'CR's) in the document.</p>
+     *
+     * @return the default line delimiter or <code>null</code> if none
+     */
+    String getDefaultLineDelimiter();
+
+    /**
+     * Sets this document's initial line delimiter i.e. the one
+     * which is returned by <code>getDefaultLineDelimiter</code>
+     * if the document does not yet contain any line delimiter.
+     *
+     * @param lineDelimiter the default line delimiter
+     */
+    void setInitialLineDelimiter(String lineDelimiter);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentInformationMapping.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,269 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IDocumentInformationMapping;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A <code>IDocumentInformationMapping</code>  represents a mapping between the coordinates of two
+ * <code>IDocument</code> objects: the original and the image. The document information mapping
+ * can translate document information such as line numbers or character ranges given for the original into
+ * the corresponding information of the image and vice versa.
+ *
+ * In order to provided backward compatibility for clients of <code>IDocumentInformationMapping</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces
+ * exist:
+ * <ul>
+ * <li> {@link dwtx.jface.text.IDocumentInformationMappingExtension} since version 3.0 extending the
+ *      degree of detail of the mapping information.</li>
+ * <li> {@link dwtx.jface.text.IDocumentInformationMappingExtension2} since version 3.1, adding lenient
+ *      image region computation.</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public interface IDocumentInformationMapping {
+
+    /**
+     * Returns the minimal region of the original document that completely comprises all of the image document
+     * or <code>null</code> if there is no such region.
+     *
+     * @return the minimal region of the original document comprising the image document or <code>null</code>
+     */
+    IRegion getCoverage();
+
+    /**
+     * Returns the offset in the original document that corresponds to the given offset in the image document
+     * or <code>-1</code> if there is no such offset
+     *
+     * @param imageOffset the offset in the image document
+     * @return the corresponding offset in the original document or <code>-1</code>
+     * @throws BadLocationException if <code>imageOffset</code> is not a valid offset in the image document
+     */
+    int toOriginOffset(int imageOffset) ;
+
+    /**
+     * Returns the minimal region of the original document that completely comprises the given region of the
+     * image document or <code>null</code> if there is no such region.
+     *
+     * @param imageRegion the region of the image document
+     * @return the minimal region of the original document comprising the given region of the image document or <code>null</code>
+     * @throws BadLocationException if <code>imageRegion</code> is not a valid region of the image document
+     */
+    IRegion toOriginRegion(IRegion imageRegion) ;
+
+    /**
+     * Returns the range of lines of the original document that corresponds to the given line of the image document or
+     * <code>null</code> if there are no such lines.
+     *
+     * @param imageLine the line of the image document
+     * @return the corresponding lines of the original document or <code>null</code>
+     * @throws BadLocationException if <code>imageLine</code> is not a valid line number in the image document
+     */
+    IRegion toOriginLines(int imageLine) ;
+
+    /**
+     * Returns the line of the original document that corresponds to the given line of the image document or
+     * <code>-1</code> if there is no such line.
+     *
+     * @param imageLine the line of the image document
+     * @return the corresponding line of the original document or <code>-1</code>
+     * @throws BadLocationException if <code>imageLine</code> is not a valid line number in the image document
+     */
+    int toOriginLine(int imageLine) ;
+
+
+
+    /**
+     * Returns the offset in the image document that corresponds to the given offset in the original document
+     * or <code>-1</code> if there is no such offset
+     *
+     * @param originOffset the offset in the original document
+     * @return the corresponding offset in the image document or <code>-1</code>
+     * @throws BadLocationException if <code>originOffset</code> is not a valid offset in the original document
+     */
+    int toImageOffset(int originOffset) ;
+
+    /**
+     * Returns the minimal region of the image document that completely comprises the given region of the
+     * original document or <code>null</code> if there is no such region.
+     *
+     * @param originRegion the region of the original document
+     * @return the minimal region of the image document comprising the given region of the original document or <code>null</code>
+     * @throws BadLocationException if <code>originRegion</code> is not a valid region of the original document
+     */
+    IRegion toImageRegion(IRegion originRegion) ;
+
+    /**
+     * Returns the line of the image document that corresponds to the given line of the original document or
+     * <code>-1</code> if there is no such line.
+     *
+     * @param originLine the line of the original document
+     * @return the corresponding line of the image document or <code>-1</code>
+     * @throws BadLocationException if <code>originLine</code> is not a valid line number in the original document
+     */
+    int toImageLine(int originLine) ;
+
+    /**
+     * Returns the line of the image document whose corresponding line in the original document
+     * is closest to the given line in the original document.
+     *
+     * @param originLine the line in the original document
+     * @return the line in the image document that corresponds best to the given line in the original document
+     * @throws BadLocationException if <code>originLine</code>is not a valid line in the original document
+     */
+    int toClosestImageLine(int originLine) ;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentInformationMappingExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,225 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IDocumentInformationMappingExtension;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension to {@link dwtx.jface.text.IDocumentInformationMapping}.
+ * <p>
+ * Extends the information available in the mapping by providing explicit access
+ * to the isomorphic portion of the basically homomorphic information mapping.
+ *
+ * @see dwtx.jface.text.IDocumentInformationMapping
+ * @since 3.0
+ */
+public interface IDocumentInformationMappingExtension {
+
+    /**
+     * Adheres to
+     * <code>originRegion=toOriginRegion(toExactImageRegion(originRegion))</code>,
+     * if <code>toExactImageRegion(originRegion) !is null</code>. Returns
+     * <code>null</code> if there is no image for the given origin region.
+     *
+     * @param originRegion the origin region
+     * @return the exact image region or <code>null</code>
+     * @throws BadLocationException if origin region is not a valid region in
+     *             the origin document
+     */
+    IRegion toExactImageRegion(IRegion originRegion) ;
+
+    /**
+     * Returns the segments of the image document that exactly correspond to the
+     * given region of the original document. Returns <code>null</code> if
+     * there are no such image regions.
+     *
+     * @param originRegion the region in the origin document
+     * @return the segments in the image document or <code>null</code>
+     * @throws BadLocationException in case the given origin region is not valid
+     *             in the original document
+     */
+    IRegion[] toExactImageRegions(IRegion originRegion) ;
+
+    /**
+     * Returns the fragments of the original document that exactly correspond to
+     * the given region of the image document.
+     *
+     * @param imageRegion the region in the image document
+     * @return the fragments in the origin document
+     * @throws BadLocationException in case the given image region is not valid
+     *             in the image document
+     */
+    IRegion[] toExactOriginRegions(IRegion imageRegion) ;
+
+    /**
+     * Returns the length of the image document.
+     *
+     * @return the length of the image document
+     */
+    int getImageLength();
+
+    /**
+     * Returns the maximal sub-regions of the given origin region which are
+     * completely covered. I.e. each offset in a sub-region has a corresponding
+     * image offset. Returns <code>null</code> if there are no such
+     * sub-regions.
+     *
+     * @param originRegion the region in the origin document
+     * @return the sub-regions with complete coverage or <code>null</code>
+     * @throws BadLocationException in case the given origin region is not valid
+     *             in the original document
+     */
+    IRegion[] getExactCoverage(IRegion originRegion) ;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentInformationMappingExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,187 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IDocumentInformationMappingExtension2;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension to {@link dwtx.jface.text.IDocumentInformationMapping}.
+ * <p>
+ * Extends the information available in the mapping by providing access
+ * to the closest image region of an origin region.
+ * </p>
+ *
+ * @see dwtx.jface.text.IDocumentInformationMapping
+ * @since 3.1
+ */
+public interface IDocumentInformationMappingExtension2 {
+
+    /**
+     * Returns the minimal region of the image document that completely
+     * comprises the given region of the original document. The difference to
+     * {@link IDocumentInformationMapping#toImageRegion(IRegion)} is that this
+     * method will always return an image region for a valid origin region. If
+     * <code>originRegion</code> has no corresponding image region, the
+     * zero-length region at the offset between its surrounding fragments is
+     * returned.
+     *
+     * @param originRegion the region of the original document
+     * @return the minimal region of the image document comprising the given
+     *         region of the original document
+     * @throws BadLocationException if <code>originRegion</code> is not a
+     *         valid region of the original document
+     */
+    IRegion toClosestImageRegion(IRegion originRegion) ;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IDocumentListener;
+
+import dwtx.jface.text.DocumentEvent; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+
+/**
+ * Interface for objects which are interested in getting informed about
+ * document changes. A listener is informed about document changes before
+ * they are applied and after they have been applied. It is ensured that
+ * the document event passed into the listener is the same for the two
+ * notifications, i.e. the two document events can be checked using object identity.
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ *
+ * @see dwtx.jface.text.IDocument
+ */
+public interface IDocumentListener {
+
+
+    /**
+     * The manipulation described by the document event will be performed.
+     *
+     * @param event the document event describing the document change
+     */
+    void documentAboutToBeChanged(DocumentEvent event);
+
+    /**
+     * The manipulation described by the document event has been performed.
+     *
+     * @param event the document event describing the document change
+     */
+    void documentChanged(DocumentEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentPartitioner.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,307 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IDocumentPartitioner;
+
+// import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+// import dwtx.jface.text.DefaultTextHover; // packageimport
+// import dwtx.jface.text.AbstractInformationControl; // packageimport
+// import dwtx.jface.text.TextUtilities; // packageimport
+// import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+// import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+// import dwtx.jface.text.ITextViewerExtension2; // packageimport
+// import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+// import dwtx.jface.text.ITextSelection; // packageimport
+// import dwtx.jface.text.Document; // packageimport
+// import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+// import dwtx.jface.text.ITextListener; // packageimport
+// import dwtx.jface.text.BadPartitioningException; // packageimport
+// import dwtx.jface.text.ITextViewerExtension5; // packageimport
+// import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+// import dwtx.jface.text.IUndoManager; // packageimport
+// import dwtx.jface.text.ITextHoverExtension2; // packageimport
+// import dwtx.jface.text.IRepairableDocument; // packageimport
+// import dwtx.jface.text.IRewriteTarget; // packageimport
+// import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+// import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+// import dwtx.jface.text.TextViewerHoverManager; // packageimport
+// import dwtx.jface.text.DocumentRewriteSession; // packageimport
+// import dwtx.jface.text.TextViewer; // packageimport
+// import dwtx.jface.text.ITextViewerExtension8; // packageimport
+// import dwtx.jface.text.RegExMessages; // packageimport
+// import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+// import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+// import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+// import dwtx.jface.text.IViewportListener; // packageimport
+// import dwtx.jface.text.GapTextStore; // packageimport
+// import dwtx.jface.text.MarkSelection; // packageimport
+// import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+// import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+// import dwtx.jface.text.IInformationControlExtension; // packageimport
+// import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+// import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+// import dwtx.jface.text.ITextViewerExtension3; // packageimport
+// import dwtx.jface.text.IInformationControlCreator; // packageimport
+// import dwtx.jface.text.TypedRegion; // packageimport
+// import dwtx.jface.text.ISynchronizable; // packageimport
+// import dwtx.jface.text.IMarkRegionTarget; // packageimport
+// import dwtx.jface.text.TextViewerUndoManager; // packageimport
+// import dwtx.jface.text.IRegion; // packageimport
+// import dwtx.jface.text.IInformationControlExtension2; // packageimport
+// import dwtx.jface.text.IDocumentExtension4; // packageimport
+// import dwtx.jface.text.IDocumentExtension2; // packageimport
+// import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+// import dwtx.jface.text.Assert; // packageimport
+// import dwtx.jface.text.DefaultInformationControl; // packageimport
+// import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+// import dwtx.jface.text.DocumentClone; // packageimport
+// import dwtx.jface.text.DefaultUndoManager; // packageimport
+// import dwtx.jface.text.IFindReplaceTarget; // packageimport
+// import dwtx.jface.text.IAutoEditStrategy; // packageimport
+// import dwtx.jface.text.ILineTrackerExtension; // packageimport
+// import dwtx.jface.text.IUndoManagerExtension; // packageimport
+// import dwtx.jface.text.TextSelection; // packageimport
+// import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+// import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+// import dwtx.jface.text.IPainter; // packageimport
+// import dwtx.jface.text.IInformationControl; // packageimport
+// import dwtx.jface.text.IInformationControlExtension3; // packageimport
+// import dwtx.jface.text.ITextViewerExtension6; // packageimport
+// import dwtx.jface.text.IInformationControlExtension4; // packageimport
+// import dwtx.jface.text.DefaultLineTracker; // packageimport
+// import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+// import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+// import dwtx.jface.text.ITextHover; // packageimport
+// import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+// import dwtx.jface.text.ILineTracker; // packageimport
+// import dwtx.jface.text.Line; // packageimport
+// import dwtx.jface.text.ITextViewerExtension; // packageimport
+// import dwtx.jface.text.IDocumentAdapter; // packageimport
+// import dwtx.jface.text.TextEvent; // packageimport
+// import dwtx.jface.text.BadLocationException; // packageimport
+// import dwtx.jface.text.AbstractDocument; // packageimport
+// import dwtx.jface.text.AbstractLineTracker; // packageimport
+// import dwtx.jface.text.TreeLineTracker; // packageimport
+// import dwtx.jface.text.ITextPresentationListener; // packageimport
+// import dwtx.jface.text.Region; // packageimport
+// import dwtx.jface.text.ITextViewer; // packageimport
+// import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+// import dwtx.jface.text.MarginPainter; // packageimport
+// import dwtx.jface.text.IPaintPositionManager; // packageimport
+// import dwtx.jface.text.TextPresentation; // packageimport
+// import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+// import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+// import dwtx.jface.text.ISelectionValidator; // packageimport
+// import dwtx.jface.text.IDocumentExtension; // packageimport
+// import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+// import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+// import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+// import dwtx.jface.text.IDocumentListener; // packageimport
+// import dwtx.jface.text.PaintManager; // packageimport
+// import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+// import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+// import dwtx.jface.text.IDocumentExtension3; // packageimport
+// import dwtx.jface.text.Position; // packageimport
+// import dwtx.jface.text.TextMessages; // packageimport
+// import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+// import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+// import dwtx.jface.text.IPositionUpdater; // packageimport
+// import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+// import dwtx.jface.text.ListLineTracker; // packageimport
+// import dwtx.jface.text.ITextInputListener; // packageimport
+// import dwtx.jface.text.BadPositionCategoryException; // packageimport
+// import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+// import dwtx.jface.text.IInputChangedListener; // packageimport
+// import dwtx.jface.text.ITextOperationTarget; // packageimport
+// import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+// import dwtx.jface.text.ITextViewerExtension7; // packageimport
+// import dwtx.jface.text.IInformationControlExtension5; // packageimport
+// import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+// import dwtx.jface.text.JFaceTextUtil; // packageimport
+// import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+// import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+// import dwtx.jface.text.CursorLinePainter; // packageimport
+// import dwtx.jface.text.ITextHoverExtension; // packageimport
+// import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+// import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+// import dwtx.jface.text.DocumentCommand; // packageimport
+// import dwtx.jface.text.TypedPosition; // packageimport
+// import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+// import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+// import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+// import dwtx.jface.text.IEditingSupport; // packageimport
+// import dwtx.jface.text.IMarkSelection; // packageimport
+// import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+// import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+// import dwtx.jface.text.ITextStore; // packageimport
+// import dwtx.jface.text.JFaceTextMessages; // packageimport
+// import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+// import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+// import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+// import dwtx.jface.text.TextAttribute; // packageimport
+// import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+/**
+ * A document partitioner divides a document into a set
+ * of disjoint text partitions. Each partition has a content type, an
+ * offset, and a length. The document partitioner is connected to one document
+ * and informed about all changes of this document before any of the
+ * document's document listeners. A document partitioner can thus
+ * incrementally update on the receipt of a document change event.<p>
+ *
+ * In order to provided backward compatibility for clients of <code>IDocumentPartitioner</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces
+ * exist:
+ * <ul>
+ * <li> {@link dwtx.jface.text.IDocumentPartitionerExtension} since version 2.0 replacing
+ *      the <code>documentChanged</code> method with a new one returning the minimal document region
+ *      comprising all partition changes.</li>
+ * <li> {@link dwtx.jface.text.IDocumentPartitionerExtension2} since version 3.0
+ *      introducing zero-length partitions in conjunction with the distinction between
+ *      open and closed partitions. Also provides inside in the implementation of the partitioner
+ *      by exposing the position category used for managing the partitioning information.</li>
+ * <li> {@link dwtx.jface.text.IDocumentPartitionerExtension3} since version 3.1 introducing
+ *      rewrite session. It also replaces the existing {@link #connect(IDocument)} method with
+ *      a new one: {@link dwtx.jface.text.IDocumentPartitionerExtension3#connect(IDocument, bool)}.
+ * </ul>
+ * <p>
+ * Clients may implement this interface and its extension interfaces or use the standard
+ * implementation <code>DefaultPartitioner</code>.
+ * </p>
+ *
+ * @see dwtx.jface.text.IDocumentPartitionerExtension
+ * @see dwtx.jface.text.IDocumentPartitionerExtension2
+ * @see dwtx.jface.text.IDocument
+ */
+public interface IDocumentPartitioner {
+
+    /**
+     * Connects the partitioner to a document.
+     * Connect indicates the begin of the usage of the receiver
+     * as partitioner of the given document. Thus, resources the partitioner
+     * needs to be operational for this document should be allocated.<p>
+     *
+     * The caller of this method must ensure that this partitioner is
+     * also set as the document's document partitioner.<p>
+     *
+     * This method has been replaced with {@link IDocumentPartitionerExtension3#connect(IDocument, bool)}.
+     * Implementers should default a call <code>connect(document)</code> to
+     * <code>connect(document, false)</code> in order to sustain the same semantics.
+     *
+     * @param document the document to be connected to
+     */
+    void connect(IDocument document);
+
+    /**
+     * Disconnects the partitioner from the document it is connected to.
+     * Disconnect indicates the end of the usage of the receiver as
+     * partitioner of the connected document. Thus, resources the partitioner
+     * needed to be operation for its connected document should be deallocated.<p>
+     * The caller of this method should also must ensure that this partitioner is
+     * no longer the document's partitioner.
+     */
+    void disconnect();
+
+    /**
+     * Informs about a forthcoming document change. Will be called by the
+     * connected document and is not intended to be used by clients
+     * other than the connected document.
+     *
+     * @param event the event describing the forthcoming change
+     */
+    void documentAboutToBeChanged(DocumentEvent event);
+
+    /**
+     * The document has been changed. The partitioner updates
+     * the document's partitioning and returns whether the structure of the
+     * document partitioning has been changed, i.e. whether partitions
+     * have been added or removed. Will be called by the connected document and
+     * is not intended to be used by clients other than the connected document.<p>
+     *
+     * This method has been replaced by {@link IDocumentPartitionerExtension#documentChanged2(DocumentEvent)}.
+     *
+     * @param event the event describing the document change
+     * @return <code>true</code> if partitioning changed
+     */
+    bool documentChanged(DocumentEvent event);
+
+    /**
+     * Returns the set of all legal content types of this partitioner.
+     * I.e. any result delivered by this partitioner may not contain a content type
+     * which would not be included in this method's result.
+     *
+     * @return the set of legal content types
+     */
+    String[] getLegalContentTypes();
+
+    /**
+     * Returns the content type of the partition containing the
+     * given offset in the connected document. There must be a
+     * document connected to this partitioner.<p>
+     *
+     * Use {@link IDocumentPartitionerExtension2#getContentType(int, bool)} when
+     * zero-length partitions are supported. In that case this method is
+     * equivalent:
+     * <pre>
+     *    IDocumentPartitionerExtension2 extension= cast(IDocumentPartitionerExtension2) partitioner;
+     *    return extension.getContentType(offset, false);
+     * </pre>
+     *
+     * @param offset the offset in the connected document
+     * @return the content type of the offset's partition
+     */
+    String getContentType(int offset);
+
+    /**
+     * Returns the partitioning of the given range of the connected
+     * document. There must be a document connected to this partitioner.<p>
+     *
+     * Use {@link IDocumentPartitionerExtension2#computePartitioning(int, int, bool)} when
+     * zero-length partitions are supported. In that case this method is
+     * equivalent:
+     * <pre>
+     *    IDocumentPartitionerExtension2 extension= cast(IDocumentPartitionerExtension2) partitioner;
+     *    return extension.computePartitioning(offset, length, false);
+     * </pre>
+     *
+     * @param offset the offset of the range of interest
+     * @param length the length of the range of interest
+     * @return the partitioning of the range
+     */
+    ITypedRegion[] computePartitioning(int offset, int length);
+
+    /**
+     * Returns the partition containing the given offset of
+     * the connected document. There must be a document connected to this
+     * partitioner.<p>
+     *
+     * Use {@link IDocumentPartitionerExtension2#getPartition(int, bool)} when
+     * zero-length partitions are supported. In that case this method is
+     * equivalent:
+     * <pre>
+     *    IDocumentPartitionerExtension2 extension= cast(IDocumentPartitionerExtension2) partitioner;
+     *    return extension.getPartition(offset, false);
+     * </pre>
+     *
+     * @param offset the offset for which to determine the partition
+     * @return the partition containing the offset
+     */
+    ITypedRegion getPartition(int offset);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentPartitionerExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IDocumentPartitionerExtension;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IDocumentPartitioner}.
+ * <p>
+ * Replaces the original concept of the document partitioner by returning the
+ * minimal region that includes all partition changes caused by the invocation
+ * of the document partitioner.
+ * The method <code>documentChanged2</code> is considered the replacement of
+ * {@link dwtx.jface.text.IDocumentPartitioner#documentChanged(DocumentEvent)}.
+ *
+ * @since 2.0
+ */
+public interface IDocumentPartitionerExtension {
+
+    /**
+     * The document has been changed. The partitioner updates the document's
+     * partitioning and returns the minimal region that comprises all partition
+     * changes caused in response to the given document event. This method
+     * returns <code>null</code> if the partitioning did not change.
+     * <p>
+     *
+     * Will be called by the connected document and is not intended to be used
+     * by clients other than the connected document.
+     * <p>
+     * Replaces {@link IDocumentPartitioner#documentChanged(DocumentEvent)}.
+     *
+     * @param event the event describing the document change
+     * @return the region of the document in which the partition type changed or <code>null</code>
+     */
+    IRegion documentChanged2(DocumentEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentPartitionerExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,265 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IDocumentPartitionerExtension2;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IDocumentPartitioner}.
+ * <p>
+ * Extends the original concept of a document partitioner to answer the position
+ * categories that are used to manage the partitioning information.
+ * <p>
+ * This extension also introduces the concept of open and delimited partitions.
+ * A delimited partition has a predefined textual token delimiting its start and
+ * end, while an open partition can fill any space between two delimited
+ * partitions.
+ * </p>
+ * <p>
+ * An open partition of length zero can occur between two delimited partitions,
+ * thus having the same offset as the following delimited partition. The
+ * document start and end are considered to be delimiters of open partitions,
+ * i.e. there may be a zero-length partition between the document start and a
+ * delimited partition starting at offset 0.
+ * </p>
+ *
+ * @since 3.0
+ */
+public interface IDocumentPartitionerExtension2 {
+
+    /**
+     * Returns the position categories that this partitioners uses in order to manage
+     * the partitioning information of the documents. Returns <code>null</code> if
+     * no position category is used.
+     *
+     * @return the position categories used to manage partitioning information or <code>null</code>
+     */
+    String[] getManagingPositionCategories();
+
+
+    /* zero-length partition support */
+
+    /**
+     * Returns the content type of the partition containing the given offset in
+     * the connected document. There must be a document connected to this
+     * partitioner.
+     * <p>
+     * If <code>preferOpenPartitions</code> is <code>true</code>,
+     * precedence is given to an open partition ending at <code>offset</code>
+     * over a delimited partition starting at <code>offset</code>.
+     * <p>
+     * This method replaces {@link IDocumentPartitioner#getContentType(int)}and
+     * behaves like it when <code>prepreferOpenPartitions</code> is
+     * <code>false</code>, i.e. precedence is always given to the partition
+     * that does not end at <code>offset</code>.
+     * </p>
+     *
+     * @param offset the offset in the connected document
+     * @param preferOpenPartitions <code>true</code> if precedence should be
+     *            given to a open partition ending at <code>offset</code> over
+     *            a delimited partition starting at <code>offset</code>
+     * @return the content type of the offset's partition
+     */
+    String getContentType(int offset, bool preferOpenPartitions);
+
+    /**
+     * Returns the partition containing the given offset of the connected
+     * document. There must be a document connected to this partitioner.
+     * <p>
+     * If <code>preferOpenPartitions</code> is <code>true</code>,
+     * precedence is given to an open partition ending at <code>offset</code>
+     * over a delimited partition starting at <code>offset</code>.
+     * <p>
+     * This method replaces {@link IDocumentPartitioner#getPartition(int)}and
+     * behaves like it when <preferOpenPartitions</code> is <code>false
+     * </code>, i.e. precedence is always given to the partition that does not
+     * end at <code>offset</code>.
+     * </p>
+     *
+     * @param offset the offset for which to determine the partition
+     * @param preferOpenPartitions <code>true</code> if precedence should be
+     *            given to a open partition ending at <code>offset</code> over
+     *            a delimited partition starting at <code>offset</code>
+     * @return the partition containing the offset
+     */
+    ITypedRegion getPartition(int offset, bool preferOpenPartitions);
+
+    /**
+     * Returns the partitioning of the given range of the connected document.
+     * There must be a document connected to this partitioner.
+     * <p>
+     * If <code>includeZeroLengthPartitions</code> is <code>true</code>, a
+     * zero-length partition of an open partition type (usually the default
+     * partition) is included between two delimited partitions. If it is
+     * <code>false</code>, no zero-length partitions are included.
+     * </p>
+     * <p>
+     * This method replaces
+     * {@link IDocumentPartitioner#computePartitioning(int, int)}and behaves
+     * like it when <code>includeZeroLengthPartitions</code> is
+     * <code>false</code>.
+     * </p>
+     *
+     * @param offset the offset of the range of interest
+     * @param length the length of the range of interest
+     * @param includeZeroLengthPartitions <code>true</code> if zero-length
+     *            partitions should be returned as part of the computed
+     *            partitioning
+     * @return the partitioning of the range
+     */
+    ITypedRegion[] computePartitioning(int offset, int length, bool includeZeroLengthPartitions);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentPartitionerExtension3.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IDocumentPartitionerExtension3;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IDocumentPartitioner}. Adds the
+ * concept of rewrite sessions. A rewrite session is a sequence of replace
+ * operations that form a semantic unit.
+ *
+ * @since 3.1
+ */
+public interface IDocumentPartitionerExtension3 {
+
+    /**
+     * Tells the document partitioner that a rewrite session started. A rewrite
+     * session is a sequence of replace operations that form a semantic unit.
+     * The document partitioner is allowed to use that information for internal
+     * optimization.
+     *
+     * @param session the rewrite session
+     * @throws IllegalStateException in case there is already an active rewrite session
+     */
+    void startRewriteSession(DocumentRewriteSession session) ;
+
+    /**
+     * Tells the document partitioner that the rewrite session has finished.
+     * This method is only called when <code>startRewriteSession</code> has
+     * been called before.
+     *
+     * @param session the rewrite session
+     */
+    void stopRewriteSession(DocumentRewriteSession session);
+
+    /**
+     * Returns the active rewrite session of this document or <code>null</code>.
+     *
+     * @return the active rewrite session or <code>null</code>
+     */
+    DocumentRewriteSession getActiveRewriteSession();
+
+    /**
+     * Connects this partitioner to a document. Connect indicates the begin of
+     * the usage of the receiver as partitioner of the given document. Thus,
+     * resources the partitioner needs to be operational for this document
+     * should be allocated.
+     * <p>
+     * The caller of this method must ensure that this partitioner is also set
+     * as the document's document partitioner.
+     * <p>
+     * <code>delayInitialization</code> indicates whether the partitioner is
+     * allowed to delay it initial computation of the document's partitioning
+     * until it has to answer the first query.
+     *
+     * Replaces {@link IDocumentPartitioner#connect(IDocument)}.
+     *
+     * @param document the document to be connected to
+     * @param delayInitialization <code>true</code> if initialization can be delayed, <code>false</code> otherwise
+     */
+    void connect(IDocument document, bool delayInitialization);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentPartitioningListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IDocumentPartitioningListener;
+
+// import dwtx.jface.text.DefaultTextHover; // packageimport
+// import dwtx.jface.text.AbstractInformationControl; // packageimport
+// import dwtx.jface.text.TextUtilities; // packageimport
+// import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+// import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+// import dwtx.jface.text.ITextViewerExtension2; // packageimport
+// import dwtx.jface.text.IDocumentPartitioner; // packageimport
+// import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+// import dwtx.jface.text.ITextSelection; // packageimport
+// import dwtx.jface.text.Document; // packageimport
+// import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+// import dwtx.jface.text.ITextListener; // packageimport
+// import dwtx.jface.text.BadPartitioningException; // packageimport
+// import dwtx.jface.text.ITextViewerExtension5; // packageimport
+// import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+// import dwtx.jface.text.IUndoManager; // packageimport
+// import dwtx.jface.text.ITextHoverExtension2; // packageimport
+// import dwtx.jface.text.IRepairableDocument; // packageimport
+// import dwtx.jface.text.IRewriteTarget; // packageimport
+// import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+// import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+// import dwtx.jface.text.TextViewerHoverManager; // packageimport
+// import dwtx.jface.text.DocumentRewriteSession; // packageimport
+// import dwtx.jface.text.TextViewer; // packageimport
+// import dwtx.jface.text.ITextViewerExtension8; // packageimport
+// import dwtx.jface.text.RegExMessages; // packageimport
+// import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+// import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+// import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+// import dwtx.jface.text.IViewportListener; // packageimport
+// import dwtx.jface.text.GapTextStore; // packageimport
+// import dwtx.jface.text.MarkSelection; // packageimport
+// import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+// import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+// import dwtx.jface.text.IInformationControlExtension; // packageimport
+// import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+// import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+// import dwtx.jface.text.ITextViewerExtension3; // packageimport
+// import dwtx.jface.text.IInformationControlCreator; // packageimport
+// import dwtx.jface.text.TypedRegion; // packageimport
+// import dwtx.jface.text.ISynchronizable; // packageimport
+// import dwtx.jface.text.IMarkRegionTarget; // packageimport
+// import dwtx.jface.text.TextViewerUndoManager; // packageimport
+// import dwtx.jface.text.IRegion; // packageimport
+// import dwtx.jface.text.IInformationControlExtension2; // packageimport
+// import dwtx.jface.text.IDocumentExtension4; // packageimport
+// import dwtx.jface.text.IDocumentExtension2; // packageimport
+// import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+// import dwtx.jface.text.Assert; // packageimport
+// import dwtx.jface.text.DefaultInformationControl; // packageimport
+// import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+// import dwtx.jface.text.DocumentClone; // packageimport
+// import dwtx.jface.text.DefaultUndoManager; // packageimport
+// import dwtx.jface.text.IFindReplaceTarget; // packageimport
+// import dwtx.jface.text.IAutoEditStrategy; // packageimport
+// import dwtx.jface.text.ILineTrackerExtension; // packageimport
+// import dwtx.jface.text.IUndoManagerExtension; // packageimport
+// import dwtx.jface.text.TextSelection; // packageimport
+// import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+// import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+// import dwtx.jface.text.IPainter; // packageimport
+// import dwtx.jface.text.IInformationControl; // packageimport
+// import dwtx.jface.text.IInformationControlExtension3; // packageimport
+// import dwtx.jface.text.ITextViewerExtension6; // packageimport
+// import dwtx.jface.text.IInformationControlExtension4; // packageimport
+// import dwtx.jface.text.DefaultLineTracker; // packageimport
+// import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+// import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+// import dwtx.jface.text.ITextHover; // packageimport
+// import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+// import dwtx.jface.text.ILineTracker; // packageimport
+// import dwtx.jface.text.Line; // packageimport
+// import dwtx.jface.text.ITextViewerExtension; // packageimport
+// import dwtx.jface.text.IDocumentAdapter; // packageimport
+// import dwtx.jface.text.TextEvent; // packageimport
+// import dwtx.jface.text.BadLocationException; // packageimport
+// import dwtx.jface.text.AbstractDocument; // packageimport
+// import dwtx.jface.text.AbstractLineTracker; // packageimport
+// import dwtx.jface.text.TreeLineTracker; // packageimport
+// import dwtx.jface.text.ITextPresentationListener; // packageimport
+// import dwtx.jface.text.Region; // packageimport
+// import dwtx.jface.text.ITextViewer; // packageimport
+// import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+// import dwtx.jface.text.MarginPainter; // packageimport
+// import dwtx.jface.text.IPaintPositionManager; // packageimport
+// import dwtx.jface.text.TextPresentation; // packageimport
+// import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+// import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+// import dwtx.jface.text.ISelectionValidator; // packageimport
+// import dwtx.jface.text.IDocumentExtension; // packageimport
+// import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+// import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+// import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+// import dwtx.jface.text.IDocumentListener; // packageimport
+// import dwtx.jface.text.PaintManager; // packageimport
+// import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+// import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+// import dwtx.jface.text.IDocumentExtension3; // packageimport
+// import dwtx.jface.text.Position; // packageimport
+// import dwtx.jface.text.TextMessages; // packageimport
+// import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+// import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+// import dwtx.jface.text.IPositionUpdater; // packageimport
+// import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+// import dwtx.jface.text.ListLineTracker; // packageimport
+// import dwtx.jface.text.ITextInputListener; // packageimport
+// import dwtx.jface.text.BadPositionCategoryException; // packageimport
+// import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+// import dwtx.jface.text.IInputChangedListener; // packageimport
+// import dwtx.jface.text.ITextOperationTarget; // packageimport
+// import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+// import dwtx.jface.text.ITextViewerExtension7; // packageimport
+// import dwtx.jface.text.IInformationControlExtension5; // packageimport
+// import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+// import dwtx.jface.text.JFaceTextUtil; // packageimport
+// import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+// import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+// import dwtx.jface.text.CursorLinePainter; // packageimport
+// import dwtx.jface.text.ITextHoverExtension; // packageimport
+// import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+// import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+// import dwtx.jface.text.DocumentCommand; // packageimport
+// import dwtx.jface.text.TypedPosition; // packageimport
+// import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+// import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+// import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+// import dwtx.jface.text.IEditingSupport; // packageimport
+// import dwtx.jface.text.IMarkSelection; // packageimport
+// import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+// import dwtx.jface.text.DocumentEvent; // packageimport
+// import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+// import dwtx.jface.text.ITextStore; // packageimport
+// import dwtx.jface.text.JFaceTextMessages; // packageimport
+// import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+// import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+// import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+// import dwtx.jface.text.TextAttribute; // packageimport
+// import dwtx.jface.text.ITextViewerExtension4; // packageimport
+// import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+/**
+ * Interface of objects which are interested in getting informed
+ * about changes of a document's partitioning.
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ * <p>
+ * In order to provided backward compatibility for clients of <code>IDocumentPartitioningListener</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces
+ * exist:
+ * <ul>
+ * <li> {@link dwtx.jface.text.IDocumentPartitioningListenerExtension} since version 2.0 replacing the original
+ *      notification mechanism.</li>
+ * <li> {@link dwtx.jface.text.IDocumentPartitioningListenerExtension2} since version 3.0 replacing all previous
+ *      notification mechanisms. Thus, implementers up-to-date with version 3.0 do not have to implement
+ *      {@link dwtx.jface.text.IDocumentPartitioningListenerExtension}.</li>
+ * </ul>
+ * </p>
+ * @see dwtx.jface.text.IDocumentPartitioningListenerExtension
+ * @see dwtx.jface.text.IDocumentPartitioningListenerExtension2
+ * @see dwtx.jface.text.IDocument
+ * @see dwtx.jface.text.IDocumentPartitioner
+ */
+public interface IDocumentPartitioningListener {
+
+    /**
+     * The partitioning of the given document changed.
+     * <p>
+     * In version 2.0 this method has been replaces by
+     * {@link IDocumentPartitioningListenerExtension#documentPartitioningChanged(IDocument, IRegion)}.
+     * <p>
+     * In version 3.0 this method has been replaces by
+     * {@link IDocumentPartitioningListenerExtension2#documentPartitioningChanged(DocumentPartitioningChangedEvent)}<p>
+     *
+     * @param document the document whose partitioning changed
+     *
+     * @see IDocumentPartitioningListenerExtension#documentPartitioningChanged(IDocument, IRegion)
+     * @see IDocumentPartitioningListenerExtension2#documentPartitioningChanged(DocumentPartitioningChangedEvent)
+     * @see IDocument#addDocumentPartitioningListener(IDocumentPartitioningListener)
+     */
+    void documentPartitioningChanged(IDocument document);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentPartitioningListenerExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IDocumentPartitioningListenerExtension;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for
+ * {@link dwtx.jface.text.IDocumentPartitioningListener}.
+ * <p>
+ * Replaces the original notification mechanism by telling the listener the
+ * minimal region that comprises all partitioning changes.
+ *
+ * @see dwtx.jface.text.IDocumentPartitionerExtension
+ * @since 2.0
+ */
+public interface IDocumentPartitioningListenerExtension {
+
+    /**
+     * The partitioning of the given document changed in the given region.
+     * <p>
+     * In version 3.0, this method has been replaced with
+     * {@link IDocumentPartitioningListenerExtension2#documentPartitioningChanged(DocumentPartitioningChangedEvent)}.
+     *
+     * @param document the document whose partitioning changed
+     * @param region the region in which the partitioning changed
+     * @see IDocumentPartitioningListenerExtension2#documentPartitioningChanged(DocumentPartitioningChangedEvent)
+     * @see IDocument#addDocumentPartitioningListener(IDocumentPartitioningListener)
+     */
+    void documentPartitioningChanged(IDocument document, IRegion region);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentPartitioningListenerExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IDocumentPartitioningListenerExtension2;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface to
+ * {@link dwtx.jface.text.IDocumentPartitioningListener}.
+ * <p>
+ *
+ * Replaces the previous notification mechanisms by introducing an explicit
+ * document partitioning changed event.
+ *
+ * @see dwtx.jface.text.DocumentPartitioningChangedEvent
+ * @since 3.0
+ */
+public interface IDocumentPartitioningListenerExtension2 {
+
+    /**
+     * Signals the change of document partitionings.
+     * <p>
+     * This method replaces
+     * {@link IDocumentPartitioningListener#documentPartitioningChanged(IDocument)}
+     * and
+     * {@link IDocumentPartitioningListenerExtension#documentPartitioningChanged(IDocument, IRegion)}
+     *
+     * @param event the event describing the change
+     * @see IDocument#addDocumentPartitioningListener(IDocumentPartitioningListener)
+     */
+    void documentPartitioningChanged(DocumentPartitioningChangedEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IDocumentRewriteSessionListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IDocumentRewriteSessionListener;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Interface for objects which are interested in getting informed about document
+ * rewrite sessions.
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ *
+ * @see dwtx.jface.text.IDocument
+ * @see dwtx.jface.text.IDocumentExtension4
+ * @since 3.1
+ */
+public interface IDocumentRewriteSessionListener {
+
+    /**
+     * Signals a change in a document's rewrite session state.
+     *
+     * @param event the event describing the document rewrite session state change
+     */
+    void documentRewriteSessionChanged(DocumentRewriteSessionEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IEditingSupport.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IEditingSupport;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Implemented by tools supporting the editing process.
+ * <p>
+ * Clients may ask an <code>IEditingSupport</code> whether it is currently
+ * displaying a shell that has focus, and whether it is the origin of a document
+ * event. Depending on the answers to these queries, clients may decide to react
+ * differently to incoming notifications about events. For example, a special
+ * editing mode, that usually deactivates when the main shell looses focus, may
+ * decide to not deactivate if the focus event was triggered by an
+ * <code>IEditingSupport</code>.
+ * </p>
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ *
+ * @see IEditingSupportRegistry
+ * @since 3.1
+ */
+public interface IEditingSupport {
+    /**
+     * Returns <code>true</code> if the receiver is the originator of a
+     * <code>DocumentEvent</code> and if that <code>event</code> is related
+     * to <code>subjectRegion</code>.
+     * <p>
+     * The relationship between <code>event</code> and
+     * <code>subjectRegion</code> is not always obvious. Often, the main
+     * editing area being monitored by the caller will be at
+     * <code>subjectRegion</code>, when the receiver modifies the underlying
+     * document at a different location without wanting to interrupt the normal
+     * typing flow of the user.
+     * </p>
+     * <p>
+     * An example would be an editor that automatically increments the section
+     * number of the next section when the user typed in a new section title. In
+     * this example, the subject region is the current typing location, while
+     * the increment results in a document change further down in the text.
+     * </p>
+     *
+     * @param event the <code>DocumentEvent</code> in question
+     * @param subjectRegion the region that the caller is interested in
+     * @return <code>true</code> if <code>event</code> was triggered by the
+     *         receiver and relates to <code>subjectRegion</code>
+     */
+    bool isOriginator(DocumentEvent event, IRegion subjectRegion);
+
+    /**
+     * Returns <code>true</code> if the receiver is showing a shell which has
+     * focus, <code>false</code> if it does not have focus or the helper has
+     * no shell.
+     *
+     * @return <code>true</code> if the support's shell has focus,
+     *         <code>false</code> otherwise
+     */
+    bool ownsFocusShell();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IEditingSupportRegistry.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IEditingSupportRegistry;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * A registry for <code>IEditingSupport</code>s.
+ * <p>
+ * This interface is not meant to be implemented outside the JFace text
+ * framework.</p>
+ * 
+ * @see IEditingSupport
+ * @since 3.1
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IEditingSupportRegistry {
+
+    /**
+     * Register a support with the registry. If the support is already
+     * registered, nothing happens.
+     *
+     * @param support an editor support
+     */
+    public void register(IEditingSupport support);
+
+    /**
+     * Deregister a support with the registry. If the support is not registered,
+     * or <code>support</code> is <code>null</code>, nothing happens.
+     *
+     * @param support the helper to deregister, or <code>null</code>
+     */
+    public void unregister(IEditingSupport support);
+
+    /**
+     * Returns the current editor helpers.
+     *
+     * @return an non- <code>null</code> array of currently registered editor
+     *         helpers
+     */
+    public IEditingSupport[] getRegisteredSupports();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IEventConsumer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IEventConsumer;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.events.VerifyEvent;
+
+/**
+ * Implementers can register with a text viewer and receive
+ * <code>VerifyEvent</code>s before the text viewer they are registered with.
+ * If the event consumer marks events as processed by turning their
+ * <code>doit</code> field to <code>false</code> the text viewer
+ * subsequently ignores them.</p>
+ * <p>
+ * Clients may implement this interface.</p>
+ * <p>
+ * {@link dwtx.jface.text.ITextViewerExtension2}allows clients to manage
+ * the {@link dwt.events.VerifyListener}s of a text viewer. This
+ * makes <code>IEventConsumer</code> obsolete.</p>
+ *
+ * @see dwtx.jface.text.ITextViewer
+ * @see dwtx.jface.text.ITextViewerExtension2
+ * @see dwt.events.VerifyEvent
+ */
+public interface IEventConsumer {
+
+    /**
+     * Processes the given event and marks it as done if it should
+     * be ignored by subsequent receivers.
+     *
+     * @param event the verify event which will be investigated
+     */
+    public void processEvent(VerifyEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IFindReplaceTarget.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,247 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IFindReplaceTarget;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwt.graphics.Point;
+
+
+/**
+ * Defines the target for finding and replacing strings.
+ * <p>
+ * The two main methods are <code>findAndSelect</code> and
+ * <code>replaceSelection</code>. The target does not provide any way to
+ * modify the content other than replacing the selection.
+ * <p>
+ *
+ * In order to provide backward compatibility for clients of
+ * <code>IFindReplaceTarget</code>, extension interfaces are used as a means
+ * of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.IFindReplaceTargetExtension} since version
+ *     2.0 introducing the notion of find/replace session and of a find/replace
+ *     scope. In additions, in allows clients to replace all occurrences of a given
+ *     find query.</li>
+ * <li>{@link dwtx.jface.text.IFindReplaceTargetExtension3} since
+ *     version 3.0 allowing clients to specify search queries as regular
+ *     expressions.</li>
+ * </ul>
+ * <p>
+ * Clients of a <code>IFindReplaceTarget</code> that also implements the
+ * <code>IFindReplaceTargetExtension</code> have to indicate the start of a find/replace
+ * session before using the target and to indicate the end of the session when the
+ * target is no longer used.
+ *
+ * @see dwtx.jface.text.IFindReplaceTargetExtension
+ * @see dwtx.jface.text.IFindReplaceTargetExtension3
+ */
+public interface IFindReplaceTarget {
+
+    /**
+     * Returns whether a find operation can be performed.
+     *
+     * @return whether a find operation can be performed
+     */
+    bool canPerformFind();
+
+    /**
+     * Searches for a string starting at the given widget offset and using the specified search
+     * directives. If a string has been found it is selected and its start offset is
+     * returned.
+     * <p>
+     * Replaced by {@link IFindReplaceTargetExtension3#findAndSelect(int, String, bool, bool, bool, bool)}.
+     *
+     * @param widgetOffset the widget offset at which searching starts
+     * @param findString the string which should be found
+     * @param searchForward <code>true</code> searches forward, <code>false</code> backwards
+     * @param caseSensitive <code>true</code> performs a case sensitive search, <code>false</code> an insensitive search
+     * @param wholeWord if <code>true</code> only occurrences are reported in which the findString stands as a word by itself
+     * @return the position of the specified string, or -1 if the string has not been found
+     */
+    int findAndSelect(int widgetOffset, String findString, bool searchForward, bool caseSensitive, bool wholeWord);
+
+    /**
+     * Returns the currently selected range of characters as a offset and length in widget coordinates.
+     *
+     * @return the currently selected character range in widget coordinates
+     */
+    Point getSelection();
+
+    /**
+     * Returns the currently selected characters as a string.
+     *
+     * @return the currently selected characters
+     */
+    String getSelectionText();
+
+    /**
+     * Returns whether this target can be modified.
+     *
+     * @return <code>true</code> if target can be modified
+     */
+    bool isEditable();
+
+    /**
+     * Replaces the currently selected range of characters with the given text.
+     * This target must be editable. Otherwise nothing happens.
+     * <p>
+     * Replaced by {@link IFindReplaceTargetExtension3#replaceSelection(String, bool)}.
+     *
+     * @param text the substitution text
+     */
+    void replaceSelection(String text);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IFindReplaceTargetExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,240 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IFindReplaceTargetExtension;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwt.graphics.Color;
+import dwt.graphics.Point;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IFindReplaceTarget}.
+ * <p>
+ * Introduces the concepts of find/replace sessions, searching in a limiting
+ * scope and a replace-all mode.
+ * <p>
+ * If a scope is set, <code>findAndSelect</code> is limited to the scope.
+ * Occurrences outside of the scope are not considered.
+ *
+ * @since 2.0
+ */
+public interface IFindReplaceTargetExtension {
+
+    /**
+     * Indicates that a session with the target begins.
+     * All calls except <code>beginSession()</code> and <code>endSession()</code> to
+     * <code>IFindReplaceTarget</code> and
+     * <code>IFindReplaceTargetExtension</code> must be embedded within calls to
+     * <code>beginSession()</code> and <code>endSession()</code>.
+     *
+     * @see #endSession()
+     */
+    void beginSession();
+
+    /**
+     * Indicates that a session with the target ends.
+     *
+     * @see #beginSession()
+     */
+    void endSession();
+
+    /**
+     * Returns the find scope of the target, <code>null</code> for global scope.
+     *
+     * @return returns the find scope of the target, may be <code>null</code>
+     */
+    IRegion getScope();
+
+    /**
+     * Sets the find scope of the target to operate on. <code>null</code>
+     * indicates that the global scope should be used.
+     *
+     * @param scope the find scope of the target, may be <code>null</code>
+     */
+    void setScope(IRegion scope_);
+
+    /**
+     * Returns the currently selected range of lines as a offset and length.
+     *
+     * @return the currently selected line range
+     */
+    Point getLineSelection();
+
+    /**
+     * Sets a selection.
+     *
+     * @param offset the offset of the selection
+     * @param length the length of the selection
+     */
+    void setSelection(int offset, int length);
+
+    /**
+     * Sets the scope highlight color
+     *
+     * @param color the color of the scope highlight
+     */
+    void setScopeHighlightColor(Color color);
+
+
+    /**
+     * Sets the target's replace-all mode.
+     *
+     * @param replaceAll <code>true</code> if this target should switch into replace-all mode,
+     *  <code>false</code> if it should leave the replace-all state
+     */
+    void setReplaceAllMode(bool replaceAll);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IFindReplaceTargetExtension3.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,207 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IFindReplaceTargetExtension3;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IFindReplaceTarget}.
+ * <p>
+ * Extends the find replace target's <code>findAndSelect</code> and
+ * <code>replaceSelection</code> methods to allow and be aware of regular
+ * expression find/replace.
+ *
+ * @since 3.0
+ */
+public interface IFindReplaceTargetExtension3 {
+
+    /**
+     * Searches for a string starting at the given offset and using the specified search
+     * directives. If a string has been found it is selected and its start offset is
+     * returned. If regExSearch is <code>true</code> the findString is
+     * interpreted as a regular expression.
+     *
+     * @param offset the offset at which searching starts
+     * @param findString the specification of what should be found
+     * @param searchForward <code>true</code> searches forward, <code>false</code> backwards
+     * @param caseSensitive <code>true</code> performs a case sensitive search, <code>false</code> an insensitive search
+     * @param wholeWord if <code>true</code> only occurrences are reported in which the findString stands as a word by itself.
+     *              Must not be used in combination with <code>regExSearch</code>.
+     * @param regExSearch if <code>true</code> findString represents a regular expression
+     *              Must not be used in combination with <code>wholeWord</code>.
+     * @return the position of the specified string, or -1 if the string has not been found
+     * @throws java.util.regex.PatternSyntaxException if regExSearch is <code>true</code> and findString is an invalid regular expression
+     */
+    int findAndSelect(int offset, String findString, bool searchForward, bool caseSensitive, bool wholeWord, bool regExSearch);
+
+    /**
+     * Replaces the currently selected range of characters with the given text.
+     * If regExReplace is <code>true</code> the text is interpreted as a
+     * regular expression that is used to process the selected text in order to
+     * produce the actual replacement of the selected text.
+     * <p>
+     * This target must be editable. Otherwise nothing happens.
+     *
+     * @param text the specification of the substitution text
+     * @param regExReplace if <code>true</code> text represents a regular
+     *            expression
+     * @throws IllegalStateException in case of regular expressions, this call
+     *             is not preceded by a call to <code>findAndSelect</code>
+     * @throws java.util.regex.PatternSyntaxException if regExReplace is
+     *             <code>true</code> and text is an invalid regular expression
+     */
+    void replaceSelection(String text, bool regExReplace);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IInformationControl.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,345 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IInformationControl;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+import dwt.DWT;
+import dwt.events.DisposeListener;
+import dwt.events.FocusListener;
+import dwt.graphics.Color;
+import dwt.graphics.Point;
+
+
+/**
+ * Interface of a control presenting information. The information is given in
+ * the form of an input object. It can be either the content itself or a
+ * description of the content. The specification of what is required from an
+ * input object is left to the implementers of this interface.
+ * <p>
+ * <em>If this information control is used by a {@link AbstractHoverInformationControlManager}
+ * then that manager will own this control and override any properties that
+ * may have been set before by any other client.</em></p>
+ * <p>
+ * The information control must not grab focus when made visible using
+ * <code>setVisible(true)</code>.
+ *
+ * In order to provide backward compatibility for clients of
+ * <code>IInformationControl</code>, extension interfaces are used as a means
+ * of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.IInformationControlExtension} since
+ *     version 2.0 introducing the predicate of whether the control has anything to
+ *     show or would be empty</li>
+ * <li>{@link dwtx.jface.text.IInformationControlExtension2} since
+ *     version 2.1 replacing the original concept of textual input by general input
+ *     objects.</li>
+ * <li>{@link dwtx.jface.text.IInformationControlExtension3} since
+ *     version 3.0 providing access to the control's bounds and introducing
+ *     the concept of persistent size and location.</li>
+ * <li>{@link dwtx.jface.text.IInformationControlExtension4} since
+ *     version 3.3, adding API which allows to set this information control's status field text.</li>
+ * <li>{@link dwtx.jface.text.IInformationControlExtension5} since
+ *     version 3.4, adding API to get the visibility of the control, to
+ *     test whether another control is a child of the information control,
+ *     to compute size constraints based on the information control's main font
+ *     and to return a control creator for an enriched version of this information control.</li>
+ * </ul>
+ * <p>
+ * Clients can implement this interface and its extension interfaces,
+ * subclass {@link AbstractInformationControl}, or use the (text-based)
+ * default implementation {@link DefaultInformationControl}.
+ *
+ * @see dwtx.jface.text.IInformationControlExtension
+ * @see dwtx.jface.text.IInformationControlExtension2
+ * @see dwtx.jface.text.IInformationControlExtension3
+ * @see dwtx.jface.text.IInformationControlExtension4
+ * @see dwtx.jface.text.IInformationControlExtension5
+ * @see AbstractInformationControl
+ * @see DefaultInformationControl
+ * @since 2.0
+ */
+public interface IInformationControl {
+
+    /**
+     * Sets the information to be presented by this information control.
+     * <p>
+     * Replaced by {@link IInformationControlExtension2#setInput(Object)}.
+     *
+     * @param information the information to be presented
+     */
+    void setInformation(String information);
+
+    /**
+     * Sets the information control's size constraints. A constraint value of
+     * {@link DWT#DEFAULT} indicates no constraint. This method must be called before
+     * {@link #computeSizeHint()} is called.
+     * <p>
+     * Note: An information control which implements {@link IInformationControlExtension3}
+     * may ignore this method or use it as hint for its very first appearance.
+     * </p>
+     * @param maxWidth the maximal width of the control  to present the information, or {@link DWT#DEFAULT} for not constraint
+     * @param maxHeight the maximal height of the control to present the information, or {@link DWT#DEFAULT} for not constraint
+     */
+    void setSizeConstraints(int maxWidth, int maxHeight);
+
+    /**
+     * Computes and returns a proposal for the size of this information control depending
+     * on the information to present. The method tries to honor known size constraints but might
+     * return a size that exceeds them.
+     *
+     * @return the computed size hint
+     */
+    Point computeSizeHint();
+
+    /**
+     * Controls the visibility of this information control.
+     * <p>
+     * <strong>Note:</strong> The information control must not grab focus when
+     * made visible.
+     * </p>
+     * 
+     * @param visible <code>true</code> if the control should be visible
+     */
+    void setVisible(bool visible);
+
+    /**
+     * Sets the size of this information control.
+     *
+     * @param width the width of the control
+     * @param height the height of the control
+     */
+    void setSize(int width, int height);
+
+    /**
+     * Sets the location of this information control.
+     *
+     * @param location the location
+     */
+    void setLocation(Point location);
+
+    /**
+     * Disposes this information control.
+     */
+    void dispose();
+
+    /**
+     * Adds the given listener to the list of dispose listeners.
+     * If the listener is already registered it is not registered again.
+     *
+     * @param listener the listener to be added
+     */
+    void addDisposeListener(DisposeListener listener);
+
+    /**
+     * Removes the given listeners from the list of dispose listeners.
+     * If the listener is not registered this call has no effect.
+     *
+     * @param listener the listener to be removed
+     */
+    void removeDisposeListener(DisposeListener listener);
+
+    /**
+     * Sets the foreground color of this information control.
+     *
+     * @param foreground the foreground color of this information control
+     */
+    void setForegroundColor(Color foreground);
+
+    /**
+     * Sets the background color of this information control.
+     *
+     * @param background the background color of this information control
+     */
+    void setBackgroundColor(Color background);
+
+    /**
+     * Returns whether this information control (or one of its children) has the focus.
+     * The suggested implementation is like this (<code>fShell</code> is this information control's shell):
+     * <pre>return fShell.getDisplay().getActiveShell() is fShell</pre>
+     *
+     * @return <code>true</code> when the information control has the focus, otherwise <code>false</code>
+     */
+    bool isFocusControl();
+
+    /**
+     * Sets the keyboard focus to this information control.
+     */
+    void setFocus();
+
+    /**
+     * Adds the given listener to the list of focus listeners.
+     * If the listener is already registered it is not registered again.
+     * <p>
+     * The suggested implementation is to install listeners for {@link DWT#Activate} and {@link DWT#Deactivate}
+     * on the shell and forward events to the focus listeners. Clients are
+     * encouraged to subclass {@link AbstractInformationControl}, which does this
+     * for free.
+     * </p>
+     * 
+     * @param listener the listener to be added
+     */
+    void addFocusListener(FocusListener listener);
+
+    /**
+     * Removes the given listeners from the list of focus listeners.
+     * If the listener is not registered this call has no affect.
+     *
+     * @param listener the listener to be removed
+     */
+    void removeFocusListener(FocusListener listener);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IInformationControlCreator.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IInformationControlCreator;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwt.widgets.Shell;
+
+
+/**
+ * Interface of a factory for information controls (
+ * {@link dwtx.jface.text.IInformationControl}).
+ *
+ * In order to provide backward compatibility for clients of
+ * <code>IInformationControlCreator</code>, extension interfaces are used as
+ * a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.IInformationControlCreatorExtension} since
+ *     version 3.0 introducing checks of whether existing information control can
+ *     be reused and whether information control creators can replace each other.
+ * </li>
+ * </ul>
+ *
+ * @see dwtx.jface.text.IInformationControlCreatorExtension
+ * @since 2.0
+ */
+public interface IInformationControlCreator {
+
+    /**
+     * Creates a new information control with the given shell as the control's parent.
+     *
+     * @param parent the parent shell
+     * @return the created information control
+     */
+    IInformationControl createInformationControl(Shell parent);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IInformationControlCreatorExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IInformationControlCreatorExtension;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IInformationControlCreator}<p>
+ * Introduces tests whether information controls can be reused and whether information
+ * control creators can replace each other.
+ *
+ * @see dwtx.jface.text.IInformationControlCreator
+ * @see dwtx.jface.text.IInformationControl
+ * @since 3.0
+ */
+public interface IInformationControlCreatorExtension {
+
+    /**
+     * Tests if an existing information control can be reused.
+     *
+     * @param control the information control to test
+     * @return <code>true</code> if the control can be reused
+     */
+    bool canReuse(IInformationControl control);
+
+    /**
+     * Tests whether this information control creator can replace the given
+     * information control creator. This is the case if the two creators create
+     * the same kind of information controls.
+     *
+     * @param creator the creator to be checked
+     * @return <code>true</code> if the given creator can be replaced,
+     *         <code>false</code> otherwise
+     */
+    bool canReplace(IInformationControlCreator creator);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IInformationControlExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IInformationControlExtension;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface {@link dwtx.jface.text.IInformationControl}.
+ * <p>
+ * As it is the responsibility of the implementer of
+ * {@link dwtx.jface.text.IInformationControl} and
+ * {@link dwtx.jface.text.IInformationControlExtension2} to specify the
+ * concrete nature of the information control's input, only the implementer can
+ * know whether it has something to show or not.
+ *
+ * @since 2.0
+ */
+public interface IInformationControlExtension {
+
+    /**
+     * Returns whether this information control has contents to be displayed.
+     *
+     * @return <code>true</code> if there is contents to be displayed.
+     */
+    bool hasContents();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IInformationControlExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IInformationControlExtension2;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IInformationControl}.
+ * <p>
+ * Replaces the concept of textual information to be displayed with the more
+ * general concept of an input of the information control. Text to be displayed
+ * set with <code>setInformation(String)</code> is ignored.
+ *
+ * @see dwtx.jface.text.IInformationControl
+ * @since 2.1
+ */
+public interface IInformationControlExtension2 {
+
+    /**
+     * Sets the input to be presented in this information control. The concrete
+     * contract the input object is expected to adhere is defined by the
+     * implementer of this interface.
+     *
+     * @param input the object to be used as input for this control
+     */
+    void setInput(Object input);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IInformationControlExtension3.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,227 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IInformationControlExtension3;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.graphics.Rectangle;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IInformationControl}.
+ * Adds API which allows to get this information control's bounds and introduces
+ * the concept of persistent size and location by introducing predicates for
+ * whether the information control supports restoring of size and location.
+ * <p>
+ * Note: An information control which implements this interface can ignore calls
+ * to
+ * {@link dwtx.jface.text.IInformationControl#setSizeConstraints(int, int)}
+ * or use it as hint for its very first appearance.
+ * </p>
+ *
+ * @see dwtx.jface.text.IInformationControl
+ * @since 3.0
+ */
+public interface IInformationControlExtension3 {
+
+    /**
+     * Returns a rectangle describing the receiver's size and location
+     * relative to its parent (or its display if its parent is null).
+     * <p>
+     * Note: If the receiver is already disposed then this methods must
+     * return the last valid location and size.
+     * </p>
+     *
+     * @return the receiver's bounding rectangle
+     */
+    Rectangle getBounds();
+
+    /**
+     * Computes the trim for this control. The trim is the space around the
+     * information control's actual content area. It includes all borders of the
+     * control and other static content placed around the content area (e.g. a
+     * toolbar).
+     * 
+     * @return The receiver's trim. <code>x</code> and <code>y</code> denote
+     *         the upper left corner of the trimming relative to this control's
+     *         location i.e. this will most likely be negative values.
+     *         <code>width</code> and <code>height</code> represent the
+     *         border sizes (the sum of the horizontal and vertical trimmings,
+     *         respectively).
+     */
+    Rectangle computeTrim();
+
+    /**
+     * Tells whether this control allows to restore the previously
+     * used size.
+     * <p>
+     * Note: This is not a static property - it can change during the
+     * lifetime of this control.</p>
+     *
+     * @return <code>true</code> if restoring size is supported
+     */
+    bool restoresSize();
+
+    /**
+     * Tells whether this control allows to restore the previously
+     * used location.
+     * <p>
+     * Note: This is not a static property - it can change during the
+     * lifetime of this control.</p>
+     *
+     * @return <code>true</code> if restoring location is supported
+     */
+    bool restoresLocation();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IInformationControlExtension4.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IInformationControlExtension4;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IInformationControl}.
+ * Adds API which allows to set this information control's status field text.
+ *
+ * @see dwtx.jface.text.IInformationControl
+ * @since 3.3
+ */
+public interface IInformationControlExtension4 {
+
+    /**
+     * Sets the text of the status field.
+     * <p>
+     * The implementor can specify whether the new text affects an
+     * already visible information control.
+     * </p>
+     * 
+     * @param statusFieldText the text to be used in the optional status field
+     *                         or <code>null</code> if the status field should be hidden
+     * @since 3.2
+     */
+    public void setStatusText(String statusFieldText);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IInformationControlExtension5.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,254 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IInformationControlExtension5;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.DWT;
+import dwt.graphics.Point;
+import dwt.widgets.Control;
+import dwtx.jface.resource.JFaceResources;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IInformationControl}.
+ * Adds API
+ * <ul>
+ * <li>to test the visibility of the control,</li>
+ * <li>to test whether another control is a child of the information control,</li>
+ * <li>to compute size constraints based on the information control's main font and</li>
+ * <li>to return a control creator for an enriched version of this information control.</li>
+ * </ul>
+ * 
+ * <p>
+ * <b>Important:</b> Enriching this information control only works properly if
+ * {@link IInformationControl#isFocusControl()} is implemented like this (<code>fShell</code>
+ * is the control's shell):
+ * 
+ * <pre>
+ * return fShell.getDisplay().getActiveShell() is fShell
+ * </pre>
+ * Likewise,
+ * {@link IInformationControl#addFocusListener(dwt.events.FocusListener)}
+ * should install listeners for {@link DWT#Activate} and {@link DWT#Deactivate}
+ * on the shell and forward events to the focus listeners. Clients are
+ * encouraged to subclass {@link AbstractInformationControl}, which does this
+ * for free.
+ * </p>
+ * 
+ * @see dwtx.jface.text.IInformationControl
+ * @since 3.4
+ */
+public interface IInformationControlExtension5 {
+
+    /**
+     * Tests whether the given control is this information control
+     * or a child of this information control.
+     * 
+     * @param control the control to test
+     * @return <code>true</code> iff the given control is this information control
+     * or a child of this information control
+     */
+    public bool containsControl(Control control);
+    
+    /**
+     * @return <code>true</code> iff the information control is currently visible
+     */
+    public abstract bool isVisible();
+    
+    /**
+     * Computes the width- and height constraints of the information control in
+     * pixels, based on the given width and height in characters. Implementors
+     * should use the main font of the information control to do the
+     * characters-to-pixels conversion. This is typically the
+     * {@link JFaceResources#getDialogFont() dialog font}.
+     * 
+     * @param widthInChars the width constraint in number of characters
+     * @param heightInChars the height constraint in number of characters
+     * @return a point with width and height in pixels, or <code>null</code>
+     *         to use the subject control's font to calculate the size
+     */
+    public Point computeSizeConstraints(int widthInChars, int heightInChars);
+    
+    /**
+     * Returns the rich information control creator for this information control.
+     * <p>
+     * The returned information control creator is used to create an enriched version of this
+     * information control, e.g. when the mouse is moved into this control and it needs to be
+     * {@link ITextViewerExtension8#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode) enriched}
+     * or when it needs to be made sticky for other reasons.
+     * </p>
+     * <p>
+     * The returned information control creator must create information controls
+     * that implement {@link IInformationControlExtension3} and {@link IInformationControlExtension2},
+     * and whose {@link IInformationControlExtension2#setInput(Object)} accepts all inputs that are
+     * also supported by this information control.
+     * </p>
+     * <p>
+     * Note that automatic enriching of this information control works only if it also implements
+     * {@link IInformationControlExtension3}.
+     * </p>
+     * <p>
+     * This method may be called frequently, so implementors should ensure it returns quickly,
+     * e.g. by caching the returned creator.
+     * </p>
+     *
+     * @return the information presenter control creator or <code>null</code> to disable enriching
+     */
+    IInformationControlCreator getInformationPresenterControlCreator();
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IInputChangedListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IInputChangedListener;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A listener which is notified when the target's input changes.
+ * <p>
+ * Clients can implement that interface and its extension interfaces.</p>
+ *
+ * @since 3.4
+ */
+public interface IInputChangedListener {
+
+    /**
+     * Called when a the input has changed.
+     * 
+     * @param newInput the new input, or <code>null</code> iff the listener should not show any new input
+     */
+    void inputChanged(Object newInput);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ILineTracker.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,291 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ILineTracker;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A line tracker maps character positions to line numbers and vice versa.
+ * Initially the line tracker is informed about its underlying text in order to
+ * initialize the mapping information. After that, the line tracker is informed
+ * about all changes of the underlying text allowing for incremental updates of
+ * the mapping information. It is the client's responsibility to actively inform
+ * the line tacker about text changes. For example, when using a line tracker in
+ * combination with a document the document controls the line tracker.
+ * <p>
+ * In order to provide backward compatibility for clients of <code>ILineTracker</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces
+ * exist:
+ * <ul>
+ * <li> {@link dwtx.jface.text.ILineTrackerExtension} since version 3.1 introducing the concept
+ *      of rewrite sessions.</li>
+ * </ul>
+ * <p>
+ * Clients may implement this interface or use the standard implementation
+ * </p>
+ * {@link dwtx.jface.text.DefaultLineTracker}or
+ * {@link dwtx.jface.text.ConfigurableLineTracker}.
+ */
+public interface ILineTracker {
+
+    /**
+     * Returns the strings this tracker considers as legal line delimiters.
+     *
+     * @return the legal line delimiters
+     */
+    String[] getLegalLineDelimiters();
+
+    /**
+     * Returns the line delimiter of the specified line. Returns <code>null</code> if the
+     * line is not closed with a line delimiter.
+     *
+     * @param line the line whose line delimiter is queried
+     * @return the line's delimiter or <code>null</code> if line does not have a delimiter
+     * @exception BadLocationException if the line number is invalid in this tracker's line structure
+     */
+    String getLineDelimiter(int line) ;
+
+    /**
+     * Computes the number of lines in the given text.
+     *
+     * @param text the text whose number of lines should be computed
+     * @return the number of lines in the given text
+     */
+    int computeNumberOfLines(String text);
+
+    /**
+     * Returns the number of lines.
+     *
+     * @return the number of lines in this tracker's line structure
+     */
+    int getNumberOfLines();
+
+    /**
+     * Returns the number of lines which are occupied by a given text range.
+     *
+     * @param offset the offset of the specified text range
+     * @param length the length of the specified text range
+     * @return the number of lines occupied by the specified range
+     * @exception BadLocationException if specified range is unknown to this tracker
+     */
+    int getNumberOfLines(int offset, int length) ;
+
+    /**
+     * Returns the position of the first character of the specified line.
+     *
+     * @param line the line of interest
+     * @return offset of the first character of the line
+     * @exception BadLocationException if the line is unknown to this tracker
+     */
+    int getLineOffset(int line) ;
+
+    /**
+     * Returns length of the specified line including the line's delimiter.
+     *
+     * @param line the line of interest
+     * @return the length of the line
+     * @exception BadLocationException if line is unknown to this tracker
+     */
+    int getLineLength(int line) ;
+
+    /**
+     * Returns the line number the character at the given offset belongs to.
+     *
+     * @param offset the offset whose line number to be determined
+     * @return the number of the line the offset is on
+     * @exception BadLocationException if the offset is invalid in this tracker
+     */
+    int getLineNumberOfOffset(int offset) ;
+
+    /**
+     * Returns a line description of the line at the given offset.
+     * The description contains the start offset and the length of the line
+     * excluding the line's delimiter.
+     *
+     * @param offset the offset whose line should be described
+     * @return a region describing the line
+     * @exception BadLocationException if offset is invalid in this tracker
+     */
+    IRegion getLineInformationOfOffset(int offset) ;
+
+    /**
+     * Returns a line description of the given line. The description
+     * contains the start offset and the length of the line excluding the line's
+     * delimiter.
+     *
+     * @param line the line that should be described
+     * @return a region describing the line
+     * @exception BadLocationException if line is unknown to this tracker
+     */
+    IRegion getLineInformation(int line) ;
+
+    /**
+     * Informs the line tracker about the specified change in the tracked text.
+     *
+     * @param offset the offset of the replaced text
+     * @param length the length of the replaced text
+     * @param text the substitution text
+     * @exception BadLocationException if specified range is unknown to this tracker
+     */
+    void replace(int offset, int length, String text) ;
+
+    /**
+     * Sets the tracked text to the specified text.
+     *
+     * @param text the new tracked text
+     */
+    void set(String text);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ILineTrackerExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ILineTrackerExtension;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.ILineTracker}. Adds the
+ * concept of rewrite sessions. A rewrite session is a sequence of replace
+ * operations that form a semantic unit.
+ *
+ * @since 3.1
+ */
+public interface ILineTrackerExtension {
+
+    /**
+     * Tells the line tracker that a rewrite session started. A rewrite session
+     * is a sequence of replace operations that form a semantic unit. The line
+     * tracker is allowed to use that information for internal optimization.
+     *
+     * @param session the rewrite session
+     * @throws IllegalStateException in case there is already an active rewrite
+     *             session
+     */
+    void startRewriteSession(DocumentRewriteSession session) ;
+
+    /**
+     * Tells the line tracker that the rewrite session has finished. This method
+     * is only called when <code>startRewriteSession</code> has been called
+     * before. The text resulting from the rewrite session is passed to the line
+     * tracker.
+     *
+     * @param session the rewrite session
+     * @param text the text with which to re-initialize the line tracker
+     */
+    void stopRewriteSession(DocumentRewriteSession session, String text);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IMarkRegionTarget.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,178 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IMarkRegionTarget;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * A mark region target to support marked regions as found in emacs.
+ *
+ * @since 2.0
+ */
+public interface IMarkRegionTarget {
+
+    /**
+     * Sets or clears a mark at the current cursor position.
+     *
+     * @param set sets the mark if <code>true</code>, clears otherwise.
+     */
+    void setMarkAtCursor(bool set);
+
+    /**
+     * Swaps the mark and cursor position if the mark is in the visible region.
+     */
+    void swapMarkAndCursor();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IMarkSelection.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IMarkSelection;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.jface.viewers.ISelection;
+
+
+/**
+ * A mark selection can be sent out by text viewers. By checking the
+ * type of the selection selection listeners can determine whether a selection
+ * event is about a mark or a normal text selection.
+ * <p>
+ * This interface is not intended to be implemented by clients other than
+ * {@link dwtx.jface.text.ITextViewer} implementers.
+ * </p>
+ *
+ * @since 2.0
+ */
+public interface IMarkSelection : ISelection {
+
+    /**
+     * Returns the marked document.
+     *
+     * @return the marked document
+     */
+    IDocument getDocument();
+
+    /**
+     * Returns the mark position. The offset may be <code>-1</code> if there's no marked region.
+     *
+     * @return the mark position or <code>-1</code> if there is no marked region
+     */
+    int getOffset();
+
+    /**
+     * Returns the length of the mark selection. The length may be negative, if the caret
+     * is before the mark position. The length has no meaning if <code>getOffset()</code>
+     * returns <code>-1</code>.
+     *
+     * @return the length of the mark selection. Result is undefined for <code>getOffset is -1</code>
+     */
+    int getLength();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IPaintPositionManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IPaintPositionManager;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+/**
+ * Manages and updates positions used by {@link IPainter}s.
+ *
+ * @see dwtx.jface.text.IPainter
+ * @since 2.1
+ */
+public interface IPaintPositionManager {
+
+    /**
+     * Starts managing the given position until <code>unmanagePosition</code> is called.
+     *
+     * @param position the position to manage
+     * @see #unmanagePosition(Position)
+     */
+    void managePosition(Position position);
+
+    /**
+     * Stops managing the given position. If the position is not managed
+     * by this managed, this call has no effect.
+     *
+     * @param position the position that should no longer be managed
+     */
+    void unmanagePosition(Position position);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IPainter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,257 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IPainter;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A painter is responsible for creating, managing, updating, and removing
+ * visual decorations on an <code>ITextViewer</code>'s text widget. Examples
+ * are the highlighting of the caret line, the print margin, or the highlighting
+ * of matching peer characters such as pairs of brackets.</p>
+ * <p>
+ * Clients may implement this interface.</p>
+ * <p>
+ * Painters should be registered with a
+ * {@link dwtx.jface.text.PaintManager}. The paint manager tracks
+ * several classes of events issued by an <code>ITextViewer</code> and reacts
+ * by appropriately invoking the registered painters.
+ * <p>
+ * Painters are either active or inactive. Usually, painters are initially
+ * inactive and are activated by the first call to their <code>paint</code>
+ * method. Painters can be deactivated by calling <code>deactivate</code>.
+ * Inactive painter can be reactivated by calling <code>paint</code>.
+ * <p>
+ * Painters usually have to manage state information. E.g., a painter painting a
+ * caret line highlight must redraw the previous and the actual caret line in
+ * the advent of a change of the caret position. This state information must be
+ * adapted to changes of the viewer's content. In order to support this common
+ * scenario, the <code>PaintManager</code> gives a painter access to a
+ * {@link dwtx.jface.text.IPaintPositionManager}. The painter can use
+ * this updater to manage its state information.
+ * <p>
+ *
+ * @see dwtx.jface.text.PaintManager
+ * @see dwtx.jface.text.IPaintPositionManager
+ * @since 2.1
+ */
+public interface IPainter {
+
+    /**
+     * Constant describing the reason of a repaint request: selection changed.
+     */
+    static const int SELECTION= 0;
+    /**
+     * Constant describing the reason of a repaint request: text changed.
+     */
+    static const int TEXT_CHANGE= 1;
+    /**
+     * Constant describing the reason of a repaint request: key pressed.
+     */
+    static const int KEY_STROKE= 2;
+    /**
+     * Constant describing the reason of a repaint request: mouse button pressed.
+     */
+    static const int MOUSE_BUTTON= 4;
+    /**
+     * Constant describing the reason of a repaint request: paint manager internal change.
+     */
+    static const int INTERNAL= 8;
+    /**
+     * Constant describing the reason of a repaint request: paint manager or painter configuration changed.
+     */
+    static const int CONFIGURATION= 16;
+
+
+    /**
+     * Disposes this painter. Prior to disposing, a painter should be deactivated. A disposed
+     * painter can not be reactivated.
+     *
+     * @see #deactivate(bool)
+     */
+    void dispose();
+
+    /**
+     * Requests this painter to repaint because of the given reason. Based on
+     * the given reason the painter can decide whether it will repaint or not.
+     * If it repaints and is inactive, it will activate itself.
+     *
+     * @param reason the repaint reason, value is one of the constants defined
+     *            in this interface
+     */
+    void paint(int reason);
+
+    /**
+     * Deactivates this painter. If the painter is inactive, this call does not
+     * have any effect. <code>redraw</code> indicates whether the painter
+     * should remove any decoration it previously applied. A deactivated painter
+     * can be reactivated by calling <code>paint</code>.
+     *
+     * @param redraw <code>true</code> if any previously applied decoration
+     *            should be removed
+     * @see #paint(int)
+     */
+    void deactivate(bool redraw);
+
+    /**
+     * Sets the paint position manager that can be used by this painter or removes any previously
+     * set paint position manager.
+     *
+     * @param manager the paint position manager or <code>null</code>
+     */
+    void setPositionManager(IPaintPositionManager manager);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IPositionUpdater.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IPositionUpdater;
+
+import dwtx.jface.text.DocumentEvent; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A position updater is responsible for adapting document positions. When
+ * installed on a document, the position updater updates the document's
+ * positions to changes applied to this document. Document updaters can be
+ * selective, i.e. they might only update positions of a certain category.
+ * <p>
+ * Position updaters are of primary importance for the definition of the
+ * semantics of positions.
+ * <p>
+ * Clients may implement this interface or use the standard implementation
+ * {@link dwtx.jface.text.DefaultPositionUpdater}.
+ * </p>
+ *
+ * @see dwtx.jface.text.IDocument
+ * @see dwtx.jface.text.Position
+ */
+public interface IPositionUpdater {
+
+    /**
+     * Adapts positions to the change specified by the document event.
+     * It is ensured that the document's partitioning has been adapted to
+     * this document change and that all the position updaters which have
+     * a smaller index in the document's position updater list have been called.
+     *
+     * @param event the document event describing the document change
+     */
+    void update(DocumentEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IRegion.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IRegion;
+
+/**
+ * A region describes a certain range in an indexed text store. Text stores are
+ * for example documents or strings. A region is defined by its offset into the
+ * text store and its length.
+ * <p>
+ * A region is considered a value object. Its offset and length do not change
+ * over time.
+ * <p>
+ * Clients may implement this interface or use the standard implementation
+ * {@link dwtx.jface.text.Region}.
+ * </p>
+ */
+public interface IRegion {
+
+    /**
+     * Returns the length of the region.
+     *
+     * @return the length of the region
+     */
+    int getLength();
+
+    /**
+     * Returns the offset of the region.
+     *
+     * @return the offset of the region
+     */
+    int getOffset();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IRepairableDocument.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IRepairableDocument;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Tagging interface to be implemented by
+ * {@link dwtx.jface.text.IDocument} implementers that offer a line
+ * repair method on the documents.
+ * <p>
+ * In order to provide backward compatibility for clients of
+ * <code>IRepairableDocument</code>, extension interfaces are used to provide
+ * a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li> {@link dwtx.jface.text.IRepairableDocumentExtension} since version 3.4
+ *      adds the ability to query whether the repairable document needs to be repaired.</li>
+ * </ul>
+ * 
+ * 
+ * @see dwtx.jface.text.IDocument
+ * @see dwtx.jface.text.IRepairableDocumentExtension
+ * @since 3.0
+ */
+public interface IRepairableDocument {
+
+    /**
+     * Repairs the line information of the document implementing this interface.
+     */
+    void repairLineInformation();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IRepairableDocumentExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IRepairableDocumentExtension;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IRepairableDocument}.
+ * <p>
+ * Adds the ability to query whether the repairable document needs to be
+ * repaired.
+ * 
+ * @see dwtx.jface.text.IRepairableDocument
+ * @since 3.4
+ */
+public interface IRepairableDocumentExtension {
+
+    /**
+     * Tells whether the line information of the document implementing this
+     * interface needs to be repaired.
+     * 
+     * @param offset the document offset
+     * @param length the length of the specified range
+     * @param text the substitution text to check
+     * @return <code>true</code> if the line information must be repaired
+     * @throws BadLocationException if the offset is invalid in this document
+     * @see IRepairableDocument#repairLineInformation()
+     */
+    bool isLineInformationRepairNeeded(int offset, int length, String text) ;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IRewriteTarget.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IRewriteTarget;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+ /**
+  * A target publishing the required functions to modify a document that is displayed
+  * in a text viewer. It provides access to the document and control
+  * over the redraw behavior and the grouping of document changes into undo commands.
+  *
+  * @see dwtx.jface.text.ITextViewer
+  * @see dwtx.jface.text.IDocument
+  * @see dwtx.jface.text.IUndoManager
+  * @since 2.0
+  */
+public interface IRewriteTarget {
+
+    /**
+     * Returns the document of this target.
+     *
+     * @return the document of this target
+     */
+    IDocument getDocument();
+
+    /**
+     * Disables/enables redrawing while modifying the target's document.
+     *
+     * @param redraw <code>true</code> if the document's visible presentation
+     *            should be updated, <code>false</code> otherwise
+     */
+    void setRedraw(bool redraw);
+
+    /**
+     * If an undo manager is connected to the document's visible presentation,
+     * this method tells the undo manager to fold all subsequent changes into
+     * one single undo command until <code>endCompoundChange</code> is called.
+     */
+    void beginCompoundChange();
+
+    /**
+     * If an undo manager is connected to the document's visible presentation,
+     * this method tells the undo manager to stop the folding of changes into a
+     * single undo command. After this call, all subsequent changes are
+     * considered to be individually undo-able.
+     */
+    void endCompoundChange();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ISelectionValidator.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ISelectionValidator;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.jface.viewers.ISelection;
+
+
+/**
+ * A selection validator allows clients to test whether the selection they
+ * received during selection changed notification is valid.
+ * <p>
+ * For example, selection and document changes that occur between the original
+ * selection and the point in time the validator is called cause the selection
+ * to be invalid.</p>
+ * <p>
+ * Clients may implement and use this interface.
+ * </p>
+ *
+ * @since 3.0
+ */
+public interface ISelectionValidator {
+
+    /**
+     * Tests whether the given post selection is still valid.
+     *
+     * @param selection
+     * @return <code>true</code> if the selection is still valid
+     */
+    bool isValid(ISelection selection);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ISlaveDocumentManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,249 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.ISlaveDocumentManager;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Slave documents are documents whose contents is defined in terms of a master
+ * document. Thus, slave documents usually reflect a projection of the master document.
+ * Slave documents are causally connected to the master document. This means, changes
+ * of the master document have immediate effect on the slave document and vice versa.
+ * <p>
+ * A slave document manager creates slave documents for given master documents, manages the
+ * life cycle of the slave documents, and keeps track of the information flow between
+ * master and slave documents. The slave document manager defines the construction rules of the
+ * slave documents in terms of the master document.</p>
+ * <p>
+* In order to provided backward compatibility for clients of <code>ISlaveDocumentManager</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces
+ * exist:
+ * <ul>
+ * <li> {@link dwtx.jface.text.ISlaveDocumentManagerExtension} since version 3.0 extending the protocol
+ *      with an access to all managed slave document for a given master document. </li>
+ * </ul>
+ * </p>
+ *
+ * @see dwtx.jface.text.IDocument
+ * @since 2.1
+ */
+public interface ISlaveDocumentManager {
+
+    /**
+     * Creates a new slave document for the given master document. The slave document
+     * is causally connected to its master document until <code>freeSlaveDocument</code>
+     * is called. The connection between the newly created slave document and the master
+     * document is managed by this slave document manager.
+     *
+     * @param master the master document
+     * @return the newly created slave document
+     * @see #freeSlaveDocument(IDocument)
+     */
+    IDocument createSlaveDocument(IDocument master);
+
+    /**
+     * Frees the given slave document. If the given document is not a slave document known
+     * to this slave document manager, this call does not have any effect. A slave
+     * document is known to this slave document manager if it has been created by
+     * this manager using <code>createSlaveDocument</code>.
+     *
+     * @param slave the slave document to be freed
+     * @see #createSlaveDocument(IDocument)
+     */
+    void freeSlaveDocument(IDocument slave);
+
+    /**
+     * Creates a new document information mapping between the given slave document and
+     * its master document. Returns <code>null</code> if the given document is unknown
+     * to this slave document manager.
+     *
+     * @param slave the slave document
+     * @return a document information mapping between the slave document and its master document or
+     *      <code>null</code>
+     */
+    IDocumentInformationMapping createMasterSlaveMapping(IDocument slave);
+
+    /**
+     * Returns the master document of the given slave document or <code>null</code> if the
+     * given document is unknown to this slave document manager.
+     *
+     * @param slave the slave document
+     * @return the master document of the given slave document or <code>null</code>
+     */
+    IDocument getMasterDocument(IDocument slave);
+
+    /**
+     * Returns whether the given document is a slave document known to this slave document manager. A slave document
+     * is known to this slave document manager, if the document has been created by this manager.
+     *
+     * @param document the document to be checked whether it is a slave document known to this manager
+     * @return <code>true</code> if the document is a slave document, <code>false</code> otherwise
+     */
+    bool isSlaveDocument(IDocument document);
+
+    /**
+     * Sets the given slave document's auto expand mode. In auto expand mode, a
+     * slave document is automatically adapted to reflect all changes applied to it's master document.
+     * Assume a master document contains 30 lines and the slave is defined to contain the lines 11-20.
+     * In auto expand mode, when the master document is changed at line 8, the slave document is expanded
+     * to contain the lines 8-20.<p>
+     * This call is without effect if the given document is unknown to this slave document manager.
+     *
+     * @param slave the slave whose auto expand mode should be set
+     * @param autoExpand <code>true</code> for auto expand, <code>false</code> otherwise
+     */
+    void setAutoExpandMode(IDocument slave, bool autoExpand);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ISlaveDocumentManagerExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ISlaveDocumentManagerExtension;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.ISlaveDocumentManager}.
+ * <p>
+ * Adds access to the list of all slave documents for a given master document.
+ *
+ * @see dwtx.jface.text.ISlaveDocumentManager
+ * @since 3.0
+ */
+public interface ISlaveDocumentManagerExtension {
+
+    /**
+     * Returns the list of slave documents for the given master document or
+     * <code>null</code> if there are no such slave document.
+     *
+     * @param master the master document
+     * @return the list of slave documents or <code>null</code>
+     */
+    IDocument[] getSlaveDocuments(IDocument master);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ISynchronizable.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ISynchronizable;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Interface for text related objects which may be used in the multi-threaded
+ * context and thus must provide a way to prevent concurrent access and
+ * manipulation.
+ * <p>
+ * In order to reduce the probability of dead locks clients should synchronize
+ * their access to these objects by using the provided lock object rather than
+ * the object itself.</p>
+ * <p>
+ * Managing objects can use the <code>setLockObject</code> method in order to
+ * synchronize whole sets of objects.</p>
+ *
+ * @since 3.0
+ */
+public interface ISynchronizable {
+
+    /**
+     * Sets the lock object for this object. If the lock object is not
+     * <code>null</code> subsequent calls to specified methods of this object
+     * are synchronized on this lock object. Which methods are synchronized is
+     * specified by the implementer.
+     * <p>
+     * <em>You should not override an existing lock object unless you own
+     * that lock object yourself. Use the existing lock object instead.</em>
+     * </p>
+     *
+     * @param lockObject the lock object. May be <code>null</code>.
+     */
+    void setLockObject(Object lockObject);
+
+    /**
+     * Returns the lock object or <code>null</code> if there is none. Clients
+     * should use the lock object in order to synchronize concurrent access to
+     * the implementer.
+     *
+     * @return the lock object or <code>null</code>
+     */
+    Object getLockObject();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextDoubleClickStrategy.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextDoubleClickStrategy;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A text double click strategy defines the reaction of a text viewer to mouse
+ * double click events. The strategy must be installed on an
+ * {@link dwtx.jface.text.ITextViewer}.
+ * <p>
+ * Clients may implement this interface or use the standard implementation
+ * <code>DefaultTextDoubleClickStrategy</code>.</p>
+ *
+ * @see dwtx.jface.text.ITextViewer
+ * @see dwt.events.MouseListener#mouseDoubleClick(dwt.events.MouseEvent)
+ */
+public interface ITextDoubleClickStrategy {
+
+    /**
+     * The mouse has been double clicked on the given text viewer.
+     *
+     * @param viewer the viewer into which has been double clicked
+     */
+    void doubleClicked(ITextViewer viewer);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextHover.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextHover;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Computes the information to be shown in a hover popup which appears on top of
+ * the text viewer's text widget when a hover event occurs. If the text hover
+ * does not provide information no hover popup is shown. Any implementer of this
+ * interface must be capable of operating in a non-UI thread.
+ * <p>
+ *
+ * In order to provide backward compatibility for clients of
+ * <code>ITextHover</code>, extension interfaces are used as a means of
+ * evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.ITextHoverExtension} since version 3.0
+ *     allowing a text hover to provide a creator for the hover control. This allows
+ *     for sophisticated hovers in a way that information computed by the hover can
+ *     be displayed in the best possible form.</li>
+ * <li>{@link dwtx.jface.text.ITextHoverExtension2} since version 3.4
+ *     allowing a text hover to return hover-specific information objects.</li>
+ * </ul></p>
+ * <p>
+ * Clients may implement this interface.</p>
+ *
+ * @see dwtx.jface.text.ITextHoverExtension
+ * @see dwtx.jface.text.ITextHoverExtension2
+ * @see dwtx.jface.text.ITextViewer
+ */
+public interface ITextHover {
+
+    /**
+     * Returns the information which should be presented when a hover popup is shown
+     * for the specified hover region. The hover region has the same semantics
+     * as the region returned by <code>getHoverRegion</code>. If the returned
+     * information is <code>null</code> or empty no hover popup will be shown.
+     *
+     * @param textViewer the viewer on which the hover popup should be shown
+     * @param hoverRegion the text range in the viewer which is used to determine
+     *      the hover display information
+     * @return the hover popup display information, or <code>null</code> if none available
+     * @deprecated As of 3.4, replaced by {@link ITextHoverExtension2#getHoverInfo2(ITextViewer, IRegion)}
+     */
+    String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion);
+
+    /**
+     * Returns the text region which should serve as the source of information
+     * to compute the hover popup display information. The popup has been requested
+     * for the given offset.<p>
+     * For example, if hover information can be provided on a per method basis in a
+     * source viewer, the offset should be used to find the enclosing method and the
+     * source range of the method should be returned.
+     *
+     * @param textViewer the viewer on which the hover popup should be shown
+     * @param offset the offset for which the hover request has been issued
+     * @return the hover region used to compute the hover display information
+     */
+    IRegion getHoverRegion(ITextViewer textViewer, int offset);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextHoverExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,177 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextHoverExtension;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.ITextHover}.
+ * <p>
+ * It provides a way for hovers to specify the information control creator they
+ * want to have used in order to create the hover control.</p>
+ *
+ * @see dwtx.jface.text.IInformationControlCreator
+ * @see dwtx.jface.text.ITextHover
+ * @since 3.0
+ */
+public interface ITextHoverExtension {
+
+    /**
+     * Returns the hover control creator of this text hover or <code>null</code>
+     *
+     * @return the hover control creator or <code>null</code>
+     */
+    IInformationControlCreator getHoverControlCreator();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextHoverExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,192 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextHoverExtension2;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.ITextHover}.
+ * <p>
+ * Provides a way for hovers to return hover-specific information objects.
+ * </p>
+ * 
+ * @see dwtx.jface.text.ITextHover
+ * @since 3.4
+ */
+public interface ITextHoverExtension2 {
+
+    /**
+     * Returns the information which should be presented when a hover popup is shown
+     * for the specified hover region. The hover region has the same semantics
+     * as the region returned by {@link ITextHover#getHoverRegion(ITextViewer, int)}.
+     * If the returned information is <code>null</code>, no hover popup will be shown.
+     * <p>
+     * <strong>Note:</strong> Implementers have to ensure that {@link ITextHoverExtension#getHoverControlCreator()}
+     * returns {@link IInformationControl}s that implement
+     * {@link IInformationControlExtension2} and whose
+     * {@link IInformationControlExtension2#setInput(Object)} can handle the
+     * information objects returned by this method.</p>
+     * <p>
+     * Callers should ignore the text returned by {@link ITextHover#getHoverInfo(ITextViewer, IRegion)}.</p>
+     *
+     * @param textViewer the viewer on which the hover popup should be shown
+     * @param hoverRegion the text range in the viewer which is used to determine
+     *      the hover display information
+     * @return the hover popup display information, or <code>null</code> if none available
+     */
+    Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion);
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextInputListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextInputListener;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+/**
+ * Text input listeners registered with an
+ * {@link dwtx.jface.text.ITextViewer} are informed if the document
+ * serving as the text viewer's model is replaced.
+ * <p>
+ * Clients may implement this interface.</p>
+ *
+ * @see dwtx.jface.text.ITextViewer
+ * @see dwtx.jface.text.IDocument
+ */
+public interface ITextInputListener {
+
+    /**
+     * Called before the input document is replaced.
+     *
+     * @param oldInput the text viewer's previous input document
+     * @param newInput the text viewer's new input document
+     */
+    void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput);
+
+    /**
+     * Called after the input document has been replaced.
+     *
+     * @param oldInput the text viewer's previous input document
+     * @param newInput the text viewer's new input document
+     */
+    void inputDocumentChanged(IDocument oldInput, IDocument newInput);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextListener;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+/**
+ * Text listeners registered with a text viewer are informed about all
+ * modifications of an {@link dwtx.jface.text.ITextViewer} by means of
+ * text events. A text event describes a change as a replace operation.
+ * <p>
+ * The changes described in the event are the changes applied to the text
+ * viewer's widget (i.e., its visual representation) and not those applied to the
+ * text viewer's document. The text event can be asked to return the
+ * corresponding document event. If the text event does not contain a document
+ * event, the modification of the text viewer is a presentation change. For
+ * example, changing the visible region of a text viewer, is a presentation
+ * change. A completely empty text event represents a change of the viewer's
+ * redraw state.</p>
+ * <p>
+ * If a text listener receives a text event, it is guaranteed that both the
+ * document and the viewer's visual representation are synchronized.</p>
+ * <p>
+ * Clients may implement this interface.</p>
+ *
+ * @see dwtx.jface.text.ITextViewer
+ * @see dwtx.jface.text.TextEvent
+ * @see dwtx.jface.text.DocumentEvent
+ */
+public interface ITextListener {
+
+    /**
+     * The visual representation of a text viewer this listener is registered with
+     * has been changed.
+     *
+     * @param event the description of the change
+     */
+    void textChanged(TextEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextOperationTarget.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextOperationTarget;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Defines the target for text operations. <code>canDoOperation</code> informs
+ * the clients about the ability of the target to perform the specified
+ * operation at the current point in time. <code>doOperation</code> executes
+ * the specified operation.
+ * <p>
+ * In order to provide backward compatibility for clients of
+ * <code>ITextOperationTarget</code>, extension interfaces are used as a
+ * means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.ITextOperationTargetExtension} since
+ *     version 2.0 introducing text operation enabling/disabling.</li>
+ * </ul>
+ *
+ * @see dwtx.jface.text.ITextOperationTargetExtension
+ */
+public interface ITextOperationTarget {
+
+
+    /**
+     * Text operation code for undoing the last edit command.
+     */
+    public static const int UNDO= 1;
+
+    /**
+     * Text operation code for redoing the last undone edit command.
+     */
+    public static const int REDO= 2;
+
+    /**
+     * Text operation code for moving the selected text to the clipboard.
+     */
+    public static const int CUT= 3;
+
+    /**
+     * Text operation code for copying the selected text to the clipboard.
+     */
+    public static const int COPY= 4;
+
+    /**
+     * Text operation code for inserting the clipboard content at the
+     * current position.
+     */
+    public static const int PASTE= 5;
+
+    /**
+     * Text operation code for deleting the selected text or if selection
+     * is empty the character  at the right of the current position.
+     */
+    public static const int DELETE= 6;
+
+    /**
+     * Text operation code for selecting the complete text.
+     */
+    public static const int SELECT_ALL= 7;
+
+    /**
+     * Text operation code for shifting the selected text block to the right.
+     */
+    public static const int SHIFT_RIGHT= 8;
+
+    /**
+     * Text operation code for shifting the selected text block to the left.
+     */
+    public static const int SHIFT_LEFT= 9;
+
+    /**
+     * Text operation code for printing the complete text.
+     */
+    public static const int PRINT= 10;
+
+    /**
+     * Text operation code for prefixing the selected text block.
+     */
+    public static const int PREFIX= 11;
+
+    /**
+     * Text operation code for removing the prefix from the selected text block.
+     */
+    public static const int STRIP_PREFIX= 12;
+
+
+    /**
+     * Returns whether the operation specified by the given operation code
+     * can be performed.
+     *
+     * @param operation the operation code
+     * @return <code>true</code> if the specified operation can be performed
+     */
+    bool canDoOperation(int operation);
+
+    /**
+     * Performs the operation specified by the operation code on the target.
+     * <code>doOperation</code> must only be called if <code>canDoOperation</code>
+     * returns <code>true</code>.
+     *
+     * @param operation the operation code
+     */
+    void doOperation(int operation);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextOperationTargetExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,180 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.ITextOperationTargetExtension;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.ITextOperationTarget}.
+ * <p>
+ * Allows a client to control the enable state of operations provided by this
+ * target.
+ *
+ * @see dwtx.jface.text.ITextOperationTarget
+ * @since 2.0
+ */
+public interface ITextOperationTargetExtension {
+
+    /**
+     * Enables/disabled the given text operation.
+     *
+     * @param operation the operation to enable/disable
+     * @param enable <code>true</code> to enable the operation otherwise <code>false</code>
+     */
+    void enableOperation(int operation, bool enable);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextPresentationListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextPresentationListener;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Text presentation listeners registered with an
+ * {@link dwtx.jface.text.ITextViewer} are informed when a
+ * {@link dwtx.jface.text.TextPresentation} is about to be applied to the
+ * text viewer. The listener can apply changes to the text presentation and thus
+ * participate in the process of text presentation creation.
+ *
+ * @since 3.0
+ */
+public interface ITextPresentationListener {
+
+    /**
+     * This method is called when a text presentation is about to be applied to
+     * the text viewer. The receiver is allowed to change the text presentation
+     * during that call.
+     *
+     * @param textPresentation the current text presentation
+     */
+    public void applyTextPresentation(TextPresentation textPresentation);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextSelection.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextSelection;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwtx.jface.viewers.ISelection;
+
+
+/**
+ * This interface represents a textual selection. A text selection is a range of
+ * characters. Although a text selection is a snapshot taken at a particular
+ * point in time, it must not copy the line information and the selected text
+ * from the selection provider.
+ * <p>
+ * If, for example, the selection provider is a text viewer (
+ * {@link dwtx.jface.text.ITextViewer}), and a text selection is created
+ * for the range [5, 10], the line formation for the 5th character must not be
+ * determined and remembered at the point of creation. It can rather be
+ * determined at the point, when <code>getStartLine</code> is called. If the
+ * source viewer range [0, 15] has been changed in the meantime between the
+ * creation of the text selection object and the invocation of
+ * <code>getStartLine</code>, the returned line number may differ from the
+ * line number of the 5th character at the point of creation of the text
+ * selection object.
+ * <p>
+ * The contract of this interface is that weak in order to allow for efficient
+ * implementations.</p>
+ * <p>
+ * Clients may implement this interface or use the default implementation
+ * provided by {@link dwtx.jface.text.TextSelection}.</p>
+ *
+ * @see dwtx.jface.text.TextSelection
+ */
+public interface ITextSelection : ISelection {
+
+    /**
+     * Returns the offset of the selected text.
+     *
+     * @return the offset of the selected text
+     */
+    int getOffset();
+
+    /**
+     * Returns the length of the selected text.
+     *
+     * @return the length of the selected text
+     */
+    int getLength();
+
+    /**
+     * Returns number of the line containing the offset of the selected text.
+     * If the underlying text has been changed between the creation of this
+     * selection object and the call of this method, the value returned might
+     * differ from what it would have been at the point of creation.
+     *
+     * @return the start line of this selection or <code>-1</code> if there is no valid line information
+     */
+    int getStartLine();
+
+    /**
+     * Returns the number of the line containing the last character of the selected text.
+     * If the underlying text has been changed between the creation of this
+     * selection object and the call of this method, the value returned might
+     * differ from what it would have been at the point of creation.
+     *
+     * @return the end line of this selection or <code>-1</code> if there is no valid line information
+     */
+    int getEndLine();
+
+    /**
+     * Returns the selected text.
+     * If the underlying text has been changed between the creation of this
+     * selection object and the call of this method, the value returned might
+     * differ from what it would have been at the point of creation.
+     *
+     * @return the selected text or <code>null</code> if there is no valid text information
+     */
+    String getText();
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextStore.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextStore;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Interface for storing and managing text.
+ * <p>
+ * Provides access to the stored text and allows to manipulate it.</p>
+ * <p>
+ * Clients may
+ * implement this interface or use {@link dwtx.jface.text.GapTextStore} or
+ * {@link dwtx.jface.text.CopyOnWriteTextStore}.</p>
+ */
+public interface ITextStore {
+
+    /**
+     * Returns the character at the specified offset.
+     *
+     * @param offset the offset in this text store
+     * @return the character at this offset
+     */
+    char get(int offset);
+
+    /**
+     * Returns the text of the specified character range.
+     *
+     * @param offset the offset of the range
+     * @param length the length of the range
+     * @return the text of the range
+     */
+    String get(int offset, int length);
+
+    /**
+     * Returns number of characters stored in this text store.
+     *
+     * @return the number of characters stored in this text store
+     */
+    int getLength();
+
+    /**
+     * Replaces the specified character range with the given text.
+     * <code>replace(getLength(), 0, "some text")</code> is a valid
+     * call and appends text to the end of the text store.
+     *
+     * @param offset the offset of the range to be replaced
+     * @param length the number of characters to be replaced
+     * @param text the substitution text
+     */
+    void replace(int offset, int length, String text);
+
+    /**
+     * Replace the content of the text store with the given text.
+     * Convenience method for <code>replace(0, getLength(), text</code>.
+     *
+     * @param text the new content of the text store
+     */
+    void set(String text);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextViewer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,692 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextViewer;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.custom.StyledText;
+import dwt.graphics.Color;
+import dwt.graphics.Point;
+import dwtx.jface.viewers.ISelectionProvider;
+
+
+/**
+ * A text viewer connects a text widget with an
+ * {@link dwtx.jface.text.IDocument}. The document is used as the
+ * widget's text model.
+ * <p>
+ * It supports the following kinds of listeners:
+ * <ul>
+ * <li>view port listeners to inform about changes of the viewer's view port</li>
+ * <li>text listeners to inform about changes of the document and the
+ * subsequent viewer change</li>
+ * <li>text input listeners to inform about changes of the viewer's input
+ * document.</li>
+ * </ul>
+ * A text viewer supports a set of configuration options and plug-ins defining
+ * its behavior:
+ * <ul>
+ * <li>undo manager</li>
+ * <li>double click behavior</li>
+ * <li>auto indentation</li>
+ * <li>text hover</li>
+ * </ul>
+ * Installed plug-ins are not automatically activated. Plug-ins must be
+ * activated with the <code>activatePlugins</code> call. Most plug-ins can be
+ * defined per content type. Content types are derived from a partitioning of
+ * the text viewer's input document. In case of documents that support multiple
+ * partitionings, the implementer is responsible for determining the
+ * partitioning to use.
+ * <p>
+ * A text viewer also provides the concept of event consumption. Events handled
+ * by the viewer can be filtered and processed by a dynamic event consumer. With
+ * {@link dwtx.jface.text.ITextViewerExtension}, this mechanism has been
+ * replaced with the support for
+ * {@link dwt.custom.VerifyKeyListener}.
+ * <p>
+ * A text viewer provides several text editing functions, some of them are
+ * configurable, through a text operation target interface. It also supports a
+ * presentation mode in which it only shows a specified section of its document.
+ * By calling <code>setVisibleRegion</code> clients define which section is
+ * visible. Clients can get access to this section by calling
+ * <code>getVisibleRegion</code>. The viewer's presentation mode does not
+ * affect any client of the viewer other than text listeners. With
+ * {@link dwtx.jface.text.ITextViewerExtension5} the visible region
+ * support has been reworked. With that extension interface, text viewers are
+ * allowed to show fractions of their input document. I.e. a widget selection of
+ * two visually neighboring characters is no longer guaranteed to be two
+ * neighboring characters in the viewer's input document. Thus, viewers
+ * implementing {@link dwtx.jface.text.ITextViewerExtension5} are
+ * potentially forced to change the fractions of the input document that are
+ * shown when clients ask for the visible region.
+ * <p>
+ *
+ * In order to provide backward compatibility for clients of
+ * <code>ITextViewer</code>, extension interfaces are used as a means of
+ * evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.ITextViewerExtension} since version 2.0
+ * replacing the event consumer mechanism and introducing the concept of rewrite
+ * targets and means to manage the viewer's redraw behavior</li>
+ * <li>{@link dwtx.jface.text.ITextViewerExtension2}since version 2.1
+ * adding a way to invalidate a viewer's presentation and setters for hovers.
+ * </li>
+ * <li>{@link dwtx.jface.text.ITextViewerExtension3} since version 2.1
+ * which itself was replaced by
+ * {@link dwtx.jface.text.ITextViewerExtension5} in version 3.0</li>
+ * <li>{@link dwtx.jface.text.ITextViewerExtension4} since version 3.0
+ * introducing focus handling for widget token keepers and the concept of text
+ * presentation listeners.</li>
+ * <li>{@link dwtx.jface.text.ITextViewerExtension5} since version 3.0
+ * extending the visible region concept with explicit handling and conversion
+ * of widget and model coordinates.</li>
+ * <li>{@link dwtx.jface.text.ITextViewerExtension6} since version 3.1
+ * extending the text viewer with the ability to detect hyperlinks and access the undo manager.</li>
+ * <li>{@link dwtx.jface.text.ITextViewerExtension7} since version 3.3
+ * extending the text viewer with the ability to install tabs to spaces conversion.</li>
+ * <li>{@link dwtx.jface.text.ITextViewerExtension8} since version 3.4
+ * extending the text viewer with the ability to print and rich hover support.</li>
+ * </ul></p>
+ * <p>
+ * Clients may implement this interface and its extension interfaces or use the
+ * standard implementation {@link dwtx.jface.text.TextViewer}.</p>
+ *
+ * @see dwtx.jface.text.ITextViewerExtension
+ * @see dwtx.jface.text.ITextViewerExtension2
+ * @see dwtx.jface.text.ITextViewerExtension3
+ * @see dwtx.jface.text.ITextViewerExtension4
+ * @see dwtx.jface.text.ITextViewerExtension5
+ * @see dwtx.jface.text.ITextViewerExtension6
+ * @see dwtx.jface.text.ITextViewerExtension7
+ * @see dwtx.jface.text.ITextViewerExtension8
+ * @see dwtx.jface.text.IDocument
+ * @see dwtx.jface.text.ITextInputListener
+ * @see dwtx.jface.text.IViewportListener
+ * @see dwtx.jface.text.ITextListener
+ * @see dwtx.jface.text.IEventConsumer
+ */
+public interface ITextViewer {
+
+
+    /* ---------- widget --------- */
+
+    /**
+     * Returns this viewer's DWT control, <code>null</code> if the control is disposed.
+     * <p>
+     * <em>Calling API directly on the widget can interfere with features provided
+     * by a text viewer. Clients who call API directly on the widget are responsible
+     * to resolve such conflicts on their side.</em>
+     * </p>
+     *
+     * @return the DWT control or <code>null</code>
+     */
+    StyledText getTextWidget();
+
+
+    /* --------- plug-ins --------- */
+
+    /**
+     * Sets this viewer's undo manager.
+     *
+     * @param undoManager the new undo manager. <code>null</code> is a valid argument.
+     */
+    void setUndoManager(IUndoManager undoManager);
+
+    /**
+     * Sets this viewer's text double click strategy for the given content type.
+     *
+     * @param strategy the new double click strategy. <code>null</code> is a valid argument.
+     * @param contentType the type for which the strategy is registered
+     */
+    void setTextDoubleClickStrategy(ITextDoubleClickStrategy strategy, String contentType);
+
+    /**
+     * Sets this viewer's auto indent strategy for the given content type. If
+     * the given strategy is <code>null</code> any installed strategy for the
+     * content type is removed. This method has been replaced by
+     * {@link ITextViewerExtension2#prependAutoEditStrategy(IAutoEditStrategy, String)} and
+     * {@link ITextViewerExtension2#removeAutoEditStrategy(IAutoEditStrategy, String)}.
+     * It is now equivalent to
+     * <pre>
+     *      ITextViewerExtension2 extension= cast(ITextViewerExtension2) viewer;
+     *      extension.removeAutoEditStrategy(oldStrategy, contentType);
+     *      extension.prependAutoEditStrategy(strategy, contentType);
+     * </pre>
+     *
+     * @param strategy the new auto indent strategy. <code>null</code> is a
+     *            valid argument.
+     * @param contentType the type for which the strategy is registered
+     * @deprecated since 3.1, use
+     *             {@link ITextViewerExtension2#prependAutoEditStrategy(IAutoEditStrategy, String)} and
+     *             {@link ITextViewerExtension2#removeAutoEditStrategy(IAutoEditStrategy, String)} instead
+     */
+    void setAutoIndentStrategy(IAutoIndentStrategy strategy, String contentType);
+
+    /**
+     * Sets this viewer's text hover for the given content type.
+     * <p>
+     * This method has been replaced by {@link ITextViewerExtension2#setTextHover(ITextHover, String, int)}.
+     * It is now equivalent to
+     * <pre>
+     *    ITextViewerExtension2 extension= cast(ITextViewerExtension2) document;
+     *    extension.setTextHover(textViewerHover, contentType, ITextViewerExtension2#DEFAULT_HOVER_STATE_MASK);
+     * </pre>
+     *
+     *
+     * @param textViewerHover the new hover. <code>null</code> is a valid
+     *            argument.
+     * @param contentType the type for which the hover is registered
+     */
+    void setTextHover(ITextHover textViewerHover, String contentType);
+
+    /**
+     * Activates the installed plug-ins. If the plug-ins are already activated
+     * this call has no effect.
+     */
+    void activatePlugins();
+
+    /**
+     * Resets the installed plug-ins. If plug-ins change their state or
+     * behavior over the course of time, this method causes them to be set
+     * back to their initial state and behavior. E.g., if an {@link IUndoManager}
+     * has been installed on this text viewer, the manager's list of remembered
+     * text editing operations is removed.
+     */
+    void resetPlugins();
+
+
+
+    /* ---------- listeners ------------- */
+
+    /**
+     * Adds the given view port listener to this viewer. The listener
+     * is informed about all changes to the visible area of this viewer.
+     * If the listener is already registered with this viewer, this call
+     * has no effect.
+     *
+     * @param listener the listener to be added
+     */
+    void addViewportListener(IViewportListener listener);
+
+    /**
+     * Removes the given listener from this viewer's set of view port listeners.
+     * If the listener is not registered with this viewer, this call has
+     * no effect.
+     *
+     * @param listener the listener to be removed
+     */
+    void removeViewportListener(IViewportListener listener);
+
+    /**
+     * Adds a text listener to this viewer. If the listener is already registered
+     * with this viewer, this call has no effect.
+     *
+     * @param listener the listener to be added
+     */
+    void addTextListener(ITextListener listener);
+
+    /**
+     * Removes the given listener from this viewer's set of text listeners.
+     * If the listener is not registered with this viewer, this call has
+     * no effect.
+     *
+     * @param listener the listener to be removed
+     */
+    void removeTextListener(ITextListener listener);
+
+    /**
+     * Adds a text input listener to this viewer. If the listener is already registered
+     * with this viewer, this call has no effect.
+     *
+     * @param listener the listener to be added
+     */
+    void addTextInputListener(ITextInputListener listener);
+
+    /**
+     * Removes the given listener from this viewer's set of text input listeners.
+     * If the listener is not registered with this viewer, this call has
+     * no effect.
+     *
+     * @param listener the listener to be removed
+     */
+    void removeTextInputListener(ITextInputListener listener);
+
+
+
+    /* -------------- model manipulation ------------- */
+
+    /**
+     * Sets the given document as the text viewer's model and updates the
+     * presentation accordingly. An appropriate <code>TextEvent</code> is
+     * issued. This text event does not carry a related document event.
+     *
+     * @param document the viewer's new input document <code>null</code> if none
+     */
+    void setDocument(IDocument document);
+
+    /**
+     * Returns the text viewer's input document.
+     *
+     * @return the viewer's input document or <code>null</code> if none
+     */
+    IDocument getDocument();
+
+
+    /* -------------- event handling ----------------- */
+
+    /**
+     * Registers an event consumer with this viewer. This method has been
+     * replaces with the {@link dwt.custom.VerifyKeyListener}
+     * management methods in {@link ITextViewerExtension}.
+     *
+     * @param consumer the viewer's event consumer. <code>null</code> is a
+     *            valid argument.
+     */
+    void setEventConsumer(IEventConsumer consumer);
+
+    /**
+     * Sets the editable state.
+     *
+     * @param editable the editable state
+     */
+    void setEditable(bool editable);
+
+    /**
+     * Returns whether the shown text can be manipulated.
+     *
+     * @return the viewer's editable state
+     */
+    bool isEditable();
+
+
+    /* ----------- visible region support ------------- */
+
+    /**
+     * Sets the given document as this viewer's model and
+     * exposes the specified region. An appropriate
+     * <code>TextEvent</code> is issued. The text event does not carry a
+     * related document event. This method is a convenience method for
+     * <code>setDocument(document);setVisibleRegion(offset, length)</code>.
+     *
+     * @param document the new input document or <code>null</code> if none
+     * @param modelRangeOffset the offset of the model range
+     * @param modelRangeLength the length of the model range
+     */
+    void setDocument(IDocument document, int modelRangeOffset, int modelRangeLength);
+
+    /**
+     * Defines and sets the region of this viewer's document which will be
+     * visible in the presentation. Every character inside the specified region
+     * is supposed to be visible in the viewer's widget after that call.
+     *
+     * @param offset the offset of the visible region
+     * @param length the length of the visible region
+     */
+    void setVisibleRegion(int offset, int length);
+
+    /**
+     * Resets the region of this viewer's document which is visible in the presentation.
+     * Afterwards, the whole input document is visible.
+     */
+    void resetVisibleRegion();
+
+    /**
+     * Returns the current visible region of this viewer's document. The result
+     * may differ from the argument passed to <code>setVisibleRegion</code> if
+     * the document has been modified since then. The visible region is supposed
+     * to be a consecutive region in viewer's input document and every character
+     * inside that region is supposed to visible in the viewer's widget.
+     * <p>
+     * Viewers implementing {@link ITextViewerExtension5} may be forced to
+     * change the fractions of the input document that are shown, in order to
+     * fulfill this contract.
+     *
+     * @return this viewer's current visible region
+     */
+    IRegion getVisibleRegion();
+
+    /**
+     * Returns whether a given range overlaps with the visible region of this
+     * viewer's document.
+     * <p>
+     * Viewers implementing {@link ITextViewerExtension5}may be forced to
+     * change the fractions of the input document that are shown in order to
+     * fulfill this request. This is because the overlap is supposed to be
+     * without gaps.
+     *
+     * @param offset the offset
+     * @param length the length
+     * @return <code>true</code> if the specified range overlaps with the
+     *         visible region
+     */
+    bool overlapsWithVisibleRegion(int offset, int length);
+
+
+
+    /* ------------- presentation manipulation ----------- */
+
+    /**
+     * Applies the color information encoded in the given text presentation.
+     * <code>controlRedraw</code> tells this viewer whether it should take care of
+     * redraw management or not. If, e.g., this call is one in a sequence of multiple
+     * presentation calls, it is more appropriate to explicitly control redrawing at the
+     * beginning and the end of the sequence.
+     *
+     * @param presentation the presentation to be applied to this viewer
+     * @param controlRedraw indicates whether this viewer should manage redraws
+     */
+    void changeTextPresentation(TextPresentation presentation, bool controlRedraw);
+
+    /**
+     * Marks the currently applied text presentation as invalid. It is the
+     * viewer's responsibility to take any action it can to repair the text
+     * presentation.
+     * <p>
+     * See {@link ITextViewerExtension2#invalidateTextPresentation(int, int)}
+     * for a way to invalidate specific regions rather than the presentation as
+     * a whole.
+     *
+     * @since 2.0
+     */
+    void invalidateTextPresentation();
+
+    /**
+     * Applies the given color as text foreground color to this viewer's
+     * selection.
+     *
+     * @param color the color to be applied
+     */
+    void setTextColor(Color color);
+
+    /**
+     * Applies the given color as text foreground color to the specified section
+     * of this viewer. <code>controlRedraw</code> tells this viewer whether it
+     * should take care of redraw management or not.
+     *
+     * @param color the color to be applied
+     * @param offset the offset of the range to be changed
+     * @param length the length of the range to be changed
+     * @param controlRedraw indicates whether this viewer should manage redraws
+     */
+    void setTextColor(Color color, int offset, int length, bool controlRedraw);
+
+
+    /* --------- target handling and configuration ------------ */
+
+    /**
+     * Returns the text operation target of this viewer.
+     *
+     * @return the text operation target of this viewer
+     */
+    ITextOperationTarget getTextOperationTarget();
+
+    /**
+     * Returns the find/replace operation target of this viewer.
+     *
+     * @return the find/replace operation target of this viewer
+     */
+    IFindReplaceTarget getFindReplaceTarget();
+
+    /**
+     * Sets the strings that are used as prefixes when lines of the given content type
+     * are prefixed using the prefix text operation. The prefixes are considered equivalent.
+     * Inserting a prefix always inserts the defaultPrefixes[0].
+     * Removing a prefix removes all of the specified prefixes.
+     *
+     * @param defaultPrefixes the prefixes to be used
+     * @param contentType the content type for which the prefixes are specified
+     * @since 2.0
+     */
+    void setDefaultPrefixes(String[] defaultPrefixes, String contentType);
+
+    /**
+     * Sets the strings that are used as prefixes when lines of the given content type
+     * are shifted using the shift text operation. The prefixes are considered equivalent.
+     * Thus "\t" and "    " can both be used as prefix characters.
+     * Shift right always inserts the indentPrefixes[0].
+     * Shift left removes all of the specified prefixes.
+     *
+     * @param indentPrefixes the prefixes to be used
+     * @param contentType the content type for which the prefixes are specified
+     */
+    void setIndentPrefixes(String[] indentPrefixes, String contentType);
+
+
+
+    /* --------- selection handling -------------- */
+
+    /**
+     * Sets the selection to the specified range.
+     * 
+     * @param offset the offset of the selection range
+     * @param length the length of the selection range. A negative length places
+     *            the caret at the visual start of the selection.
+     */
+    void setSelectedRange(int offset, int length);
+
+    /**
+     * Returns the range of the current selection in coordinates of this viewer's document.
+     *
+     * @return a <code>Point</code> with x as the offset and y as the length of the current selection
+     */
+    Point getSelectedRange();
+
+    /**
+     * Returns a selection provider dedicated to this viewer. Subsequent
+     * calls to this method return always the same selection provider.
+     *
+     * @return this viewer's selection provider
+     */
+    ISelectionProvider getSelectionProvider();
+
+
+    /* ------------- appearance manipulation --------------- */
+
+    /**
+     * Ensures that the given range is visible.
+     *
+     * @param offset the offset of the range to be revealed
+     * @param length the length of the range to be revealed
+     */
+    void revealRange(int offset, int length);
+
+    /**
+     * Scrolls the widget so that the given index is the line
+     * with the smallest line number of all visible lines.
+     *
+     * @param index the line which should become the top most line
+     */
+    void setTopIndex(int index);
+
+    /**
+     * Returns the visible line with the smallest line number.
+     *
+     * @return the number of the top most visible line
+     */
+    int getTopIndex();
+
+    /**
+     * Returns the document offset of the upper left corner of this viewer's view port.
+     *
+     * @return the upper left corner offset
+     */
+    int getTopIndexStartOffset();
+
+    /**
+     * Returns the visible line with the highest line number.
+     *
+     * @return the number of the bottom most line
+     */
+    int getBottomIndex();
+
+    /**
+     * Returns the document offset of the lower right
+     * corner of this viewer's view port. This is the visible character
+     * with the highest character position. If the content of this viewer
+     * is shorter, the position of the last character of the content is returned.
+     *
+     * @return the lower right corner offset
+     */
+    int getBottomIndexEndOffset();
+
+    /**
+     * Returns the vertical offset of the first visible line.
+     *
+     * @return the vertical offset of the first visible line
+     */
+    int getTopInset();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextViewerExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.ITextViewerExtension;
+
+import dwtx.jface.text.IRewriteTarget; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwt.custom.VerifyKeyListener;
+import dwt.widgets.Control;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.ITextViewer}.
+ * <p>
+ * This extension interface replaces the event consumer mechanism (
+ * {@link dwtx.jface.text.ITextViewer#setEventConsumer(IEventConsumer)})
+ * with a set of methods that allow to manage a sequence of
+ * {@link dwt.custom.VerifyKeyListener}objects. It also adds
+ * <ul>
+ * <li>access to the control of this viewer</li>
+ * <li>marked region support as in emacs</li>
+ * <li>control of the viewer's redraw behavior by introducing
+ *     <code>setRedraw(bool)</code>
+ * <li>access to the viewer's rewrite target.
+ * </ul>
+ *
+ * A rewrite target ({@link dwtx.jface.text.IRewriteTarget}) represents
+ * an facade offering the necessary methods to manipulate a document that is the
+ * input document of a text viewer.
+ *
+ * @since 2.0
+ */
+public interface ITextViewerExtension {
+
+    /**
+     * Inserts the verify key listener at the beginning of the viewer's list of
+     * verify key listeners. If the listener is already registered with the
+     * viewer this call moves the listener to the beginning of the list.
+     *
+     * @param listener the listener to be inserted
+     */
+    void prependVerifyKeyListener(VerifyKeyListener listener);
+
+    /**
+     * Appends a verify key listener to the viewer's list of verify key
+     * listeners. If the listener is already registered with the viewer this
+     * call moves the listener to the end of the list.
+     *
+     * @param listener the listener to be added
+     */
+    void appendVerifyKeyListener(VerifyKeyListener listener);
+
+    /**
+     * Removes the verify key listener from the viewer's list of verify key listeners.
+     * If the listener is not registered with this viewer, this call has no effect.
+     *
+     * @param listener the listener to be removed
+     */
+    void removeVerifyKeyListener(VerifyKeyListener listener);
+
+    /**
+     * Returns the control of this viewer.
+     *
+     * @return the control of this viewer
+     */
+    Control getControl();
+
+    /**
+     * Sets a mark at the given offset or clears the mark if the specified
+     * offset is <code>-1</code>. If a mark is set and the selection is
+     * empty, cut and copy actions performed on this text viewer work on the
+     * region described by the positions of the mark and the cursor.
+     *
+     * @param offset the offset of the mark
+     */
+    void setMark(int offset);
+
+    /**
+     * Returns the position of the mark, <code>-1</code> if the mark is not set.
+     *
+     * @return the position of the mark or <code>-1</code> if no mark is set
+     */
+    int getMark();
+
+    /**
+     * Enables/disables the redrawing of this text viewer. This temporarily
+     * disconnects the viewer from its underlying
+     * {@link dwt.custom.StyledText}widget. While being
+     * disconnected only the viewer's selection may be changed using
+     * <code>setSelectedRange</code>. Any direct manipulation of the widget
+     * as well as calls to methods that change the viewer's presentation state
+     * (such as enabling the segmented view) are not allowed. When redrawing is
+     * disabled the viewer does not send out any selection or view port change
+     * notification. When redrawing is enabled again, a selection change
+     * notification is sent out for the selected range and this range is
+     * revealed causing a view port changed notification.
+     *
+     * @param redraw <code>true</code> to enable redrawing, <code>false</code>
+     *            otherwise
+     */
+    void setRedraw(bool redraw);
+
+    /**
+     * Returns the viewer's rewrite target.
+     *
+     * @return the viewer's rewrite target
+     */
+    IRewriteTarget getRewriteTarget();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextViewerExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,276 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.ITextViewerExtension2;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwt.graphics.Point;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.ITextViewer}.
+ * <p>
+ * It provides
+ * <ul>
+ * <li>text presentation invalidation enhancements</li>
+ * <li>text hover management enhancements</li>
+ * <li>a replacement for auto indent strategies</li>
+ * <li>support for custom painters</li>
+ * </ul>
+ *
+ * It extends the means for text presentation invalidation by allowing a
+ * specific region of the presentation to get invalidated. It replaces
+ * {@link dwtx.jface.text.ITextViewer#setTextHover(ITextHover, String)}
+ * with a new method that allows to specify state masks for a better control of
+ * the hover behavior.
+ * <p>
+ * An {@link dwtx.jface.text.IAutoEditStrategy} is a generalization of
+ * the original {@link dwtx.jface.text.IAutoIndentStrategy}. Auto edit
+ * strategies can be arranged in a list that is executed like a pipeline when
+ * the viewer content is changed.
+ * <p>
+ * A {@link dwtx.jface.text.IPainter}is creating and managing visual
+ * decorations on the viewer's text widget. Viewer's can have an open number of
+ * painters. Painters are informed about changes to the viewer content and state
+ * and can take the necessary action in responds to the notification.
+ *
+ * @since 2.1
+ */
+public interface ITextViewerExtension2 {
+
+     /**
+      * The state mask of the default hover (value <code>0xff</code>).
+      */
+     static const int DEFAULT_HOVER_STATE_MASK= 0xff;
+
+    /**
+     * Invalidates the viewer's text presentation for the given range.
+     *
+     * @param offset the offset of the first character to be redrawn
+     * @param length the length of the range to be redrawn
+     */
+    void invalidateTextPresentation(int offset, int length);
+
+    /**
+     * Sets this viewer's text hover for the given content type and the given state mask. If the given text hover
+     * is <code>null</code>, any hover installed for the given content type and state mask is removed.
+     *
+     * @param textViewerHover the new hover or <code>null</code>
+     * @param contentType the type for which the hover is to be registered or unregistered
+     * @param stateMask the DWT event state mask; <code>DEFAULT_HOVER_STATE_MASK</code> indicates that
+     *          the hover is installed as the default hover.
+     */
+    void setTextHover(ITextHover textViewerHover, String contentType, int stateMask);
+
+    /**
+     * Removes all text hovers for the given content type independent from their state mask.
+     * <p>
+     * Note: To remove a hover for a given content type and state mask
+     * use {@link #setTextHover(ITextHover, String, int)} with <code>null</code>
+     * as parameter for the text hover.
+     * </p>
+     * @param contentType the type for which all text hovers are to be unregistered
+     */
+    void removeTextHovers(String contentType);
+
+    /**
+     * Returns the currently displayed text hover if any, <code>null</code> otherwise.
+     *
+     * @return the currently displayed text hover or <code>null</code>
+     */
+    ITextHover getCurrentTextHover();
+
+    /**
+     * Returns the location at which the most recent mouse hover event
+     * has occurred.
+     *
+     * @return the location of the most recent mouse hover event
+     */
+    Point getHoverEventLocation();
+
+    /**
+     * Prepends the given auto edit strategy to the existing list of strategies
+     * for the specified content type. The strategies are called in the order in
+     * which they appear in the list of strategies.
+     *
+     * @param strategy the auto edit strategy
+     * @param contentType the content type
+     */
+    void prependAutoEditStrategy(IAutoEditStrategy strategy, String contentType);
+
+    /**
+     * Removes the first occurrence of the given auto edit strategy in the list of strategies
+     * registered under the specified content type.
+     *
+     * @param strategy the auto edit strategy
+     * @param contentType the content type
+     */
+    void removeAutoEditStrategy(IAutoEditStrategy strategy, String contentType);
+
+    /**
+     * Adds the given painter to this viewer.
+     *
+     * @param painter the painter to be added
+     */
+    void addPainter(IPainter painter);
+
+    /**
+     * Removes the given painter from this viewer. If the painter has not been
+     * added to this viewer, this call is without effect.
+     *
+     * @param painter the painter to be removed
+     */
+    void removePainter(IPainter painter);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextViewerExtension3.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextViewerExtension3;
+
+import dwtx.jface.text.IRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.ITextViewer}. <p>
+ * This interface has been replaced by {@link dwtx.jface.text.ITextViewerExtension5}.
+ * Clients are not supposed to use this interface any longer.
+ *
+ * @since 2.1
+ * @deprecated replaced by {@link dwtx.jface.text.ITextViewerExtension5}
+ */
+public interface ITextViewerExtension3 {
+
+
+    /**
+     * Returns the minimal region of the viewer's document that completely comprises everything that is
+     * visible in the viewer's widget or <code>null</code> if there is no such region.
+     *
+     * @return the minimal region of the viewer's document comprising the contents of the viewer's widget or <code>null</code>
+     */
+    IRegion getModelCoverage();
+
+
+    /**
+     * Returns the widget line that corresponds to the given line of the viewer's document or <code>-1</code> if there is no such line.
+     *
+     * @param modelLine the line of the viewer's document
+     * @return the corresponding widget line or <code>-1</code>
+     */
+    int modelLine2WidgetLine(int modelLine);
+
+    /**
+     * Returns the widget offset that corresponds to the given offset in the viewer's document
+     * or <code>-1</code> if there is no such offset
+     *
+     * @param modelOffset the offset in the viewer's document
+     * @return the corresponding widget offset or <code>-1</code>
+     */
+    int modelOffset2WidgetOffset(int modelOffset);
+
+    /**
+     * Returns the minimal region of the viewer's widget that completely comprises the given region of the
+     * viewer's document or <code>null</code> if there is no such region.
+     *
+     * @param modelRange the region of the viewer's document
+     * @return the minimal region of the widget comprising <code>modelRange</code> or <code>null</code>
+     */
+    IRegion modelRange2WidgetRange(IRegion modelRange);
+
+
+    /**
+     * Returns the offset of the viewer's document that corresponds to the given widget offset
+     * or <code>-1</code> if there is no such offset
+     *
+     * @param widgetOffset the widget offset
+     * @return the corresponding offset in the viewer's document or <code>-1</code>
+     */
+    int widgetOffset2ModelOffset(int widgetOffset);
+
+    /**
+     * Returns the minimal region of the viewer's document that completely comprises the given widget region
+     * or <code>null</code> if there is no such region.
+     *
+     * @param widgetRange the widget region
+     * @return the minimal region of the viewer's document comprising <code>widgetRange</code> or <code>null</code>
+     */
+    IRegion widgetRange2ModelRange(IRegion widgetRange);
+
+    /**
+     * Returns the line of the viewer's document that corresponds to the given widget line or <code>-1</code> if there is no such line.
+     *
+     * @param widgetLine the widget line
+     * @return the corresponding line of the viewer's document or <code>-1</code>
+     */
+    int widgetlLine2ModelLine(int widgetLine);
+
+    /**
+     * Returns the widget line of the given widget offset.
+     *
+     * @param widgetOffset the widget offset
+     * @return the widget line of the widget offset
+     */
+    int widgetLineOfWidgetOffset(int widgetOffset);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextViewerExtension4.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextViewerExtension4;
+
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.ITextViewer}.
+ * Introduces the concept of text presentation listeners and improves focus
+ * handling among widget token keepers.
+ * <p>
+ * A {@link dwtx.jface.text.ITextPresentationListener}is a listener that
+ * is informed by the viewer that a text presentation is about to be applied.
+ * During this callback the listener is allowed to modify the presentation. Text
+ * presentation listeners are thus a mean to participate in the process of text
+ * presentation creation.
+ *
+ * @since 3.0
+ */
+public interface ITextViewerExtension4 {
+
+    /**
+     * Instructs the receiver to request the {@link IWidgetTokenKeeper}
+     * currently holding the widget token to take the keyboard focus.
+     *
+     * @return <code>true</code> if there was any
+     *         <code>IWidgetTokenKeeper</code> that was asked to take the
+     *         focus, <code>false</code> otherwise
+     */
+    bool moveFocusToWidgetToken();
+
+    /**
+     * Adds the given text presentation listener to this text viewer.
+     * This call has no effect if the listener is already registered
+     * with this text viewer.
+     *
+     * @param listener the text presentation listener
+     */
+    void addTextPresentationListener(ITextPresentationListener listener);
+
+    /**
+     * Removes the given text presentation listener from this text viewer.
+     * This call has no effect if the listener is not registered with this
+     * text viewer.
+     *
+     * @param listener the text presentation listener
+     */
+    void removeTextPresentationListener(ITextPresentationListener listener);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextViewerExtension5.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextViewerExtension5;
+
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.ITextViewer}. Defines
+ * a conceptual replacement of the original visible region concept. This interface
+ * replaces {@link dwtx.jface.text.ITextViewerExtension3}.
+ * <p>
+ * Introduces the explicit concept of model and widget coordinates. For example,
+ * a selection returned by the text viewer's control is a widget selection. A
+ * widget selection always maps to a certain range of the viewer's document.
+ * This range is considered the model selection.
+ * <p>
+ * All model ranges that have a corresponding widget ranges are considered
+ * "exposed model ranges". The viewer can be requested to expose a given model
+ * range. Thus, a visible region is a particular degeneration of exposed model
+ * ranges.
+ * <p>
+ * This interface allows implementers to follow a sophisticated presentation
+ * model in which the visible presentation is a complex projection of the
+ * viewer's input document.
+ *
+ * @since 3.0
+ */
+public interface ITextViewerExtension5 : ITextViewerExtension3 {
+
+    /**
+     * Returns the minimal region of the viewer's input document that completely
+     * comprises everything that is visible in the viewer's widget or
+     * <code>null</code> if there is no such region.
+     *
+     * @return the minimal region of the viewer's document comprising the
+     *         contents of the viewer's widget or <code>null</code>
+     */
+    IRegion getModelCoverage();
+
+    /**
+     * Returns the widget line that corresponds to the given line of the
+     * viewer's input document or <code>-1</code> if there is no such line.
+     *
+     * @param modelLine the line of the viewer's document
+     * @return the corresponding widget line or <code>-1</code>
+     */
+    int modelLine2WidgetLine(int modelLine);
+
+    /**
+     * Returns the widget offset that corresponds to the given offset in the
+     * viewer's input document or <code>-1</code> if there is no such offset
+     *
+     * @param modelOffset the offset in the viewer's document
+     * @return the corresponding widget offset or <code>-1</code>
+     */
+    int modelOffset2WidgetOffset(int modelOffset);
+
+    /**
+     * Returns the minimal region of the viewer's widget that completely
+     * comprises the given region of the viewer's input document or
+     * <code>null</code> if there is no such region.
+     *
+     * @param modelRange the region of the viewer's document
+     * @return the minimal region of the widget comprising
+     *         <code>modelRange</code> or <code>null</code>
+     */
+    IRegion modelRange2WidgetRange(IRegion modelRange);
+
+    /**
+     * Returns the offset of the viewer's input document that corresponds to the
+     * given widget offset or <code>-1</code> if there is no such offset
+     *
+     * @param widgetOffset the widget offset
+     * @return the corresponding offset in the viewer's document or
+     *         <code>-1</code>
+     */
+    int widgetOffset2ModelOffset(int widgetOffset);
+
+    /**
+     * Returns the minimal region of the viewer's input document that completely
+     * comprises the given widget region or <code>null</code> if there is no
+     * such region.
+     *
+     * @param widgetRange the widget region
+     * @return the minimal region of the viewer's document comprising
+     *         <code>widgetlRange</code> or <code>null</code>
+     */
+    IRegion widgetRange2ModelRange(IRegion widgetRange);
+
+    /**
+     * Returns the line of the viewer's input document that corresponds to the
+     * given widget line or <code>-1</code> if there is no such line.
+     *
+     * @param widgetLine the widget line
+     * @return the corresponding line of the viewer's document or
+     *         <code>-1</code>
+     */
+    int widgetLine2ModelLine(int widgetLine);
+
+    /**
+     * Returns the widget line of the given widget offset.
+     *
+     * @param widgetOffset the widget offset
+     * @return the widget line of the widget offset
+     */
+    int widgetLineOfWidgetOffset(int widgetOffset);
+
+
+    /**
+     * Returns the maximal subranges of the given model range thus that there is
+     * no offset inside a subrange for which there is no image offset.
+     *
+     * @param modelRange the model range
+     * @return the list of subranges
+     */
+    IRegion[] getCoveredModelRanges(IRegion modelRange);
+
+    /**
+     * Exposes the given model range. Returns whether this call caused a change
+     * of the set of exposed model ranges.
+     *
+     * @param modelRange the model range to be exposed
+     * @return <code>true</code> if the set of exposed model ranges changed,
+     *         <code>false</code> otherwise
+     */
+    bool exposeModelRange(IRegion modelRange);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextViewerExtension6.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextViewerExtension6;
+
+import dwtx.jface.text.IUndoManager; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.hyperlink.IHyperlinkDetector;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.ITextViewer}.
+ * Introduces the concept of text hyperlinks and adds access to the undo manager.
+ *
+ * @see dwtx.jface.text.hyperlink.IHyperlink
+ * @see dwtx.jface.text.hyperlink.IHyperlinkDetector
+ * @since 3.1
+ */
+public interface ITextViewerExtension6 {
+
+    /**
+     * Sets this viewer's hyperlink detectors for the given state mask.
+     *
+     * @param hyperlinkDetectors    the new array of hyperlink detectors, <code>null</code>
+     *                                  or an empty array to disable hyperlinking
+     * @param eventStateMask        the DWT event state mask to activate hyperlink mode
+     */
+    void setHyperlinkDetectors(IHyperlinkDetector[] hyperlinkDetectors, int eventStateMask);
+
+    /**
+     * Returns this viewer's undo manager.
+     *
+     * @return the undo manager or <code>null</code> if it has not been plugged-in
+     * @since 3.1
+     */
+    IUndoManager getUndoManager();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextViewerExtension7.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextViewerExtension7;
+
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.ITextViewer}.
+ * Adds the ability to install tabs to spaces conversion.
+ *
+ * @since 3.3
+ */
+public interface ITextViewerExtension7 {
+
+    /**
+     * Sets an auto edit strategy can converts tabs to spaces.
+     *
+     * @param converter the converter or <code>null</code> if none should be used
+     */
+    void setTabsToSpacesConverter(IAutoEditStrategy converter);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITextViewerExtension8.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITextViewerExtension8;
+
+import dwt.dwthelper.utils;
+
+import dwt.custom.StyledTextPrintOptions;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.ITextViewer}. Adds the
+ * ability to print and set how hovers should be enriched when the mouse is moved into them.
+ *
+ * @since 3.4
+ */
+public interface ITextViewerExtension8 {
+
+    /**
+     * Print the text viewer contents using the given options.
+     *
+     * @param options the print options
+     */
+    void print(StyledTextPrintOptions options);
+
+    /**
+     * Sets the hover enrich mode.
+     * A non-<code>null</code> <code>mode</code> defines when hovers
+     * should be enriched once the mouse is moved into them.
+     * If <code>mode</code> is <code>null</code>, hovers are automatically closed
+     * when the mouse is moved out of the {@link ITextHover#getHoverRegion(ITextViewer, int) hover region}.
+     * <p>
+     * Note that a hover can only be enriched if its {@link IInformationControlExtension5#getInformationPresenterControlCreator()}
+     * is not <code>null</code>.
+     * </p>
+     *
+     * @param mode the enrich mode, or <code>null</code>
+     */
+    void setHoverEnrichMode(EnrichMode mode);
+
+
+
+}
+
+    /**
+     * Type-safe enum of the available enrich modes.
+     */
+    public final class EnrichMode {
+
+        /**
+         * Enrich the hover shortly after the mouse has been moved into it and
+         * stopped moving.
+         *
+         * @see ITextViewerExtension8#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode)
+         */
+        public static const EnrichMode AFTER_DELAY;
+
+        /**
+         * Enrich the hover immediately when the mouse is moved into it.
+         *
+         * @see ITextViewerExtension8#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode)
+         */
+        public static const EnrichMode IMMEDIATELY;
+
+        /**
+         * Enrich the hover on explicit mouse click.
+         *
+         * @see ITextViewerExtension8#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode)
+         */
+        public static const EnrichMode ON_CLICK;
+
+
+        static this(){
+            AFTER_DELAY= new EnrichMode("after delay"); //$NON-NLS-1$
+            IMMEDIATELY= new EnrichMode("immediately"); //$NON-NLS-1$
+            ON_CLICK= new EnrichMode("on click"); //$NON-NLS-1$;
+        }
+
+        private String fName;
+
+        private this(String name) {
+            fName= name;
+        }
+
+        /*
+         * @see java.lang.Object#toString()
+         */
+        public override String toString() {
+            return fName;
+        }
+    }
+alias EnrichMode ITextViewerExtension8_EnrichMode;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ITypedRegion.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ITypedRegion;
+
+import dwtx.jface.text.IRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+
+/**
+ * Describes a region of an indexed text store such as a document or a string.
+ * The region consists of offset, length, and type. The region type is defined
+ * as a string.
+ * <p>
+ * A typed region can, e.g., be used to described document partitions.</p>
+ * <p>
+ * Clients may implement this interface or use the standard implementation
+ * {@link dwtx.jface.text.TypedRegion}.</p>
+ */
+public interface ITypedRegion : IRegion {
+
+    /**
+     * Returns the content type of the region.
+     *
+     * @return the content type of the region
+     */
+    String getType();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IUndoManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IUndoManager;
+
+import dwtx.jface.text.ITextViewer; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * An undo manager is connected to at most one
+ * {@link dwtx.jface.text.ITextViewer}.
+ * <p>
+ * It monitors the text viewer and keeps a history of the changes applied to the
+ * viewer. The undo manager groups those changes into user interactions which on
+ * an undo request are rolled back in one atomic change.</p>
+ * <p>
+ * In order to provide backward compatibility for clients of
+ * <code>IUndoManager</code>, extension interfaces are used as a means of
+ * evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.IUndoManagerExtension} since version 3.1
+ * introducing access to the undo context.</li>
+ * </ul></p>
+ * <p>
+ * Clients may implement this interface or use the standard implementation
+ * <code>TextViewerUndoManager</code>.
+ * </p>
+ *
+ * @see TextViewerUndoManager
+ * @see IUndoManagerExtension
+ */
+public interface IUndoManager {
+
+    /**
+     * Connects this undo manager to the given text viewer.
+     *
+     * @param viewer the viewer the undo manager is connected to
+     */
+    void connect(ITextViewer viewer);
+
+    /**
+     * Disconnects this undo manager from its text viewer.
+     * If this undo manager hasn't been connected before this
+     * operation has no effect.
+     */
+    void disconnect();
+
+    /**
+     * Signals the undo manager that all subsequent changes until
+     * <code>endCompoundChange</code> is called are to be undone in one piece.
+     */
+    void beginCompoundChange();
+
+    /**
+     * Signals the undo manager that the sequence of changes which started with
+     * <code>beginCompoundChange</code> has been finished. All subsequent changes
+     * are considered to be individually undo-able.
+     */
+    void endCompoundChange();
+
+    /**
+     * Resets the history of the undo manager. After that call,
+     * there aren't any undo-able or redo-able text changes.
+     */
+    void reset();
+
+    /**
+     * The given parameter determines the maximal length of the history
+     * remembered by the undo manager.
+     *
+     * @param undoLevel the length of this undo manager's history
+     */
+    void setMaximalUndoLevel(int undoLevel);
+
+    /**
+     * Returns whether at least one text change can be rolled back.
+     *
+     * @return <code>true</code> if at least one text change can be rolled back
+     */
+    bool undoable();
+
+    /**
+     * Returns whether at least one text change can be repeated. A text change
+     * can be repeated only if it was executed and rolled back.
+     *
+     * @return <code>true</code> if at least on text change can be repeated
+     */
+    bool redoable();
+
+    /**
+     * Rolls back the most recently executed text change.
+     */
+    void undo();
+
+    /**
+     * Repeats the most recently rolled back text change.
+     */
+    void redo();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IUndoManagerExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IUndoManagerExtension;
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.commands.operations.IUndoContext;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IUndoManager}.
+ * Introduces access to the undo context.
+ *
+ * @see dwtx.jface.text.IUndoManager
+ * @since 3.1
+ */
+public interface IUndoManagerExtension {
+
+    /**
+     * Returns this undo manager's undo context.
+     *
+     * @return the undo context or <code>null</code> if the undo manager is not connected
+     * @see dwtx.core.commands.operations.IUndoContext
+     */
+    IUndoContext getUndoContext();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IViewportListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IViewportListener;
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Registered with a text viewer, view port listeners are informed about changes
+ * of a text viewer's view port. The view port is that portion of the viewer's
+ * document which is visible in the viewer.
+ * <p>
+ * Clients may implement this interface.</p>
+ *
+ * @see dwtx.jface.text.ITextViewer
+ */
+public interface IViewportListener {
+
+    /**
+     * Informs about view port changes. The given vertical position is the new
+     * vertical scrolling offset measured in pixels.
+     *
+     * @param verticalOffset the vertical offset measured in pixels
+     */
+    void viewportChanged(int verticalOffset);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IWidgetTokenKeeper.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IWidgetTokenKeeper;
+
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * A widget token keeper may require a widget token from an
+ * {@link dwtx.jface.text.IWidgetTokenOwner} and release the token to the
+ * owner after usage. A widget token owner may request the token from the token
+ * keeper. The keeper may deny the return of the token.
+ * <p>
+ * The widget token owner and keeper interplay is used by a text viewer in
+ * order to manage the appearance and disappearance of addition, on-top popup
+ * windows such as text hovers, content assist, etc.
+ *
+ * In order to provide backward compatibility for clients of
+ * <code>IWidgetTokeKeeper</code>, extension interfaces are used as a means
+ * of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.IWidgetTokenKeeperExtension} since version
+ *     3.0 introducing priorities when requesting a widget token and thus replacing
+ *     the non-prioritized scheme. It also allows a client to force a widget token
+ *     keeper to accept focus.</li>
+ * </ul>
+ *
+ * @see dwtx.jface.text.IWidgetTokenKeeperExtension
+ * @since 2.0
+ */
+public interface IWidgetTokenKeeper {
+
+    /**
+     * The given widget token owner requests the widget token from this token
+     * keeper. Returns <code>true</code> if the token is released by this
+     * token keeper. Note, the keeper must not call
+     * <code>releaseWidgetToken(IWidgetTokenKeeper)</code> explicitly.
+     * <p>
+     * Replaced by
+     * {@link IWidgetTokenKeeperExtension#requestWidgetToken(IWidgetTokenOwner, int)}.
+     *
+     * @param owner the token owner
+     * @return <code>true</code> if token has been released <code>false</code>
+     *         otherwise
+     */
+    bool requestWidgetToken(IWidgetTokenOwner owner);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IWidgetTokenKeeperExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IWidgetTokenKeeperExtension;
+
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IWidgetTokenKeeper}.
+ * <p>
+ * Replaces the original <code>requestWidgetToken</code> functionality with a
+ * new priority based approach. Adds the concept of focus handling.
+ *
+ * @since 3.0
+ */
+public interface IWidgetTokenKeeperExtension {
+
+    /**
+     * The given widget token owner requests the widget token  from
+     * this token keeper. Returns  <code>true</code> if the token is released
+     * by this token keeper. Note, the keeper must not call
+     * <code>releaseWidgetToken(IWidgetTokenKeeper)</code> explicitly.
+     *
+     * <p>The general contract is that the receiver should release the token
+     * if <code>priority</code> exceeds the receiver's priority.</p>
+     *
+     * @param owner the token owner
+     * @param priority the priority of the request
+     * @return <code>true</code> if token has been released <code>false</code> otherwise
+     */
+    bool requestWidgetToken(IWidgetTokenOwner owner, int priority);
+
+    /**
+     * Requests the receiver to give focus to its popup shell, hover, or similar. There is
+     * no assumption made whether the receiver actually succeeded in taking the focus. The return
+     * value gives a hint whether the receiver tried to take focus.
+     *
+     * @param owner the token owner
+     * @return <code>true</code> if the receiver tried to take focus, <code>false</code> if it did not.
+     */
+    bool setFocus(IWidgetTokenOwner owner);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IWidgetTokenOwner.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.IWidgetTokenOwner;
+
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * In order to display information in a temporary window, a widget token must be
+ * acquired. The intent behind this concept is that only one temporary window
+ * should be presented at any moment in time and also to avoid overlapping
+ * temporary windows. This concept is used by the
+ * {@link dwtx.jface.text.ITextViewer}.
+ * <p>
+ * In order to provide backward compatibility for clients of
+ * <code>IWidgetTokenOwner</code>, extension interfaces are used as a means
+ * of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.IWidgetTokenOwnerExtension} since version
+ * 3.0 introducing priorities when requesting a widget token and thus replacing
+ * the non-prioritized scheme.</li>
+ * </ul>
+ *
+ * @see dwtx.jface.text.IWidgetTokenOwnerExtension
+ * @since 2.0
+ */
+public interface IWidgetTokenOwner {
+
+    /**
+     * Requests the widget token from this token owner. Returns
+     * <code>true</code> if the token has been acquired or is already owned by
+     * the requester. This method is non-blocking.
+     * <p>
+     * Replaced by
+     * {@link IWidgetTokenOwnerExtension#requestWidgetToken(IWidgetTokenKeeper, int)}.
+     *
+     * @param requester the token requester
+     * @return <code>true</code> if requester acquires the token,
+     *         <code>false</code> otherwise
+     */
+    bool requestWidgetToken(IWidgetTokenKeeper requester);
+
+    /**
+     * The given token keeper releases the token to this
+     * token owner. If the token has previously not been held
+     * by the given token keeper, nothing happens. This
+     * method is non-blocking.
+     *
+     * @param tokenKeeper the token keeper
+     */
+    void releaseWidgetToken(IWidgetTokenKeeper tokenKeeper);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/IWidgetTokenOwnerExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.IWidgetTokenOwnerExtension;
+
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.IWidgetTokenOwner}.
+ * <p>
+ * Replaces the original <code>requestWidgetToken</code> functionality with a
+ * new priority based approach.
+ *
+ * @since 3.0
+ */
+public interface IWidgetTokenOwnerExtension {
+
+    /**
+     * Requests the widget token from this token owner. Returns
+     * <code>true</code> if the token has been acquired or is
+     * already owned by the requester. This method is non-blocking.
+     *
+     * <p><code>priority</code> is forwarded to any existing token keeper
+     * to give it an estimate on whether the request has higher priority than
+     * the current keeper's. There is, however, no guarantee that another keeper
+     * will release the token even if it has a high priority.</p>
+     *
+     * @param requester the token requester
+     * @param priority the priority of the request
+     * @return <code>true</code> if requester acquires the token,
+     *  <code>false</code> otherwise
+     */
+    bool requestWidgetToken(IWidgetTokenKeeper requester, int priority);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/JFaceTextMessages.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,182 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.JFaceTextMessages;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.dwthelper.ResourceBundle;
+
+class JFaceTextMessages {
+
+//     private static const String RESOURCE_BUNDLE= "dwtx.jface.text.JFaceTextMessages";//$NON-NLS-1$
+
+    private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+    static this() {
+        fgResourceBundle = ResourceBundle.getBundle(
+            getImportData!("dwtx.jface.text.JFaceTextMessages.properties"));
+    }
+
+    private this() {
+    }
+
+    public static String getString(String key) {
+        try {
+            return fgResourceBundle.getString(key);
+        } catch (MissingResourceException e) {
+            return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/JFaceTextUtil.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,503 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.JFaceTextUtil;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.custom.StyledText;
+import dwt.graphics.GC;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Control;
+import dwtx.jface.text.source.ILineRange;
+import dwtx.jface.text.source.LineRange;
+
+/**
+ * A collection of JFace Text functions.
+ * <p>
+ * This class is neither intended to be instantiated nor subclassed.
+ * </p>
+ *
+ * @since 3.3
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class JFaceTextUtil {
+
+    private this() {
+        // Do not instantiate
+    }
+
+    /**
+     * Computes the line height for the given line range.
+     *
+     * @param textWidget the <code>StyledText</code> widget
+     * @param startLine the start line
+     * @param endLine the end line (exclusive)
+     * @param lineCount the line count used by the old API
+     * @return the height of all lines starting with <code>startLine</code> and ending above <code>endLime</code>
+     */
+    public static int computeLineHeight(StyledText textWidget, int startLine, int endLine, int lineCount) {
+        return getLinePixel(textWidget, endLine) - getLinePixel(textWidget, startLine);
+    }
+
+    /**
+     * Returns the last fully visible line of the widget. The exact semantics of "last fully visible
+     * line" are:
+     * <ul>
+     * <li>the last line of which the last pixel is visible, if any
+     * <li>otherwise, the only line that is partially visible
+     * </ul>
+     *
+     * @param widget the widget
+     * @return the last fully visible line
+     */
+    public static int getBottomIndex(StyledText widget) {
+        int lastPixel= computeLastVisiblePixel(widget);
+
+        // bottom is in [0 .. lineCount - 1]
+        int bottom= widget.getLineIndex(lastPixel);
+
+        // bottom is the first line - no more checking
+        if (bottom is 0)
+            return bottom;
+
+        int pixel= widget.getLinePixel(bottom);
+        // bottom starts on or before the client area start - bottom is the only visible line
+        if (pixel <= 0)
+            return bottom;
+
+        int offset= widget.getOffsetAtLine(bottom);
+        int height= widget.getLineHeight(offset);
+
+        // bottom is not showing entirely - use the previous line
+        if (pixel + height - 1 > lastPixel)
+            return bottom - 1;
+
+        // bottom is fully visible and its last line is exactly the last pixel
+        return bottom;
+    }
+
+    /**
+     * Returns the index of the first (possibly only partially) visible line of the widget
+     *
+     * @param widget the widget
+     * @return the index of the first line of which a pixel is visible
+     */
+    public static int getPartialTopIndex(StyledText widget) {
+        // see StyledText#getPartialTopIndex()
+        int top= widget.getTopIndex();
+        int pixels= widget.getLinePixel(top);
+
+        // FIXME remove when https://bugs.eclipse.org/bugs/show_bug.cgi?id=123770 is fixed
+        if (pixels is -widget.getLineHeight(widget.getOffsetAtLine(top))) {
+            top++;
+            pixels= 0;
+        }
+
+        if (pixels > 0)
+            top--;
+
+        return top;
+    }
+
+    /**
+     * Returns the index of the last (possibly only partially) visible line of the widget
+     *
+     * @param widget the text widget
+     * @return the index of the last line of which a pixel is visible
+     */
+    public static int getPartialBottomIndex(StyledText widget) {
+        // @see StyledText#getPartialBottomIndex()
+        int lastPixel= computeLastVisiblePixel(widget);
+        int bottom= widget.getLineIndex(lastPixel);
+        return bottom;
+    }
+
+    /**
+     * Returns the last visible pixel in the widget's client area.
+     *
+     * @param widget the widget
+     * @return the last visible pixel in the widget's client area
+     */
+    private static int computeLastVisiblePixel(StyledText widget) {
+        int caHeight= widget.getClientArea().height;
+        int lastPixel= caHeight - 1;
+        // XXX what if there is a margin? can't take trim as this includes the scrollbars which are not part of the client area
+//      if ((textWidget.getStyle() & DWT.BORDER) !is 0)
+//          lastPixel -= 4;
+        return lastPixel;
+    }
+
+    /**
+     * Returns the line index of the first visible model line in the viewer. The line may be only
+     * partially visible.
+     *
+     * @param viewer the text viewer
+     * @return the first line of which a pixel is visible, or -1 for no line
+     */
+    public static int getPartialTopIndex(ITextViewer viewer) {
+        StyledText widget= viewer.getTextWidget();
+        int widgetTop= getPartialTopIndex(widget);
+        return widgetLine2ModelLine(viewer, widgetTop);
+    }
+
+    /**
+     * Returns the last, possibly partially, visible line in the view port.
+     *
+     * @param viewer the text viewer
+     * @return the last, possibly partially, visible line in the view port
+     */
+    public static int getPartialBottomIndex(ITextViewer viewer) {
+        StyledText textWidget= viewer.getTextWidget();
+        int widgetBottom= getPartialBottomIndex(textWidget);
+        return widgetLine2ModelLine(viewer, widgetBottom);
+    }
+
+    /**
+     * Returns the range of lines that is visible in the viewer, including any partially visible
+     * lines.
+     *
+     * @param viewer the viewer
+     * @return the range of lines that is visible in the viewer, <code>null</code> if no lines are
+     *         visible
+     */
+    public static ILineRange getVisibleModelLines(ITextViewer viewer) {
+        int top= getPartialTopIndex(viewer);
+        int bottom= getPartialBottomIndex(viewer);
+        if (top is -1 || bottom is -1)
+            return null;
+        return new LineRange(top, bottom - top + 1);
+    }
+
+    /**
+     * Converts a widget line into a model (i.e. {@link IDocument}) line using the
+     * {@link ITextViewerExtension5} if available, otherwise by adapting the widget line to the
+     * viewer's {@link ITextViewer#getVisibleRegion() visible region}.
+     *
+     * @param viewer the viewer
+     * @param widgetLine the widget line to convert.
+     * @return the model line corresponding to <code>widgetLine</code> or -1 to signal that there
+     *         is no corresponding model line
+     */
+    public static int widgetLine2ModelLine(ITextViewer viewer, int widgetLine) {
+        int modelLine;
+        if ( cast(ITextViewerExtension5)viewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) viewer;
+            modelLine= extension.widgetLine2ModelLine(widgetLine);
+        } else {
+            try {
+                IRegion r= viewer.getVisibleRegion();
+                IDocument d= viewer.getDocument();
+                modelLine= widgetLine + d.getLineOfOffset(r.getOffset());
+            } catch (BadLocationException x) {
+                modelLine= widgetLine;
+            }
+        }
+        return modelLine;
+    }
+
+    /**
+     * Converts a model (i.e. {@link IDocument}) line into a widget line using the
+     * {@link ITextViewerExtension5} if available, otherwise by adapting the model line to the
+     * viewer's {@link ITextViewer#getVisibleRegion() visible region}.
+     *
+     * @param viewer the viewer
+     * @param modelLine the model line to convert.
+     * @return the widget line corresponding to <code>modelLine</code> or -1 to signal that there
+     *         is no corresponding widget line
+     */
+    public static int modelLineToWidgetLine(ITextViewer viewer, int modelLine) {
+        int widgetLine;
+        if ( cast(ITextViewerExtension5)viewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) viewer;
+            widgetLine= extension.modelLine2WidgetLine(modelLine);
+        } else {
+            IRegion region= viewer.getVisibleRegion();
+            IDocument document= viewer.getDocument();
+            try {
+                int visibleStartLine= document.getLineOfOffset(region.getOffset());
+                int visibleEndLine= document.getLineOfOffset(region.getOffset() + region.getLength());
+                if (modelLine < visibleStartLine || modelLine > visibleEndLine)
+                    widgetLine= -1;
+                else
+                widgetLine= modelLine - visibleStartLine;
+            } catch (BadLocationException x) {
+                // ignore and return -1
+                widgetLine= -1;
+            }
+        }
+        return widgetLine;
+    }
+
+
+    /**
+     * Returns the number of hidden pixels of the first partially visible line. If there is no
+     * partially visible line, zero is returned.
+     *
+     * @param textWidget the widget
+     * @return the number of hidden pixels of the first partial line, always &gt;= 0
+     */
+    public static int getHiddenTopLinePixels(StyledText textWidget) {
+        int top= getPartialTopIndex(textWidget);
+        return -textWidget.getLinePixel(top);
+    }
+
+    /*
+     * @see StyledText#getLinePixel(int)
+     */
+    public static int getLinePixel(StyledText textWidget, int line) {
+        return textWidget.getLinePixel(line);
+    }
+
+    /*
+     * @see StyledText#getLineIndex(int)
+     */
+    public static int getLineIndex(StyledText textWidget, int y) {
+        int lineIndex= textWidget.getLineIndex(y);
+        return lineIndex;
+    }
+
+    /**
+     * Returns <code>true</code> if the widget displays the entire contents, i.e. it cannot
+     * be vertically scrolled.
+     *
+     * @param widget the widget
+     * @return <code>true</code> if the widget displays the entire contents, i.e. it cannot
+     *         be vertically scrolled, <code>false</code> otherwise
+     */
+    public static bool isShowingEntireContents(StyledText widget) {
+        if (widget.getTopPixel() !is 0) // more efficient shortcut
+            return false;
+
+        int lastVisiblePixel= computeLastVisiblePixel(widget);
+        int lastPossiblePixel= widget.getLinePixel(widget.getLineCount());
+        return lastPossiblePixel <= lastVisiblePixel;
+    }
+
+    /**
+     * Determines the graphical area covered by the given text region in
+     * the given viewer.
+     *
+     * @param region the region whose graphical extend must be computed
+     * @param textViewer the text viewer containing the region
+     * @return the graphical extend of the given region in the given viewer
+     *
+     * @since 3.4
+     */
+    public static Rectangle computeArea(IRegion region, ITextViewer textViewer) {
+        int start= 0;
+        int end= 0;
+        IRegion widgetRegion= modelRange2WidgetRange(region, textViewer);
+        if (widgetRegion !is null) {
+            start= widgetRegion.getOffset();
+            end= start + widgetRegion.getLength();
+        }
+
+        StyledText styledText= textViewer.getTextWidget();
+        Rectangle bounds;
+        if (end > 0 && start < end)
+            bounds= styledText.getTextBounds(start, end - 1);
+        else {
+            Point loc= styledText.getLocationAtOffset(start);
+            bounds= new Rectangle(loc.x, loc.y, getAverageCharWidth(textViewer.getTextWidget()), styledText.getLineHeight(start));
+        }
+
+        return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
+    }
+
+    /**
+     * Translates a given region of the text viewer's document into
+     * the corresponding region of the viewer's widget.
+     *
+     * @param region the document region
+     * @param textViewer the viewer containing the region
+     * @return the corresponding widget region
+     *
+     * @since 3.4
+     */
+    private static IRegion modelRange2WidgetRange(IRegion region, ITextViewer textViewer) {
+        if ( cast(ITextViewerExtension5)textViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) textViewer;
+            return extension.modelRange2WidgetRange(region);
+        }
+
+        IRegion visibleRegion= textViewer.getVisibleRegion();
+        int start= region.getOffset() - visibleRegion.getOffset();
+        int end= start + region.getLength();
+        if (end > visibleRegion.getLength())
+            end= visibleRegion.getLength();
+
+        return new Region(start, end - start);
+    }
+
+    /**
+     * Returns the average character width of the given control's font.
+     *
+     * @param control the control to calculate the average char width for
+     * @return the average character width of the controls font
+     *
+     * @since 3.4
+     */
+    public static int getAverageCharWidth(Control control) {
+        GC gc= new GC(control);
+        gc.setFont(control.getFont());
+        int increment= gc.getFontMetrics().getAverageCharWidth();
+        gc.dispose();
+        return increment;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/Line.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.Line;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Describes a line as a particular number of characters beginning at
+ * a particular offset, consisting of a particular number of characters,
+ * and being closed with a particular line delimiter.
+ */
+final class Line : IRegion {
+
+    /** The offset of the line */
+    public int offset;
+    /** The length of the line */
+    public int length;
+    /** The delimiter of this line */
+    public const String delimiter;
+
+    /**
+     * Creates a new Line.
+     *
+     * @param offset the offset of the line
+     * @param end the last including character offset of the line
+     * @param delimiter the line's delimiter
+     */
+    public this(int offset, int end, String delimiter) {
+        this.offset= offset;
+        this.length= (end - offset) +1;
+        this.delimiter= delimiter;
+    }
+
+    /**
+     * Creates a new Line.
+     *
+     * @param offset the offset of the line
+     * @param length the length of the line
+     */
+    public this(int offset, int length) {
+        this.offset= offset;
+        this.length= length;
+        this.delimiter= null;
+    }
+
+    /*
+     * @see dwtx.jface.text.IRegion#getOffset()
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /*
+     * @see dwtx.jface.text.IRegion#getLength()
+     */
+    public int getLength() {
+        return length;
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/ListLineTracker.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,505 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.ListLineTracker;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+
+import dwtx.jface.text.AbstractLineTracker;
+
+/**
+ * Abstract, read-only implementation of <code>ILineTracker</code>. It lets the definition of
+ * line delimiters to subclasses. Assuming that '\n' is the only line delimiter, this abstract
+ * implementation defines the following line scheme:
+ * <ul>
+ * <li> "" -> [0,0]
+ * <li> "a" -> [0,1]
+ * <li> "\n" -> [0,1], [1,0]
+ * <li> "a\n" -> [0,2], [2,0]
+ * <li> "a\nb" -> [0,2], [2,1]
+ * <li> "a\nbc\n" -> [0,2], [2,3], [5,0]
+ * </ul>
+ * This class must be subclassed.
+ *
+ * @since 3.2
+ */
+abstract class ListLineTracker : ILineTracker {
+
+    /** The line information */
+    private const List fLines;
+    /** The length of the tracked text */
+    private int fTextLength;
+
+    /**
+     * Creates a new line tracker.
+     */
+    protected this() {
+        fLines= new ArrayList();
+    }
+
+    /**
+     * Binary search for the line at a given offset.
+     *
+     * @param offset the offset whose line should be found
+     * @return the line of the offset
+     */
+    private int findLine(int offset) {
+
+        if (fLines.size() is 0)
+            return -1;
+
+        int left= 0;
+        int right= fLines.size() - 1;
+        int mid= 0;
+        Line line= null;
+
+        while (left < right) {
+
+            mid= (left + right) / 2;
+
+            line= cast(Line) fLines.get(mid);
+            if (offset < line.offset) {
+                if (left is mid)
+                    right= left;
+                else
+                    right= mid - 1;
+            } else if (offset > line.offset) {
+                if (right is mid)
+                    left= right;
+                else
+                    left= mid + 1;
+            } else if (offset is line.offset) {
+                left= right= mid;
+            }
+        }
+
+        line= cast(Line) fLines.get(left);
+        if (line.offset > offset)
+            --left;
+        return left;
+    }
+
+    /**
+     * Returns the number of lines covered by the specified text range.
+     *
+     * @param startLine the line where the text range starts
+     * @param offset the start offset of the text range
+     * @param length the length of the text range
+     * @return the number of lines covered by this text range
+     * @exception BadLocationException if range is undefined in this tracker
+     */
+    private int getNumberOfLines(int startLine, int offset, int length)  {
+
+        if (length is 0)
+            return 1;
+
+        int target= offset + length;
+
+        Line l= cast(Line) fLines.get(startLine);
+
+        if (l.delimiter is null)
+            return 1;
+
+        if (l.offset + l.length > target)
+            return 1;
+
+        if (l.offset + l.length is target)
+            return 2;
+
+        return getLineNumberOfOffset(target) - startLine + 1;
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineLength(int)
+     */
+    public final int getLineLength(int line)  {
+        int lines= fLines.size();
+
+        if (line < 0 || line > lines)
+            throw new BadLocationException();
+
+        if (lines is 0 || lines is line)
+            return 0;
+
+        Line l= cast(Line) fLines.get(line);
+        return l.length;
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineNumberOfOffset(int)
+     */
+    public final int getLineNumberOfOffset(int position)  {
+        if (position < 0 || position > fTextLength)
+            throw new BadLocationException();
+
+        if (position is fTextLength) {
+
+            int lastLine= fLines.size() - 1;
+            if (lastLine < 0)
+                return 0;
+
+            Line l= cast(Line) fLines.get(lastLine);
+            return (l.delimiter !is null ? lastLine + 1 : lastLine);
+        }
+
+        return findLine(position);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineInformationOfOffset(int)
+     */
+    public final IRegion getLineInformationOfOffset(int position)  {
+        if (position > fTextLength)
+            throw new BadLocationException();
+
+        if (position is fTextLength) {
+            int size= fLines.size();
+            if (size is 0)
+                return new Region(0, 0);
+            Line l= cast(Line) fLines.get(size - 1);
+            return (l.delimiter !is null ? new Line(fTextLength, 0) : new Line(fTextLength - l.length, l.length));
+        }
+
+        return getLineInformation(findLine(position));
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineInformation(int)
+     */
+    public final IRegion getLineInformation(int line)  {
+        int lines= fLines.size();
+
+        if (line < 0 || line > lines)
+            throw new BadLocationException();
+
+        if (lines is 0)
+            return new Line(0, 0);
+
+        if (line is lines) {
+            Line l= cast(Line) fLines.get(line - 1);
+            return new Line(l.offset + l.length, 0);
+        }
+
+        Line l= cast(Line) fLines.get(line);
+        return (l.delimiter !is null ? new Line(l.offset, l.length - l.delimiter.length()) : l);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineOffset(int)
+     */
+    public final int getLineOffset(int line)  {
+        int lines= fLines.size();
+
+        if (line < 0 || line > lines)
+            throw new BadLocationException();
+
+        if (lines is 0)
+            return 0;
+
+        if (line is lines) {
+            Line l= cast(Line) fLines.get(line - 1);
+            if (l.delimiter !is null)
+                return l.offset + l.length;
+            throw new BadLocationException();
+        }
+
+        Line l= cast(Line) fLines.get(line);
+        return l.offset;
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getNumberOfLines()
+     */
+    public final int getNumberOfLines() {
+        int lines= fLines.size();
+
+        if (lines is 0)
+            return 1;
+
+        Line l= cast(Line) fLines.get(lines - 1);
+        return (l.delimiter !is null ? lines + 1 : lines);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getNumberOfLines(int, int)
+     */
+    public final int getNumberOfLines(int position, int length)  {
+
+        if (position < 0 || position + length > fTextLength)
+            throw new BadLocationException();
+
+        if (length is 0) // optimization
+            return 1;
+
+        return getNumberOfLines(getLineNumberOfOffset(position), position, length);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#computeNumberOfLines(java.lang.String)
+     */
+    public final int computeNumberOfLines(String text) {
+        int count= 0;
+        int start= 0;
+        AbstractLineTracker_DelimiterInfo delimiterInfo= nextDelimiterInfo(text, start);
+        while (delimiterInfo !is null && delimiterInfo.delimiterIndex > -1) {
+            ++count;
+            start= delimiterInfo.delimiterIndex + delimiterInfo.delimiterLength;
+            delimiterInfo= nextDelimiterInfo(text, start);
+        }
+        return count;
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineDelimiter(int)
+     */
+    public final String getLineDelimiter(int line)  {
+        int lines= fLines.size();
+
+        if (line < 0 || line > lines)
+            throw new BadLocationException();
+
+        if (lines is 0)
+            return null;
+
+        if (line is lines)
+            return null;
+
+        Line l= cast(Line) fLines.get(line);
+        return l.delimiter;
+    }
+
+    /**
+     * Returns the information about the first delimiter found in the given text starting at the
+     * given offset.
+     *
+     * @param text the text to be searched
+     * @param offset the offset in the given text
+     * @return the information of the first found delimiter or <code>null</code>
+     */
+    protected abstract AbstractLineTracker_DelimiterInfo nextDelimiterInfo(String text, int offset);
+
+    /**
+     * Creates the line structure for the given text. Newly created lines are inserted into the line
+     * structure starting at the given position. Returns the number of newly created lines.
+     *
+     * @param text the text for which to create a line structure
+     * @param insertPosition the position at which the newly created lines are inserted into the
+     *        tracker's line structure
+     * @param offset the offset of all newly created lines
+     * @return the number of newly created lines
+     */
+    private int createLines(String text, int insertPosition, int offset) {
+
+        int count= 0;
+        int start= 0;
+        AbstractLineTracker_DelimiterInfo delimiterInfo= nextDelimiterInfo(text, 0);
+
+        while (delimiterInfo !is null && delimiterInfo.delimiterIndex > -1) {
+
+            int index= delimiterInfo.delimiterIndex + (delimiterInfo.delimiterLength - 1);
+
+            if (insertPosition + count >= fLines.size())
+                fLines.add(new Line(offset + start, offset + index, delimiterInfo.delimiter));
+            else
+                fLines.add(insertPosition + count, new Line(offset + start, offset + index, delimiterInfo.delimiter));
+
+            ++count;
+            start= index + 1;
+            delimiterInfo= nextDelimiterInfo(text, start);
+        }
+
+        if (start < text.length()) {
+            if (insertPosition + count < fLines.size()) {
+                // there is a line below the current
+                Line l= cast(Line) fLines.get(insertPosition + count);
+                int delta= text.length() - start;
+                l.offset-= delta;
+                l.length+= delta;
+            } else {
+                fLines.add(new Line(offset + start, offset + text.length() - 1, null));
+                ++count;
+            }
+        }
+
+        return count;
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#replace(int, int, java.lang.String)
+     */
+    public final void replace(int position, int length, String text)  {
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#set(java.lang.String)
+     */
+    public final void set(String text) {
+        fLines.clear();
+        if (text !is null) {
+            fTextLength= text.length();
+            createLines(text, 0, 0);
+        }
+    }
+
+    /**
+     * Returns the internal data structure, a {@link List} of {@link Line}s. Used only by
+     * {@link TreeLineTracker#TreeLineTracker(ListLineTracker)}.
+     *
+     * @return the internal list of lines.
+     */
+    final List getLines() {
+        return fLines;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/MarginPainter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,322 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.MarginPainter;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.PaintEvent;
+import dwt.events.PaintListener;
+import dwt.graphics.Color;
+import dwt.graphics.GC;
+import dwt.graphics.Rectangle;
+
+
+/**
+ * Paints a vertical line (margin line) after a given column respecting the text
+ * viewer's font.
+ * <p>
+ * Clients usually instantiate and configure objects of this class.</p>
+ * <p>
+ * This class is not intended to be subclassed.</p>
+ *
+ * @since 2.1
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class MarginPainter : IPainter, PaintListener {
+
+    /** The widget of the text viewer */
+    private StyledText fTextWidget;
+
+    /** The column after which to paint the line, default value <code>80</code> */
+    private int fMarginWidth= 80;
+    /** The color in which to paint the line */
+    private Color fColor;
+    /** The line style of the line to be painted, default value <code>DWT.LINE_SOLID</code> */
+    private int fLineStyle= DWT.LINE_SOLID;
+    /** The line width of the line to be painted, default value <code>1</code> */
+    private int fLineWidth= 0; // NOTE: 0 means width is 1 but with optimized performance
+    /** The cached x-offset of the <code>fMarginWidth</code> for the current font */
+    private int fCachedWidgetX= -1;
+    /** The active state of this painter */
+    private bool fIsActive= false;
+
+    /**
+     * Creates a new painter for the given text viewer.
+     *
+     * @param textViewer the text viewer
+     */
+    public this(ITextViewer textViewer) {
+        fTextWidget= textViewer.getTextWidget();
+    }
+
+    /**
+     * Sets the column after which to draw the margin line.
+     *
+     * @param width the column
+     */
+    public void setMarginRulerColumn(int width) {
+        fMarginWidth= width;
+        initialize();
+    }
+
+    /**
+     * Sets the line style of the margin line.
+     *
+     * @param lineStyle a <code>DWT</code> style constant describing the line style
+     */
+    public void setMarginRulerStyle(int lineStyle) {
+        fLineStyle= lineStyle;
+    }
+
+    /**
+     * Sets the line width of the margin line.
+     *
+     * @param lineWidth the line width
+     */
+    public void setMarginRulerWidth(int lineWidth) {
+        if (lineWidth is 1)
+            lineWidth= 0; // NOTE: 0 means width is 1 but with optimized performance
+        fLineWidth= lineWidth;
+    }
+
+    /**
+     * Sets the color of the margin line. Must be called before <code>paint</code> is called the first time.
+     *
+     * @param color the color
+     */
+    public void setMarginRulerColor(Color color) {
+        fColor= color;
+    }
+
+    /**
+     * Initializes this painter, by flushing and recomputing all caches and causing
+     * the widget to be redrawn. Must be called explicitly when font of text widget changes.
+     */
+    public void initialize() {
+        computeWidgetX();
+        fTextWidget.redraw();
+    }
+
+    /**
+     * Computes and remembers the x-offset of the margin column for the
+     * current widget font.
+     */
+    private void computeWidgetX() {
+        GC gc= new GC(fTextWidget);
+        int pixels= gc.getFontMetrics().getAverageCharWidth();
+        gc.dispose();
+
+        fCachedWidgetX= pixels * fMarginWidth;
+    }
+
+    /*
+     * @see IPainter#deactivate(bool)
+     */
+    public void deactivate(bool redraw) {
+        if (fIsActive) {
+            fIsActive= false;
+            fCachedWidgetX= -1;
+            fTextWidget.removePaintListener(this);
+            if (redraw)
+                fTextWidget.redraw();
+        }
+    }
+
+    /*
+     * @see IPainter#dispose()
+     */
+    public void dispose() {
+        fTextWidget= null;
+    }
+
+    /*
+     * @see IPainter#paint(int)
+     */
+    public void paint(int reason) {
+        if (!fIsActive) {
+            fIsActive= true;
+            fTextWidget.addPaintListener(this);
+            if (fCachedWidgetX is -1)
+                computeWidgetX();
+            fTextWidget.redraw();
+        } else if (CONFIGURATION is reason || INTERNAL is reason)
+            fTextWidget.redraw();
+    }
+
+    /*
+     * @see dwt.events.PaintListener#paintControl(dwt.events.PaintEvent)
+     */
+    public void paintControl(PaintEvent e) {
+        if (fTextWidget !is null) {
+            int x= fCachedWidgetX - fTextWidget.getHorizontalPixel();
+            if (x >= 0) {
+                Rectangle area= fTextWidget.getClientArea();
+                e.gc.setForeground(fColor);
+                e.gc.setLineStyle(fLineStyle);
+                e.gc.setLineWidth(fLineWidth);
+                e.gc.drawLine(x, 0, x, area.height);
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IPainter#setPositionManager(dwtx.jface.text.IPaintPositionManager)
+     */
+    public void setPositionManager(IPaintPositionManager manager) {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/MarkSelection.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,216 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.MarkSelection;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Default implementation of {@link dwtx.jface.text.IMarkSelection}.
+ *
+ * @since 2.0
+ */
+public class MarkSelection : IMarkSelection {
+
+    /** The marked document. */
+    private const IDocument fDocument;
+    /** The offset of the mark selection. */
+    private const int fOffset;
+    /** The length of the mark selection. */
+    private const int fLength;
+
+    /**
+     * Creates a MarkSelection.
+     *
+     * @param document the marked document
+     * @param offset the offset of the mark
+     * @param length the length of the mark, may be negative if caret before offset
+     */
+    public this(IDocument document, int offset, int length) {
+        fDocument= document;
+        fOffset= offset;
+        fLength= length;
+    }
+
+    /*
+     * @see IMarkSelection#getDocument()
+     */
+    public IDocument getDocument() {
+        return fDocument;
+    }
+
+    /*
+     * @see IMarkSelection#getOffset()
+     */
+    public int getOffset() {
+        return fOffset;
+    }
+
+    /*
+     * @see IMarkSelection#getLength()
+     */
+    public int getLength() {
+        return fLength;
+    }
+
+    /*
+     * @see ISelection#isEmpty()
+     */
+    public bool isEmpty() {
+        return fLength is 0;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/PaintManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,528 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.PaintManager;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+import dwt.custom.StyledText;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.widgets.Control;
+import dwtx.jface.viewers.ISelectionChangedListener;
+import dwtx.jface.viewers.ISelectionProvider;
+import dwtx.jface.viewers.SelectionChangedEvent;
+
+
+/**
+ * Manages the {@link dwtx.jface.text.IPainter} object registered with an
+ * {@link dwtx.jface.text.ITextViewer}.
+ * <p>
+ * Clients usually instantiate and configure objects of this type.</p>
+ *
+ * @since 2.1
+ */
+public final class PaintManager : KeyListener, MouseListener, ISelectionChangedListener, ITextListener, ITextInputListener {
+
+    /**
+     * Position updater used by the position manager. This position updater differs from the default position
+     * updater in that it extends a position when an insertion happens at the position's offset and right behind
+     * the position.
+     */
+    static class PaintPositionUpdater : DefaultPositionUpdater {
+
+        /**
+         * Creates the position updater for the given category.
+         *
+         * @param category the position category
+         */
+        protected this(String category) {
+            super(category);
+        }
+
+        /**
+         * If an insertion happens at a position's offset, the
+         * position is extended rather than shifted. Also, if something is added
+         * right behind the end of the position, the position is extended rather
+         * than kept stable.
+         */
+        protected void adaptToInsert() {
+
+            int myStart= fPosition.offset;
+            int myEnd=   fPosition.offset + fPosition.length;
+            myEnd= Math.max(myStart, myEnd);
+
+            int yoursStart= fOffset;
+            int yoursEnd=   fOffset + fReplaceLength;// - 1;
+            yoursEnd= Math.max(yoursStart, yoursEnd);
+
+            if (myEnd < yoursStart)
+                return;
+
+            if (myStart <= yoursStart)
+                fPosition.length += fReplaceLength;
+            else
+                fPosition.offset += fReplaceLength;
+        }
+    }
+
+    /**
+     * The paint position manager used by this paint manager. The paint position
+     * manager is installed on a single document and control the creation/disposed
+     * and updating of a position category that will be used for managing positions.
+     */
+    static class PositionManager : IPaintPositionManager {
+
+//      /** The document this position manager works on */
+        private IDocument fDocument;
+        /** The position updater used for the managing position category */
+        private IPositionUpdater fPositionUpdater;
+        /** The managing position category */
+        private String fCategory;
+
+        /**
+         * Creates a new position manager. Initializes the managing
+         * position category using its class name and its hash value.
+         */
+        public this() {
+            fCategory= this.classinfo.name ~ Integer.toString(toHash());
+            fPositionUpdater= new PaintPositionUpdater(fCategory);
+        }
+
+        /**
+         * Installs this position manager in the given document. The position manager stays
+         * active until <code>uninstall</code> or <code>dispose</code>
+         * is called.
+         *
+         * @param document the document to be installed on
+         */
+        public void install(IDocument document) {
+            fDocument= document;
+            fDocument.addPositionCategory(fCategory);
+            fDocument.addPositionUpdater(fPositionUpdater);
+        }
+
+        /**
+         * Disposes this position manager. The position manager is automatically
+         * removed from the document it has previously been installed
+         * on.
+         */
+        public void dispose() {
+            uninstall(fDocument);
+        }
+
+        /**
+         * Uninstalls this position manager form the given document. If the position
+         * manager has no been installed on this document, this method is without effect.
+         *
+         * @param document the document form which to uninstall
+         */
+        public void uninstall(IDocument document) {
+            if (document is fDocument && document !is null) {
+                try {
+                    fDocument.removePositionUpdater(fPositionUpdater);
+                    fDocument.removePositionCategory(fCategory);
+                } catch (BadPositionCategoryException x) {
+                    // should not happen
+                }
+                fDocument= null;
+            }
+        }
+
+        /*
+         * @see IPositionManager#addManagedPosition(Position)
+         */
+        public void managePosition(Position position) {
+            try {
+                fDocument.addPosition(fCategory, position);
+            } catch (BadPositionCategoryException x) {
+                // should not happen
+            } catch (BadLocationException x) {
+                // should not happen
+            }
+        }
+
+        /*
+         * @see IPositionManager#removeManagedPosition(Position)
+         */
+        public void unmanagePosition(Position position) {
+            try {
+                fDocument.removePosition(fCategory, position);
+            } catch (BadPositionCategoryException x) {
+                // should not happen
+            }
+        }
+    }
+
+
+    /** The painters managed by this paint manager. */
+    private List fPainters;
+    /** The position manager used by this paint manager */
+    private PositionManager fManager;
+    /** The associated text viewer */
+    private ITextViewer fTextViewer;
+
+    /**
+     * Creates a new paint manager for the given text viewer.
+     *
+     * @param textViewer the text viewer associated to this newly created paint manager
+     */
+    public this(ITextViewer textViewer) {
+        fPainters= new ArrayList(2);
+        fTextViewer= textViewer;
+    }
+
+
+    /**
+     * Adds the given painter to the list of painters managed by this paint manager.
+     * If the painter is already registered with this paint manager, this method is
+     * without effect.
+     *
+     * @param painter the painter to be added
+     */
+    public void addPainter(IPainter painter) {
+        if (!fPainters.contains(cast(Object)painter)) {
+            fPainters.add(cast(Object)painter);
+            if (fPainters.size() is 1)
+                install();
+            painter.setPositionManager(fManager);
+            painter.paint(IPainter.INTERNAL);
+        }
+    }
+
+    /**
+     * Removes the given painter from the list of painters managed by this
+     * paint manager. If the painter has not previously been added to this
+     * paint manager, this method is without effect.
+     *
+     * @param painter the painter to be removed
+     */
+    public void removePainter(IPainter painter) {
+        if (fPainters.remove(cast(Object)painter)) {
+            painter.deactivate(true);
+            painter.setPositionManager(null);
+        }
+        if (fPainters.size() is 0)
+            dispose();
+    }
+
+    /**
+     * Installs/activates this paint manager. Is called as soon as the
+     * first painter is to be managed by this paint manager.
+     */
+    private void install() {
+
+        fManager= new PositionManager();
+        if (fTextViewer.getDocument() !is null)
+            fManager.install(fTextViewer.getDocument());
+
+        fTextViewer.addTextInputListener(this);
+
+        addListeners();
+    }
+
+    /**
+     * Installs our listener set on the text viewer and the text widget,
+     * respectively.
+     */
+    private void addListeners() {
+        ISelectionProvider provider= fTextViewer.getSelectionProvider();
+        provider.addSelectionChangedListener(this);
+
+        fTextViewer.addTextListener(this);
+
+        StyledText text= fTextViewer.getTextWidget();
+        text.addKeyListener(this);
+        text.addMouseListener(this);
+    }
+
+    /**
+     * Disposes this paint manager. The paint manager uninstalls itself
+     * and clears all registered painters. This method is also called when the
+     * last painter is removed from the list of managed painters.
+     */
+    public void dispose() {
+
+        if (fManager !is null) {
+            fManager.dispose();
+            fManager= null;
+        }
+
+        for (Iterator e = fPainters.iterator(); e.hasNext();)
+            (cast(IPainter) e.next()).dispose();
+        fPainters.clear();
+
+        fTextViewer.removeTextInputListener(this);
+
+        removeListeners();
+    }
+
+    /**
+     * Removes our set of listeners from the text viewer and widget,
+     * respectively.
+     */
+    private void removeListeners() {
+        ISelectionProvider provider= fTextViewer.getSelectionProvider();
+        if (provider !is null)
+            provider.removeSelectionChangedListener(this);
+
+        fTextViewer.removeTextListener(this);
+
+        StyledText text= fTextViewer.getTextWidget();
+        if (text !is null && !text.isDisposed()) {
+            text.removeKeyListener(this);
+            text.removeMouseListener(this);
+        }
+    }
+
+    /**
+     * Triggers all registered painters for the given reason.
+     *
+     * @param reason the reason
+     * @see IPainter
+     */
+    private void paint(int reason) {
+        for (Iterator e = fPainters.iterator(); e.hasNext();)
+            (cast(IPainter) e.next()).paint(reason);
+    }
+
+    /*
+     * @see KeyListener#keyPressed(KeyEvent)
+     */
+    public void keyPressed(KeyEvent e) {
+        paint(IPainter.KEY_STROKE);
+    }
+
+    /*
+     * @see KeyListener#keyReleased(KeyEvent)
+     */
+    public void keyReleased(KeyEvent e) {
+    }
+
+    /*
+     * @see MouseListener#mouseDoubleClick(MouseEvent)
+     */
+    public void mouseDoubleClick(MouseEvent e) {
+    }
+
+    /*
+     * @see MouseListener#mouseDown(MouseEvent)
+     */
+    public void mouseDown(MouseEvent e) {
+        paint(IPainter.MOUSE_BUTTON);
+    }
+
+    /*
+     * @see MouseListener#mouseUp(MouseEvent)
+     */
+    public void mouseUp(MouseEvent e) {
+    }
+
+    /*
+     * @see ISelectionChangedListener#selectionChanged(SelectionChangedEvent)
+     */
+    public void selectionChanged(SelectionChangedEvent event) {
+        paint(IPainter.SELECTION);
+    }
+
+    /*
+     * @see ITextListener#textChanged(TextEvent)
+     */
+    public void textChanged(TextEvent event) {
+
+        if (!event.getViewerRedrawState())
+            return;
+
+        Control control= fTextViewer.getTextWidget();
+        if (control !is null) {
+            control.getDisplay().asyncExec(new class()  Runnable {
+                public void run() {
+                    if (fTextViewer !is null)
+                        paint(IPainter.TEXT_CHANGE);
+                }
+            });
+        }
+    }
+
+    /*
+     * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument)
+     */
+    public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
+        if (oldInput !is null) {
+            for (Iterator e = fPainters.iterator(); e.hasNext();)
+                (cast(IPainter) e.next()).deactivate(false);
+            fManager.uninstall(oldInput);
+            removeListeners();
+        }
+    }
+
+    /*
+     * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument)
+     */
+    public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+        if (newInput !is null) {
+            fManager.install(newInput);
+            paint(IPainter.TEXT_CHANGE);
+            addListeners();
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/Position.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,342 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.Position;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Positions describe text ranges of a document. Positions are adapted to
+ * changes applied to that document. The text range is specified by an offset
+ * and a length. Positions can be marked as deleted. Deleted positions are
+ * considered to no longer represent a valid text range in the managing
+ * document.
+ * <p>
+ * Positions attached to documents are usually updated by position updaters.
+ * Because position updaters are freely definable and because of the frequency
+ * in which they are used, the fields of a position are made publicly
+ * accessible. Clients other than position updaters are not allowed to access
+ * these public fields.
+ * </p>
+ * <p>
+ * Positions cannot be used as keys in hash tables as they override
+ * <code>equals</code> and <code>hashCode</code> as they would be value
+ * objects.
+ * </p>
+ *
+ * @see dwtx.jface.text.IDocument
+ */
+public class Position {
+
+    /** The offset of the position */
+    public int offset;
+    /** The length of the position */
+    public int length;
+    /** Indicates whether the position has been deleted */
+    public bool isDeleted_;
+
+    /**
+     * Creates a new position with the given offset and length 0.
+     *
+     * @param offset the position offset, must be >= 0
+     */
+    public this(int offset) {
+        this(offset, 0);
+    }
+
+    /**
+     * Creates a new position with the given offset and length.
+     *
+     * @param offset the position offset, must be >= 0
+     * @param length the position length, must be >= 0
+     */
+    public this(int offset, int length) {
+        Assert.isTrue(offset >= 0);
+        Assert.isTrue(length >= 0);
+        this.offset= offset;
+        this.length= length;
+    }
+
+    /**
+     * Creates a new, not initialized position.
+     */
+    protected this() {
+    }
+
+     /*
+     * @see java.lang.Object#hashCode()
+     */
+    public override hash_t toHash() {
+        int deleted= isDeleted_ ? 0 : 1;
+        return (offset << 24) | (length << 16) | deleted;
+     }
+
+    /**
+     * Marks this position as deleted.
+     */
+    public void delete_() {
+        isDeleted_= true;
+    }
+
+    /**
+     * Marks this position as not deleted.
+     *
+     * @since 2.0
+     */
+    public void undelete() {
+        isDeleted_= false;
+    }
+
+    /*
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public override int opEquals(Object other) {
+        if ( auto rp = cast(Position)other ) {
+            return (rp.offset is offset) && (rp.length is length);
+        }
+        return super.opEquals(other);
+    }
+
+    /**
+     * Returns the length of this position.
+     *
+     * @return the length of this position
+     */
+    public int getLength() {
+        return length;
+    }
+
+    /**
+     * Returns the offset of this position.
+     *
+     * @return the offset of this position
+     */
+    public int getOffset() {
+        return offset;
+    }
+
+    /**
+     * Checks whether the given index is inside
+     * of this position's text range.
+     *
+     * @param index the index to check
+     * @return <code>true</code> if <code>index</code> is inside of this position
+     */
+    public bool includes(int index) {
+
+        if (isDeleted_)
+            return false;
+
+        return (this.offset <= index) && (index < this.offset + length);
+    }
+
+    /**
+     * Checks whether the intersection of the given text range
+     * and the text range represented by this position is empty
+     * or not.
+     *
+     * @param rangeOffset the offset of the range to check
+     * @param rangeLength the length of the range to check
+     * @return <code>true</code> if intersection is not empty
+     */
+    public bool overlapsWith(int rangeOffset, int rangeLength) {
+
+        if (isDeleted_)
+            return false;
+
+        int end= rangeOffset + rangeLength;
+        int thisEnd= this.offset + this.length;
+
+        if (rangeLength > 0) {
+            if (this.length > 0)
+                return this.offset < end && rangeOffset < thisEnd;
+            return  rangeOffset <= this.offset && this.offset < end;
+        }
+
+        if (this.length > 0)
+            return this.offset <= rangeOffset && rangeOffset < thisEnd;
+        return this.offset is rangeOffset;
+    }
+
+    /**
+     * Returns whether this position has been deleted or not.
+     *
+     * @return <code>true</code> if position has been deleted
+     */
+    public bool isDeleted() {
+        return isDeleted_;
+    }
+
+    /**
+     * Changes the length of this position to the given length.
+     *
+     * @param length the new length of this position
+     */
+    public void setLength(int length) {
+        Assert.isTrue(length >= 0);
+        this.length= length;
+    }
+
+    /**
+     * Changes the offset of this position to the given offset.
+     *
+     * @param offset the new offset of this position
+     */
+    public void setOffset(int offset) {
+        Assert.isTrue(offset >= 0);
+        this.offset= offset;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/PropagatingFontFieldEditor.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,290 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.PropagatingFontFieldEditor;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+
+
+import dwt.graphics.FontData;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Label;
+import dwtx.jface.preference.FontFieldEditor;
+import dwtx.jface.preference.IPreferenceStore;
+import dwtx.jface.preference.PreferenceConverter;
+import dwtx.jface.util.IPropertyChangeListener;
+import dwtx.jface.util.PropertyChangeEvent;
+
+
+/**
+ * This font field editor implements chaining between a source preference
+ * store and a target preference store. Any time the source preference
+ * store changes, the change is propagated to the target store. Propagation
+ * means that the actual value stored in the source store is set as default
+ * value in the target store. If the target store does not contain a value
+ * other than the default value, the new default value is immediately
+ * effective.
+ *
+ * @see FontFieldEditor
+ * @since 2.0
+ * @deprecated since 3.0 not longer in use, no longer supported
+ */
+public class PropagatingFontFieldEditor : FontFieldEditor {
+
+    /** The editor's parent widget */
+    private Composite fParent;
+    /** The representation of the default font choice */
+    private String fDefaultFontLabel;
+
+    /**
+     * Creates a new font field editor with the given parameters.
+     *
+     * @param name the editor's name
+     * @param labelText the text shown as editor description
+     * @param parent the editor's parent widget
+     * @param defaultFontLabel the label shown in the editor value field when the default value should be taken
+     */
+    public this(String name, String labelText, Composite parent, String defaultFontLabel) {
+        super(name, labelText, parent);
+        fParent= parent;
+        fDefaultFontLabel= defaultFontLabel is null ? "" : defaultFontLabel; //$NON-NLS-1$
+    }
+
+    /*
+     * @see FontFieldEditor#doLoad()
+     */
+    protected void doLoad() {
+        if (getPreferenceStore().isDefault(getPreferenceName()))
+            loadDefault();
+        super.doLoad();
+        checkForDefault();
+    }
+
+    /*
+     * @see FontFieldEditor#doLoadDefault()
+     */
+    protected void doLoadDefault() {
+        super.doLoadDefault();
+        checkForDefault();
+    }
+
+    /**
+     * Checks whether this editor presents the default value "inherited"
+     * from the workbench rather than its own font.
+     */
+    private void checkForDefault() {
+        if (presentsDefaultValue()) {
+            Control c= getValueControl(fParent);
+            if ( cast(Label)c )
+                (cast(Label) c).setText(fDefaultFontLabel);
+        }
+    }
+
+    /**
+     * Propagates the font set in the source store to the
+     * target store using the given keys.
+     *
+     * @param source the store from which to read the text font
+     * @param sourceKey the key under which the font can be found
+     * @param target the store to which to propagate the font
+     * @param targetKey the key under which to store the font
+     */
+    private static void propagateFont(IPreferenceStore source, String sourceKey, IPreferenceStore target, String targetKey) {
+        FontData fd= PreferenceConverter.getFontData(source, sourceKey);
+        if (fd !is null) {
+            bool isDefault= target.isDefault(targetKey); // save old state!
+            PreferenceConverter.setDefault(target, targetKey, fd);
+            if (isDefault) {
+                // restore old state
+                target.setToDefault(targetKey);
+            }
+        }
+    }
+
+    /**
+     * Starts the propagation of the font preference stored in the source preference
+     * store under the source key to the target preference store using the target
+     * preference key.
+     *
+     * @param source the source preference store
+     * @param sourceKey the key to be used in the source preference store
+     * @param target the target preference store
+     * @param targetKey the key to be used in the target preference store
+     */
+    public static void startPropagate(IPreferenceStore source, String sourceKey, IPreferenceStore target, String targetKey) {
+        source.addPropertyChangeListener(new class(source,sourceKey,target,targetKey)  IPropertyChangeListener {
+            IPreferenceStore source_;
+            String sourceKey_;
+            IPreferenceStore target_;
+            String targetKey_;
+            this(IPreferenceStore a, String b, IPreferenceStore c, String d){
+                source_=a;
+                sourceKey_=b;
+                target_=c;
+                targetKey_=d;
+            }
+            public void propertyChange(PropertyChangeEvent event) {
+                if (sourceKey_.equals(event.getProperty()))
+                    propagateFont(source_, sourceKey_, target_, targetKey_);
+            }
+        });
+
+        propagateFont(source, sourceKey, target, targetKey);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/RegExMessages.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.RegExMessages;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+// import dwt.dwthelper.MissingResourceException;
+import dwt.dwthelper.ResourceBundle;
+
+
+/**
+ * RegEx messages. Helper class to get NLSed messages.
+ *
+ * @since 3.4
+ */
+final class RegExMessages {
+
+    //private static const String RESOURCE_BUNDLE= RegExMessages.classinfo.getName();
+    private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+    static this() {
+        fgResourceBundle = ResourceBundle.getBundle(
+            getImportData!("dwtx.jface.text.RegExMessages.properties"));
+    }
+
+    private this() {
+        // Do not instantiate
+    }
+
+    public static String getString(String key) {
+        try {
+            return fgResourceBundle.getString(key);
+        } catch (MissingResourceException e) {
+            return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$
+        }
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/Region.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,220 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.Region;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+import tango.text.convert.Format;
+
+
+/**
+ * The default implementation of the {@link dwtx.jface.text.IRegion} interface.
+ */
+public class Region : IRegion {
+
+    /** The region offset */
+    private int fOffset;
+    /** The region length */
+    private int fLength;
+
+    /**
+     * Create a new region.
+     *
+     * @param offset the offset of the region
+     * @param length the length of the region
+     */
+    public this(int offset, int length) {
+        fOffset= offset;
+        fLength= length;
+    }
+
+    /*
+     * @see dwtx.jface.text.IRegion#getLength()
+     */
+    public int getLength() {
+        return fLength;
+    }
+
+    /*
+     * @see dwtx.jface.text.IRegion#getOffset()
+     */
+    public int getOffset() {
+        return fOffset;
+    }
+
+    /*
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public bool equals(Object o) {
+        if ( cast(IRegion)o ) {
+            IRegion r= cast(IRegion) o;
+            return r.getOffset() is fOffset && r.getLength() is fLength;
+        }
+        return false;
+    }
+
+    /*
+     * @see java.lang.Object#hashCode()
+     */
+    public override hash_t toHash() {
+        return (fOffset << 24) | (fLength << 16);
+    }
+
+    /*
+     * @see java.lang.Object#toString()
+     */
+    public override String toString() {
+        return Format("[{}+{}]", fOffset, fLength ); //$NON-NLS-1$
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/RewriteSessionEditProcessor.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,260 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.RewriteSessionEditProcessor;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.text.edits.CopyTargetEdit;
+import dwtx.text.edits.DeleteEdit;
+import dwtx.text.edits.InsertEdit;
+import dwtx.text.edits.MalformedTreeException;
+import dwtx.text.edits.MoveTargetEdit;
+import dwtx.text.edits.ReplaceEdit;
+import dwtx.text.edits.TextEdit;
+import dwtx.text.edits.TextEditProcessor;
+import dwtx.text.edits.TextEditVisitor;
+import dwtx.text.edits.UndoEdit;
+
+/**
+ * A text edit processor that brackets the application of edits into a document rewrite session.
+ *
+ * @since 3.3
+ */
+public final class RewriteSessionEditProcessor : TextEditProcessor {
+    /** The threshold for <em>large</em> text edits. */
+    private static const int THRESHOLD= 1000;
+
+    /**
+     * Text edit visitor that estimates the compound size of an edit tree in characters.
+     */
+    private static final class SizeVisitor : TextEditVisitor {
+        int fSize= 0;
+
+        public bool visit(CopyTargetEdit edit) {
+            fSize += edit.getLength();
+            return super.visit(edit);
+        }
+
+        public bool visit(DeleteEdit edit) {
+            fSize += edit.getLength();
+            return super.visit(edit);
+        }
+
+        public bool visit(InsertEdit edit) {
+            fSize += edit.getText().length();
+            return super.visit(edit);
+        }
+
+        public bool visit(MoveTargetEdit edit) {
+            fSize += edit.getLength();
+            return super.visit(edit);
+        }
+
+        public bool visit(ReplaceEdit edit) {
+            fSize += Math.max(edit.getLength(), edit.getText().length());
+            return super.visit(edit);
+        }
+    }
+
+    /**
+     * Constructs a new edit processor for the given document.
+     *
+     * @param document the document to manipulate
+     * @param root the root of the text edit tree describing the modifications. By passing a text
+     *        edit a a text edit processor the ownership of the edit is transfered to the text edit
+     *        processors. Clients must not modify the edit (e.g adding new children) any longer.
+     * @param style {@link TextEdit#NONE}, {@link TextEdit#CREATE_UNDO} or
+     *        {@link TextEdit#UPDATE_REGIONS})
+     */
+    public this(IDocument document, TextEdit root, int style) {
+        super(document, root, style);
+    }
+
+    /*
+     * @see dwtx.text.edits.TextEditProcessor#performEdits()
+     */
+    public UndoEdit performEdits()  {
+        IDocument document= getDocument();
+        if (!( cast(IDocumentExtension4)document ))
+            return super.performEdits();
+
+        IDocumentExtension4 extension= cast(IDocumentExtension4) document;
+        bool isLargeEdit= isLargeEdit(getRoot());
+        DocumentRewriteSessionType type= isLargeEdit ? DocumentRewriteSessionType.UNRESTRICTED : DocumentRewriteSessionType.UNRESTRICTED_SMALL;
+
+        DocumentRewriteSession session= extension.startRewriteSession(type);
+        try {
+            return super.performEdits();
+        } finally {
+            extension.stopRewriteSession(session);
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if the passed edit is considered <em>large</em>,
+     * <code>false</code> otherwise.
+     *
+     * @param edit the edit to check
+     * @return <code>true</code> if <code>edit</code> is considered <em>large</em>,
+     *         <code>false</code> otherwise
+     * @since 3.3
+     */
+    public static bool isLargeEdit(TextEdit edit) {
+        SizeVisitor sizeVisitor= new SizeVisitor();
+        edit.accept(sizeVisitor);
+        return sizeVisitor.fSize > THRESHOLD;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/SequentialRewriteTextStore.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,417 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.SequentialRewriteTextStore;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+/**
+ * A text store that optimizes a given source text store for sequential rewriting.
+ * While rewritten it keeps a list of replace command that serve as patches for
+ * the source store. Only on request, the source store is indeed manipulated
+ * by applying the patch commands to the source text store.
+ *
+ * @since 2.0
+ * @deprecated since 3.3 as {@link GapTextStore} performs better even for sequential rewrite scenarios
+ */
+public class SequentialRewriteTextStore : ITextStore {
+
+    /**
+     * A buffered replace command.
+     */
+    private static class Replace {
+        public int newOffset;
+        public const int offset;
+        public const int length;
+        public const String text;
+
+        public this(int offset, int newOffset, int length, String text) {
+            this.newOffset= newOffset;
+            this.offset= offset;
+            this.length= length;
+            this.text= text;
+        }
+    }
+
+    /** The list of buffered replacements. */
+    private LinkedList fReplaceList;
+    /** The source text store */
+    private ITextStore fSource;
+    /** A flag to enforce sequential access. */
+    private static const bool ASSERT_SEQUENTIALITY= false;
+
+
+    /**
+     * Creates a new sequential rewrite store for the given source store.
+     *
+     * @param source the source text store
+     */
+    public this(ITextStore source) {
+        fReplaceList= new LinkedList();
+        fSource= source;
+    }
+
+    /**
+     * Returns the source store of this rewrite store.
+     *
+     * @return  the source store of this rewrite store
+     */
+    public ITextStore getSourceStore() {
+        commit();
+        return fSource;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#replace(int, int, java.lang.String)
+     */
+    public void replace(int offset, int length, String text) {
+        if (text is null)
+            text= ""; //$NON-NLS-1$
+
+        if (fReplaceList.size() is 0) {
+            fReplaceList.add(new Replace(offset, offset, length, text));
+
+        } else {
+            Replace firstReplace= cast(Replace) fReplaceList.getFirst();
+            Replace lastReplace= cast(Replace) fReplaceList.getLast();
+
+            // backward
+            if (offset + length <= firstReplace.newOffset) {
+                int delta= text.length - length;
+                if (delta !is 0) {
+                    for (Iterator i= fReplaceList.iterator(); i.hasNext(); ) {
+                        Replace replace= cast(Replace) i.next();
+                        replace.newOffset += delta;
+                    }
+                }
+
+                fReplaceList.addFirst(new Replace(offset, offset, length, text));
+
+            // forward
+            } else if (offset >= lastReplace.newOffset + lastReplace.text.length) {
+                int delta= getDelta(lastReplace);
+                fReplaceList.add(new Replace(offset - delta, offset, length, text));
+
+            } else if (ASSERT_SEQUENTIALITY) {
+                throw new IllegalArgumentException(null);
+
+            } else {
+                commit();
+                fSource.replace(offset, length, text);
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#set(java.lang.String)
+     */
+    public void set(String text) {
+        fSource.set(text);
+        fReplaceList.clear();
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#get(int, int)
+     */
+    public String get(int offset, int length) {
+
+        if (fReplaceList.isEmpty())
+            return fSource.get(offset, length);
+
+
+        Replace firstReplace= cast(Replace) fReplaceList.getFirst();
+        Replace lastReplace= cast(Replace) fReplaceList.getLast();
+
+        // before
+        if (offset + length <= firstReplace.newOffset) {
+            return fSource.get(offset, length);
+
+            // after
+        } else if (offset >= lastReplace.newOffset + lastReplace.text.length) {
+            int delta= getDelta(lastReplace);
+            return fSource.get(offset - delta, length);
+
+        } else if (ASSERT_SEQUENTIALITY) {
+            throw new IllegalArgumentException(null);
+
+        } else {
+
+            int delta= 0;
+            for (Iterator i= fReplaceList.iterator(); i.hasNext(); ) {
+                Replace replace= cast(Replace) i.next();
+
+                if (offset + length < replace.newOffset) {
+                    return fSource.get(offset - delta, length);
+
+                } else if (offset >= replace.newOffset && offset + length <= replace.newOffset + replace.text.length) {
+                    return replace.text.substring(offset - replace.newOffset, offset - replace.newOffset + length);
+
+                } else if (offset >= replace.newOffset + replace.text.length) {
+                    delta= getDelta(replace);
+                    continue;
+
+                } else {
+                    commit();
+                    return fSource.get(offset, length);
+                }
+            }
+
+            return fSource.get(offset - delta, length);
+        }
+
+    }
+
+    /**
+     * Returns the difference between the offset in the source store and the "same" offset in the
+     * rewrite store after the replace operation.
+     *
+     * @param replace the replace command
+     * @return the difference
+     */
+    private static final int getDelta(Replace replace) {
+        return replace.newOffset - replace.offset + replace.text.length() - replace.length;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#get(int)
+     */
+    public char get(int offset) {
+        if (fReplaceList.isEmpty())
+            return fSource.get(offset);
+
+        Replace firstReplace= cast(Replace) fReplaceList.getFirst();
+        Replace lastReplace= cast(Replace) fReplaceList.getLast();
+
+        // before
+        if (offset < firstReplace.newOffset) {
+            return fSource.get(offset);
+
+            // after
+        } else if (offset >= lastReplace.newOffset + lastReplace.text.length()) {
+            int delta= getDelta(lastReplace);
+            return fSource.get(offset - delta);
+
+        } else if (ASSERT_SEQUENTIALITY) {
+            throw new IllegalArgumentException(null);
+
+        } else {
+
+            int delta= 0;
+            for (Iterator i= fReplaceList.iterator(); i.hasNext(); ) {
+                Replace replace= cast(Replace) i.next();
+
+                if (offset < replace.newOffset)
+                    return fSource.get(offset - delta);
+
+                else if (offset < replace.newOffset + replace.text.length())
+                    return replace.text.charAt(offset - replace.newOffset);
+
+                delta= getDelta(replace);
+            }
+
+            return fSource.get(offset - delta);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#getLength()
+     */
+    public int getLength() {
+        if (fReplaceList.isEmpty())
+            return fSource.getLength();
+
+        Replace lastReplace= cast(Replace) fReplaceList.getLast();
+        return fSource.getLength() + getDelta(lastReplace);
+    }
+
+    /**
+     * Disposes this rewrite store.
+     */
+    public void dispose() {
+        fReplaceList= null;
+        fSource= null;
+    }
+
+    /**
+     * Commits all buffered replace commands.
+     */
+    private void commit() {
+
+        if (fReplaceList.isEmpty())
+            return;
+
+        StringBuffer buffer= new StringBuffer();
+
+        int delta= 0;
+        for (Iterator i= fReplaceList.iterator(); i.hasNext(); ) {
+            Replace replace= cast(Replace) i.next();
+
+            int offset= buffer.length() - delta;
+            buffer.append(fSource.get(offset, replace.offset - offset));
+            buffer.append(replace.text);
+            delta= getDelta(replace);
+        }
+
+        int offset= buffer.length() - delta;
+        buffer.append(fSource.get(offset, fSource.getLength() - offset));
+
+        fSource.set(buffer.toString());
+        fReplaceList.clear();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/SlaveDocumentEvent.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.SlaveDocumentEvent;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A slave document event represents a master document event as a slave-relative
+ * document event. It also carries the master document event.
+ */
+public class SlaveDocumentEvent : DocumentEvent {
+
+    /** The master document event */
+    private DocumentEvent fMasterEvent;
+
+    /**
+     * Creates a new slave document event.
+     *
+     * @param doc the slave document
+     * @param offset the offset in the slave document
+     * @param length the length in the slave document
+     * @param text the substitution text
+     * @param masterEvent the master document event
+     */
+    public this(IDocument doc, int offset, int length, String text, DocumentEvent masterEvent) {
+        super(doc, offset, length, text);
+        fMasterEvent= masterEvent;
+    }
+
+    /**
+     * Returns this event's master event.
+     *
+     * @return this event's master event
+     */
+    public DocumentEvent getMasterEvent() {
+        return fMasterEvent;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/TabsToSpacesConverter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,241 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.TabsToSpacesConverter;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Auto edit strategy that converts tabs into spaces.
+ * <p>
+ * Clients usually instantiate and configure this class but
+ * can also extend it in their own subclass.
+ * </p>
+ * 
+ * @since 3.3
+ */
+public class TabsToSpacesConverter : IAutoEditStrategy {
+
+    private int fTabRatio;
+    private ILineTracker fLineTracker;
+
+
+    public void setNumberOfSpacesPerTab(int ratio) {
+        fTabRatio= ratio;
+    }
+
+    public void setLineTracker(ILineTracker lineTracker) {
+        fLineTracker= lineTracker;
+    }
+
+    private int insertTabString(StringBuffer buffer, int offsetInLine) {
+
+        if (fTabRatio is 0)
+            return 0;
+
+        int remainder= offsetInLine % fTabRatio;
+        remainder= fTabRatio - remainder;
+        for (int i= 0; i < remainder; i++)
+            buffer.append(' ');
+        return remainder;
+    }
+
+    public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
+        String text= command.text;
+        if (text is null)
+            return;
+
+        int index= text.indexOf('\t');
+        if (index > -1) {
+
+            StringBuffer buffer= new StringBuffer();
+
+            fLineTracker.set(command.text);
+            int lines= fLineTracker.getNumberOfLines();
+
+            try {
+
+                for (int i= 0; i < lines; i++) {
+
+                    int offset= fLineTracker.getLineOffset(i);
+                    int endOffset= offset + fLineTracker.getLineLength(i);
+                    String line= text.substring(offset, endOffset);
+
+                    int position= 0;
+                    if (i is 0) {
+                        IRegion firstLine= document.getLineInformationOfOffset(command.offset);
+                        position= command.offset - firstLine.getOffset();
+                    }
+
+                    int length= line.length();
+                    for (int j= 0; j < length; j++) {
+                        char c= line.charAt(j);
+                        if (c is '\t') {
+                            position += insertTabString(buffer, position);
+                        } else {
+                            buffer.append(c);
+                            ++ position;
+                        }
+                    }
+
+                }
+
+                command.text= buffer.toString();
+
+            } catch (BadLocationException x) {
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/TextAttribute.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,328 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.TextAttribute;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwt.DWT;
+import dwt.graphics.Color;
+import dwt.graphics.Font;
+
+
+/**
+ * Description of textual attributes such as color and style. Text attributes
+ * are considered value objects.
+ * <p>
+ * Clients usually instantiate object of the class.</p>
+ */
+public class TextAttribute {
+
+    /**
+     * Text attribute for strikethrough style.
+     * (value <code>1 << 29</code>).
+     * @since 3.1
+     */
+    public static const int STRIKETHROUGH= 1 << 29;
+
+    /**
+     * Text attribute for underline style.
+     * (value <code>1 << 30</code>)
+     * @since 3.1
+     */
+    public static const int UNDERLINE= 1 << 30;
+
+
+    /** Foreground color */
+    private Color foreground;
+
+    /** Background color */
+    private Color background;
+
+    /** The text style */
+    private int style;
+
+    /**
+     * The text font.
+     * @since 3.3
+     */
+    private Font font;
+
+    /**
+     * Cached hash code.
+     * @since 3.3
+     */
+    private int fHashCode;
+
+    /**
+     * Creates a text attribute with the given colors and style.
+     *
+     * @param foreground the foreground color, <code>null</code> if none
+     * @param background the background color, <code>null</code> if none
+     * @param style the style
+     */
+    public this(Color foreground, Color background, int style) {
+        this.foreground= foreground;
+        this.background= background;
+        this.style= style;
+    }
+
+    /**
+     * Creates a text attribute with the given colors and style.
+     *
+     * @param foreground the foreground color, <code>null</code> if none
+     * @param background the background color, <code>null</code> if none
+     * @param style the style
+     * @param font the font, <code>null</code> if none
+     * @since 3.3
+     */
+    public this(Color foreground, Color background, int style, Font font) {
+        this.foreground= foreground;
+        this.background= background;
+        this.style= style;
+        this.font= font;
+    }
+
+    /**
+     * Creates a text attribute for the given foreground color, no background color and
+     * with the DWT normal style.
+     *
+     * @param foreground the foreground color, <code>null</code> if none
+     */
+    public this(Color foreground) {
+        this(foreground, null, DWT.NORMAL);
+    }
+
+    /*
+     * @see Object#equals(Object)
+     */
+    public bool equals(Object object) {
+
+        if (object is this)
+            return true;
+
+        if (!( cast(TextAttribute)object ))
+            return false;
+        TextAttribute a= cast(TextAttribute)object;
+
+        return (a.style is style && equals(a.foreground, foreground) && equals(a.background, background) && equals(a.font, font));
+    }
+
+    /**
+     * Returns whether the two given objects are equal.
+     *
+     * @param o1 the first object, can be <code>null</code>
+     * @param o2 the second object, can be <code>null</code>
+     * @return <code>true</code> if the given objects are equals
+     * @since 2.0
+     */
+    private bool equals(Object o1, Object o2) {
+        if (o1 !is null)
+            return cast(bool) o1.opEquals(o2);
+        return (o2 is null);
+    }
+
+    /*
+     * @see Object#hashCode()
+     */
+     public override hash_t toHash() {
+         if (fHashCode is 0) {
+             int multiplier= 37; // some prime
+             fHashCode= 13; // some random value
+             fHashCode= multiplier * fHashCode + (font is null ? 0 : font.toHash());
+             fHashCode= multiplier * fHashCode + (background is null ? 0 : background.toHash());
+             fHashCode= multiplier * fHashCode + (foreground is null ? 0 : foreground.toHash());
+             fHashCode= multiplier * fHashCode + style;
+         }
+        return fHashCode;
+     }
+
+    /**
+     * Returns the attribute's foreground color.
+     *
+     * @return the attribute's foreground color or <code>null</code> if not set
+     */
+    public Color getForeground() {
+        return foreground;
+    }
+
+    /**
+     * Returns the attribute's background color.
+     *
+     * @return the attribute's background color or <code>null</code> if not set
+     */
+    public Color getBackground() {
+        return background;
+    }
+
+    /**
+     * Returns the attribute's style.
+     *
+     * @return the attribute's style
+     */
+    public int getStyle() {
+        return style;
+    }
+
+    /**
+     * Returns the attribute's font.
+     *
+     * @return the attribute's font or <code>null</code> if not set
+     * @since 3.3
+     */
+    public Font getFont() {
+        return font;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/TextEvent.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.TextEvent;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * This event is sent to implementers of
+ * {@link dwtx.jface.text.ITextListener}. It represents a change applied
+ * to text viewer. The change is specified as a replace command using offset,
+ * length, inserted text, and replaced text. The text viewer issues a text event
+ * after the viewer has been changed either in response to a change of the
+ * viewer's document or when the viewer's visual content has been changed. In
+ * the first case, the text event also carries the original document event.
+ * Depending on the viewer's presentation mode, the text event coordinates are
+ * different from the document event's coordinates.
+ * <p>
+ * An empty text event usually indicates a change of the viewer's redraw state.</p>
+ * <p>
+ * Clients other than text viewer's don't create instances of this class.</p>
+ *
+ * @see dwtx.jface.text.ITextListener
+ * @see dwtx.jface.text.ITextViewer
+ * @see dwtx.jface.text.DocumentEvent
+ */
+public class TextEvent {
+
+    /** Start offset of the change */
+    private int fOffset;
+    /** The length of the change */
+    private int fLength;
+    /** Inserted text */
+    private String fText;
+    /** Replaced text */
+    private String fReplacedText;
+    /** The original document event, may by null */
+    private DocumentEvent fDocumentEvent;
+    /**
+     * The redraw state of the viewer issuing this event
+     * @since 2.0
+     */
+    private bool fViewerRedrawState;
+
+    /**
+     * Creates a new <code>TextEvent</code> based on the specification.
+     *
+     * @param offset the offset
+     * @param length the length
+     * @param text the inserted text
+     * @param replacedText the replaced text
+     * @param event the associated document event or <code>null</code> if none
+     * @param viewerRedrawState the redraw state of the viewer
+     */
+    /+protected+/ this(int offset, int length, String text, String replacedText, DocumentEvent event, bool viewerRedrawState) {
+        fOffset= offset;
+        fLength= length;
+        fText= text;
+        fReplacedText= replacedText;
+        fDocumentEvent= event;
+        fViewerRedrawState= viewerRedrawState;
+    }
+
+    /**
+     * Returns the offset of the event.
+     *
+     * @return the offset of the event
+     */
+    public int getOffset() {
+        return fOffset;
+    }
+
+    /**
+     * Returns the length of the event.
+     *
+     * @return the length of the event
+     */
+    public int getLength() {
+        return fLength;
+    }
+
+    /**
+     * Returns the text of the event.
+     *
+     * @return the text of the event
+     */
+    public String getText() {
+        return fText;
+    }
+
+    /**
+     * Returns the text replaced by this event.
+     *
+     * @return the text replaced by this event
+     */
+    public String getReplacedText() {
+        return fReplacedText;
+    }
+
+    /**
+     * Returns the corresponding document event that caused the viewer change
+     *
+     * @return the corresponding document event, <code>null</code> if a visual change only
+     */
+    public DocumentEvent getDocumentEvent() {
+        return fDocumentEvent;
+    }
+
+    /**
+     * Returns the viewer's redraw state.
+     *
+     * @return <code>true</code> if the viewer's redraw state is <code>true</code>
+     * @since 2.0
+     */
+    public bool getViewerRedrawState() {
+        return fViewerRedrawState;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/TextMessages.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.TextMessages;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.dwthelper.ResourceBundle;
+import dwtx.dwtxhelper.MessageFormat;
+
+
+/**
+ * Helper class to get NLSed messages.
+ *
+ * @since 3.4
+ */
+class TextMessages {
+//     private static const String BUNDLE_NAME= "dwtx.jface.text.TextMessages"; //$NON-NLS-1$
+
+    private static const ResourceBundle RESOURCE_BUNDLE;//= ResourceBundle.getBundle(BUNDLE_NAME);
+
+    static this() {
+        RESOURCE_BUNDLE = ResourceBundle.getBundle(
+            getImportData!("dwtx.jface.text.TextMessages.properties"));
+    }
+
+
+    private this() {
+    }
+
+    public static String getString(String key) {
+        try {
+            return RESOURCE_BUNDLE.getString(key);
+        } catch (MissingResourceException e) {
+            return '!' ~ key ~ '!';
+        }
+    }
+
+    public static String getFormattedString(String key, Object[] args...) {
+        return MessageFormat.format(getString(key), args);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/TextPresentation.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,873 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.TextPresentation;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.core.Exception;
+
+import dwt.DWT;
+import dwt.custom.StyleRange;
+import dwt.custom.StyledText;
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Describes the presentation styles for a section of an indexed text such as a
+ * document or string. A text presentation defines a default style for the whole
+ * section and in addition style differences for individual subsections. Text
+ * presentations can be narrowed down to a particular result window. All methods
+ * are result window aware, i.e. ranges outside the result window are always
+ * ignored.
+ * <p>
+ * All iterators provided by a text presentation assume that they enumerate non
+ * overlapping, consecutive ranges inside the default range. Thus, all these
+ * iterators do not include the default range. The default style range must be
+ * explicitly asked for using <code>getDefaultStyleRange</code>.
+ */
+public class TextPresentation {
+
+    /**
+     * Applies the given presentation to the given text widget. Helper method.
+     *
+     * @param presentation the style information
+     * @param text the widget to which to apply the style information
+     * @since 2.0
+     */
+    public static void applyTextPresentation(TextPresentation presentation, StyledText text) {
+
+        StyleRange[] ranges= new StyleRange[presentation.getDenumerableRanges()];
+
+        int i= 0;
+        Iterator e= presentation.getAllStyleRangeIterator();
+        while (e.hasNext())
+            ranges[i++]= cast(StyleRange) e.next();
+
+        text.setStyleRanges(ranges);
+    }
+
+
+
+
+    /**
+     * Enumerates all the <code>StyleRange</code>s included in the presentation.
+     */
+    class FilterIterator : Iterator {
+
+        /** The index of the next style range to be enumerated */
+        protected int fIndex;
+        /** The upper bound of the indices of style ranges to be enumerated */
+        protected int fLength;
+        /** Indicates whether ranges similar to the default range should be enumerated */
+        protected bool fSkipDefaults;
+        /** The result window */
+        protected IRegion fWindow;
+
+        /**
+         * <code>skipDefaults</code> tells the enumeration to skip all those style ranges
+         * which define the same style as the presentation's default style range.
+         *
+         * @param skipDefaults <code>false</code> if ranges similar to the default range should be enumerated
+         */
+        protected this(bool skipDefaults) {
+
+            fSkipDefaults= skipDefaults;
+
+            fWindow= fResultWindow;
+            fIndex= getFirstIndexInWindow(fWindow);
+            fLength= getFirstIndexAfterWindow(fWindow);
+
+            if (fSkipDefaults)
+                computeIndex();
+        }
+
+        /*
+         * @see Iterator#next()
+         */
+        public Object next() {
+            try {
+                StyleRange r= cast(StyleRange) fRanges.get(fIndex++);
+                return createWindowRelativeRange(fWindow, r);
+            } catch (ArrayIndexOutOfBoundsException x) {
+                throw new NoSuchElementException(null);
+            } finally {
+                if (fSkipDefaults)
+                    computeIndex();
+            }
+        }
+
+        /*
+         * @see Iterator#hasNext()
+         */
+        public bool hasNext() {
+            return fIndex < fLength;
+        }
+
+        /*
+         * @see Iterator#remove()
+         */
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        /**
+         * Returns whether the given object should be skipped.
+         *
+         * @param o the object to be checked
+         * @return <code>true</code> if the object should be skipped by the iterator
+         */
+        protected bool skip(Object o) {
+            StyleRange r= cast(StyleRange) o;
+            return r.similarTo(fDefaultRange);
+        }
+
+        /**
+         * Computes the index of the styled range that is the next to be enumerated.
+         */
+        protected void computeIndex() {
+            while (fIndex < fLength && skip(fRanges.get(fIndex)))
+                ++ fIndex;
+        }
+    }
+
+    /** The style information for the range covered by the whole presentation */
+    private StyleRange fDefaultRange;
+    /** The member ranges of the presentation */
+    private ArrayList fRanges;
+    /** A clipping region against which the presentation can be clipped when asked for results */
+    private IRegion fResultWindow;
+    /**
+     * The optional extent for this presentation.
+     * @since 3.0
+     */
+    private IRegion fExtent;
+
+
+    /**
+     * Creates a new empty text presentation.
+     */
+    public this() {
+        fRanges= new ArrayList(50);
+    }
+
+    /**
+     * Creates a new empty text presentation. <code>sizeHint</code>  tells the
+     * expected size of this presentation.
+     *
+     * @param sizeHint the expected size of this presentation
+     */
+    public this(int sizeHint) {
+        Assert.isTrue(sizeHint > 0);
+        fRanges= new ArrayList(sizeHint);
+    }
+
+    /**
+     * Creates a new empty text presentation with the given extent.
+     * <code>sizeHint</code>  tells the expected size of this presentation.
+     *
+     * @param extent the extent of the created <code>TextPresentation</code>
+     * @param sizeHint the expected size of this presentation
+     * @since 3.0
+     */
+    public this(IRegion extent, int sizeHint) {
+        this(sizeHint);
+        Assert.isNotNull(cast(Object)extent);
+        fExtent= extent;
+    }
+
+    /**
+     * Sets the result window for this presentation. When dealing with
+     * this presentation all ranges which are outside the result window
+     * are ignored. For example, the size of the presentation is 0
+     * when there is no range inside the window even if there are ranges
+     * outside the window. All methods are aware of the result window.
+     *
+     * @param resultWindow the result window
+     */
+    public void setResultWindow(IRegion resultWindow) {
+        fResultWindow= resultWindow;
+    }
+
+    /**
+     * Set the default style range of this presentation.
+     * The default style range defines the overall area covered
+     * by this presentation and its style information.
+     *
+     * @param range the range describing the default region
+     */
+    public void setDefaultStyleRange(StyleRange range) {
+        fDefaultRange= range;
+    }
+
+    /**
+     * Returns this presentation's default style range. The returned <code>StyleRange</code>
+     * is relative to the start of the result window.
+     *
+     * @return this presentation's default style range
+     */
+    public StyleRange getDefaultStyleRange() {
+        StyleRange range= createWindowRelativeRange(fResultWindow, fDefaultRange);
+        if (range is null)
+            return null;
+        return cast(StyleRange)range.clone();
+
+    }
+
+    /**
+     * Add the given range to the presentation. The range must be a
+     * subrange of the presentation's default range.
+     *
+     * @param range the range to be added
+     */
+    public void addStyleRange(StyleRange range) {
+        checkConsistency(range);
+        fRanges.add(range);
+    }
+
+    /**
+     * Replaces the given range in this presentation. The range must be a
+     * subrange of the presentation's default range.
+     *
+     * @param range the range to be added
+     * @since 3.0
+     */
+    public void replaceStyleRange(StyleRange range) {
+        applyStyleRange(range, false);
+    }
+
+    /**
+     * Merges the given range into this presentation. The range must be a
+     * subrange of the presentation's default range.
+     *
+     * @param range the range to be added
+     * @since 3.0
+     */
+    public void mergeStyleRange(StyleRange range) {
+        applyStyleRange(range, true);
+    }
+
+    /**
+     * Applies the given range to this presentation. The range must be a
+     * subrange of the presentation's default range.
+     *
+     * @param range the range to be added
+     * @param merge <code>true</code> if the style should be merged instead of replaced
+     * @since 3.0
+     */
+    private void applyStyleRange(StyleRange range, bool merge) {
+        if (range.length is 0)
+            return;
+
+        checkConsistency(range);
+
+        int start= range.start;
+        int length= range.length;
+        int end= start + length;
+
+        if (fRanges.size() is 0) {
+            StyleRange defaultRange= getDefaultStyleRange();
+            if (defaultRange is null)
+                defaultRange= range;
+
+            defaultRange.start= start;
+            defaultRange.length= length;
+            applyStyle(range, defaultRange, merge);
+            fRanges.add(defaultRange);
+        } else {
+            IRegion rangeRegion= new Region(start, length);
+            int first= getFirstIndexInWindow(rangeRegion);
+
+            if (first is fRanges.size()) {
+                StyleRange defaultRange= getDefaultStyleRange();
+                if (defaultRange is null)
+                    defaultRange= range;
+                defaultRange.start= start;
+                defaultRange.length= length;
+                applyStyle(range, defaultRange, merge);
+                fRanges.add(defaultRange);
+                return;
+            }
+
+            int last= getFirstIndexAfterWindow(rangeRegion);
+            for (int i= first; i < last && length > 0; i++) {
+
+                StyleRange current= cast(StyleRange)fRanges.get(i);
+                int currentStart= current.start;
+                int currentEnd= currentStart + current.length;
+
+                if (end <= currentStart) {
+                    fRanges.add(i, range);
+                    return;
+                }
+
+                if (start >= currentEnd)
+                    continue;
+
+                StyleRange currentCopy= null;
+                if (end < currentEnd)
+                    currentCopy= cast(StyleRange)current.clone();
+
+                if (start < currentStart) {
+                    // Apply style to new default range and add it
+                    StyleRange defaultRange= getDefaultStyleRange();
+                    if (defaultRange is null)
+                        defaultRange= new StyleRange();
+
+                    defaultRange.start= start;
+                    defaultRange.length= currentStart - start;
+                    applyStyle(range, defaultRange, merge);
+                    fRanges.add(i, defaultRange);
+                    i++; last++;
+
+
+                    // Apply style to first part of current range
+                    current.length= Math.min(end, currentEnd) - currentStart;
+                    applyStyle(range, current, merge);
+                }
+
+                if (start >= currentStart) {
+                    // Shorten the current range
+                    current.length= start - currentStart;
+
+                    // Apply the style to the rest of the current range and add it
+                    if (current.length > 0) {
+                        current= cast(StyleRange)current.clone();
+                        i++; last++;
+                        fRanges.add(i, current);
+                    }
+                    applyStyle(range, current, merge);
+                    current.start= start;
+                    current.length= Math.min(end, currentEnd) - start;
+                }
+
+                if (end < currentEnd) {
+                    // Add rest of current range
+                    currentCopy.start= end;
+                    currentCopy.length= currentEnd - end;
+                    i++; last++;
+                    fRanges.add(i,  currentCopy);
+                }
+
+                // Update range
+                range.start=  currentEnd;
+                range.length= Math.max(end - currentEnd, 0);
+                start= range.start;
+                length= range.length;
+            }
+            if (length > 0) {
+                // Apply style to new default range and add it
+                StyleRange defaultRange= getDefaultStyleRange();
+                if (defaultRange is null)
+                    defaultRange= range;
+                defaultRange.start= start;
+                defaultRange.length= end - start;
+                applyStyle(range, defaultRange, merge);
+                fRanges.add(last, defaultRange);
+            }
+        }
+    }
+
+    /**
+     * Replaces the given ranges in this presentation. Each range must be a
+     * subrange of the presentation's default range. The ranges must be ordered
+     * by increasing offset and must not overlap (but may be adjacent).
+     *
+     * @param ranges the ranges to be added
+     * @since 3.0
+     */
+    public void replaceStyleRanges(StyleRange[] ranges) {
+        applyStyleRanges(ranges, false);
+    }
+
+    /**
+     * Merges the given ranges into this presentation. Each range must be a
+     * subrange of the presentation's default range. The ranges must be ordered
+     * by increasing offset and must not overlap (but may be adjacent).
+     *
+     * @param ranges the ranges to be added
+     * @since 3.0
+     */
+    public void mergeStyleRanges(StyleRange[] ranges) {
+        applyStyleRanges(ranges, true);
+    }
+
+    /**
+     * Applies the given ranges to this presentation. Each range must be a
+     * subrange of the presentation's default range. The ranges must be ordered
+     * by increasing offset and must not overlap (but may be adjacent).
+     *
+     * @param ranges the ranges to be added
+     * @param merge <code>true</code> if the style should be merged instead of replaced
+     * @since 3.0
+     */
+    private void applyStyleRanges(StyleRange[] ranges, bool merge) {
+        int j= 0;
+        ArrayList oldRanges= fRanges;
+        ArrayList newRanges= new ArrayList(2*ranges.length + oldRanges.size());
+        for (int i= 0, n= ranges.length; i < n; i++) {
+            StyleRange range= ranges[i];
+            fRanges= oldRanges; // for getFirstIndexAfterWindow(...)
+            for (int m= getFirstIndexAfterWindow(new Region(range.start, range.length)); j < m; j++)
+                newRanges.add(oldRanges.get(j));
+            fRanges= newRanges; // for mergeStyleRange(...)
+            applyStyleRange(range, merge);
+        }
+        for (int m= oldRanges.size(); j < m; j++)
+            newRanges.add(oldRanges.get(j));
+        fRanges= newRanges;
+    }
+
+    /**
+     * Applies the template_'s style to the target.
+     *
+     * @param template_ the style range to be used as template_
+     * @param target the style range to which to apply the template_
+     * @param merge <code>true</code> if the style should be merged instead of replaced
+     * @since 3.0
+     */
+    private void applyStyle(StyleRange template_, StyleRange target, bool merge) {
+        if (merge) {
+            if (template_.font !is null)
+                target.font= template_.font;
+            target.fontStyle|= template_.fontStyle;
+
+            if (template_.metrics !is null)
+                target.metrics= template_.metrics;
+
+            if (template_.foreground !is null)
+                target.foreground= template_.foreground;
+            if (template_.background !is null)
+                target.background= template_.background;
+
+            target.strikeout|= template_.strikeout;
+            if (template_.strikeoutColor !is null)
+                target.strikeoutColor= template_.strikeoutColor;
+
+            target.underline|= template_.underline;
+            if (template_.underlineStyle !is DWT.NONE)
+                target.underlineStyle= template_.underlineStyle;
+            if (template_.underlineColor !is null)
+                target.underlineColor= template_.underlineColor;
+
+            if (template_.borderStyle !is DWT.NONE)
+                target.borderStyle= template_.borderStyle;
+            if (template_.borderColor !is null)
+                target.borderColor= template_.borderColor;
+
+        } else {
+            target.font= template_.font;
+            target.fontStyle= template_.fontStyle;
+            target.metrics= template_.metrics;
+            target.foreground= template_.foreground;
+            target.background= template_.background;
+            target.strikeout= template_.strikeout;
+            target.strikeoutColor= template_.strikeoutColor;
+            target.underline= template_.underline;
+            target.underlineStyle= template_.underlineStyle;
+            target.underlineColor= template_.underlineColor;
+            target.borderStyle= template_.borderStyle;
+            target.borderColor= template_.borderColor;
+        }
+    }
+
+    /**
+     * Checks whether the given range is a subrange of the presentation's
+     * default style range.
+     *
+     * @param range the range to be checked
+     * @exception IllegalArgumentException if range is not a subrange of the presentation's default range
+     */
+    private void checkConsistency(StyleRange range) {
+
+        if (range is null)
+            throw new IllegalArgumentException(null);
+
+        if (fDefaultRange !is null) {
+
+            if (range.start < fDefaultRange.start)
+                range.start= fDefaultRange.start;
+
+            int defaultEnd= fDefaultRange.start + fDefaultRange.length;
+            int end= range.start + range.length;
+            if (end > defaultEnd)
+                range.length -= (end - defaultEnd);
+        }
+    }
+
+    /**
+     * Returns the index of the first range which overlaps with the
+     * specified window.
+     *
+     * @param window the window to be used for searching
+     * @return the index of the first range overlapping with the window
+     */
+    private int getFirstIndexInWindow(IRegion window) {
+        if (window !is null) {
+            int start= window.getOffset();
+            int i= -1, j= fRanges.size();
+            while (j - i > 1) {
+                int k= (i + j) >> 1;
+                StyleRange r= cast(StyleRange) fRanges.get(k);
+                if (r.start + r.length > start)
+                    j= k;
+                else
+                    i= k;
+            }
+            return j;
+        }
+        return 0;
+    }
+
+    /**
+     * Returns the index of the first range which comes after the specified window and does
+     * not overlap with this window.
+     *
+     * @param window the window to be used for searching
+     * @return the index of the first range behind the window and not overlapping with the window
+     */
+    private int getFirstIndexAfterWindow(IRegion window) {
+        if (window !is null) {
+            int end= window.getOffset() + window.getLength();
+            int i= -1, j= fRanges.size();
+            while (j - i > 1) {
+                int k= (i + j) >> 1;
+                StyleRange r= cast(StyleRange) fRanges.get(k);
+                if (r.start < end)
+                    i= k;
+                else
+                    j= k;
+            }
+            return j;
+        }
+        return fRanges.size();
+    }
+
+    /**
+     * Returns a style range which is relative to the specified window and
+     * appropriately clipped if necessary. The original style range is not
+     * modified.
+     *
+     * @param window the reference window
+     * @param range the absolute range
+     * @return the window relative range based on the absolute range
+     */
+    private StyleRange createWindowRelativeRange(IRegion window, StyleRange range) {
+        if (window is null || range is null)
+            return range;
+
+        int start= range.start - window.getOffset();
+        if (start < 0)
+            start= 0;
+
+        int rangeEnd= range.start + range.length;
+        int windowEnd= window.getOffset() + window.getLength();
+        int end= (rangeEnd > windowEnd ? windowEnd : rangeEnd);
+        end -= window.getOffset();
+
+        StyleRange newRange= cast(StyleRange) range.clone();
+        newRange.start= start;
+        newRange.length= end - start;
+        return newRange;
+    }
+
+    /**
+     * Returns the region which is relative to the specified window and
+     * appropriately clipped if necessary.
+     *
+     * @param coverage the absolute coverage
+     * @return the window relative region based on the absolute coverage
+     * @since 3.0
+     */
+    private IRegion createWindowRelativeRegion(IRegion coverage) {
+        if (fResultWindow is null || coverage is null)
+            return coverage;
+
+        int start= coverage.getOffset() - fResultWindow.getOffset();
+        if (start < 0)
+            start= 0;
+
+        int rangeEnd= coverage.getOffset() + coverage.getLength();
+        int windowEnd= fResultWindow.getOffset() + fResultWindow.getLength();
+        int end= (rangeEnd > windowEnd ? windowEnd : rangeEnd);
+        end -= fResultWindow.getOffset();
+
+        return new Region(start, end - start);
+    }
+
+    /**
+     * Returns an iterator which enumerates all style ranged which define a style
+     * different from the presentation's default style range. The default style range
+     * is not enumerated.
+     *
+     * @return a style range iterator
+     */
+    public Iterator getNonDefaultStyleRangeIterator() {
+        return new FilterIterator(fDefaultRange !is null);
+    }
+
+    /**
+     * Returns an iterator which enumerates all style ranges of this presentation
+     * except the default style range. The returned <code>StyleRange</code>s
+     * are relative to the start of the presentation's result window.
+     *
+     * @return a style range iterator
+     */
+    public Iterator getAllStyleRangeIterator() {
+        return new FilterIterator(false);
+    }
+
+    /**
+     * Returns whether this collection contains any style range including
+     * the default style range.
+     *
+     * @return <code>true</code> if there is no style range in this presentation
+     */
+    public bool isEmpty() {
+        return (fDefaultRange is null && getDenumerableRanges() is 0);
+    }
+
+    /**
+     * Returns the number of style ranges in the presentation not counting the default
+     * style range.
+     *
+     * @return the number of style ranges in the presentation excluding the default style range
+     */
+    public int getDenumerableRanges() {
+        int size= getFirstIndexAfterWindow(fResultWindow) - getFirstIndexInWindow(fResultWindow);
+        return (size < 0 ? 0 : size);
+    }
+
+    /**
+     * Returns the style range with the smallest offset ignoring the default style range or null
+     * if the presentation is empty.
+     *
+     * @return the style range with the smallest offset different from the default style range
+     */
+    public StyleRange getFirstStyleRange() {
+        try {
+
+            StyleRange range= cast(StyleRange) fRanges.get(getFirstIndexInWindow(fResultWindow));
+            return createWindowRelativeRange(fResultWindow, range);
+
+        } catch (NoSuchElementException x) {
+        } catch (IndexOutOfBoundsException x) {
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the style range with the highest offset ignoring the default style range.
+     *
+     * @return the style range with the highest offset different from the default style range
+     */
+    public StyleRange getLastStyleRange() {
+        try {
+
+            StyleRange range=  cast(StyleRange) fRanges.get(getFirstIndexAfterWindow(fResultWindow) - 1);
+            return createWindowRelativeRange(fResultWindow, range);
+
+        } catch (NoSuchElementException x) {
+            return null;
+        } catch (IndexOutOfBoundsException x) {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the coverage of this presentation as clipped by the presentation's
+     * result window.
+     *
+     * @return the coverage of this presentation
+     */
+    public IRegion getCoverage() {
+
+        if (fDefaultRange !is null) {
+            StyleRange range= getDefaultStyleRange();
+            return new Region(range.start, range.length);
+        }
+
+        StyleRange first= getFirstStyleRange();
+        StyleRange last= getLastStyleRange();
+
+        if (first is null || last is null)
+            return null;
+
+        return new Region(first.start, last.start - first. start + last.length);
+    }
+
+    /**
+     * Returns the extent of this presentation clipped by the
+     * presentation's result window.
+     *
+     * @return the clipped extent
+     * @since 3.0
+     */
+    public IRegion getExtent() {
+        if (fExtent !is null)
+            return createWindowRelativeRegion(fExtent);
+        return getCoverage();
+    }
+
+    /**
+     * Clears this presentation by resetting all applied changes.
+     * @since 2.0
+     */
+    public void clear() {
+        fDefaultRange= null;
+        fResultWindow= null;
+        fRanges.clear();
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/TextSelection.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,343 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.TextSelection;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Standard implementation of {@link dwtx.jface.text.ITextSelection}.
+ * <p>
+ * Makes advantage of the weak contract of correctness of its interface. If
+ * generated from a selection provider, it only remembers its offset and length
+ * and computes the remaining information on request.</p>
+ */
+public class TextSelection : ITextSelection {
+
+    /** Internal empty text selection */
+    private static ITextSelection NULL_;
+    private static ITextSelection NULL(){
+        if( NULL_ is null ){
+            synchronized( TextSelection.classinfo ){
+                if( NULL_ is null ){
+                    NULL_= new TextSelection();
+                }
+            }
+        }
+        return NULL_;
+    }
+
+    /**
+     * Returns a shared instance of an empty text selection.
+     *
+     * @return a shared instance of an empty text selection
+     */
+    public static ITextSelection emptySelection() {
+        return NULL;
+    }
+
+    /** Document which delivers the data of the selection */
+    private IDocument fDocument;
+    /** Offset of the selection */
+    private int fOffset;
+    /** Length of the selection */
+    private int fLength;
+
+
+    /**
+     * Creates an empty text selection.
+     */
+    private this() {
+        this(null, -1, -1);
+    }
+
+    /**
+     * Creates a text selection for the given range. This
+     * selection object describes generically a text range and
+     * is intended to be an argument for the <code>setSelection</code>
+     * method of selection providers.
+     *
+     * @param offset the offset of the range
+     * @param length the length of the range
+     */
+    public this(int offset, int length) {
+        this(null, offset, length);
+    }
+
+    /**
+     * Creates a text selection for the given range of the given document.
+     * This selection object is created by selection providers in responds
+     * <code>getSelection</code>.
+     *
+     * @param document the document whose text range is selected in a viewer
+     * @param offset the offset of the selected range
+     * @param length the length of the selected range
+     */
+    public this(IDocument document, int offset, int length) {
+        fDocument= document;
+        fOffset= offset;
+        fLength= length;
+    }
+
+    /**
+     *
+     * Returns true if the offset and length are smaller than 0.
+     * A selection of length 0, is a valid text selection as it
+     * describes, e.g., the cursor position in a viewer.
+     *
+     * @return <code>true</code> if this selection is empty
+     * @see dwtx.jface.viewers.ISelection#isEmpty()
+     */
+    public bool isEmpty() {
+        return fOffset < 0 || fLength < 0;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextSelection#getOffset()
+     */
+    public int getOffset() {
+        return fOffset;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextSelection#getLength()
+     */
+    public int getLength() {
+        return fLength;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextSelection#getStartLine()
+     */
+    public int getStartLine() {
+
+        try {
+            if (fDocument !is null)
+                return fDocument.getLineOfOffset(fOffset);
+        } catch (BadLocationException x) {
+        }
+
+        return -1;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextSelection#getEndLine()
+     */
+    public int getEndLine() {
+        try {
+            if (fDocument !is null) {
+                int endOffset= fOffset + fLength;
+                if (fLength !is 0)
+                    endOffset--;
+                return fDocument.getLineOfOffset(endOffset);
+            }
+        } catch (BadLocationException x) {
+        }
+
+        return -1;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextSelection#getText()
+     */
+    public String getText() {
+        try {
+            if (fDocument !is null)
+                return fDocument.get(fOffset, fLength);
+        } catch (BadLocationException x) {
+        }
+
+        return null;
+    }
+
+    /*
+     * @see java.lang.Object#equals(Object)
+     */
+    public override int opEquals(Object obj) {
+        if (obj is this)
+            return true;
+
+        if (obj is null || this.classinfo !is obj.classinfo)
+            return false;
+
+        TextSelection s= cast(TextSelection) obj;
+        bool sameRange= (s.fOffset is fOffset && s.fLength is fLength);
+        if (sameRange) {
+
+            if (s.fDocument is null && fDocument is null)
+                return true;
+            if (s.fDocument is null || fDocument is null)
+                return false;
+
+            try {
+                String sContent= s.fDocument.get(fOffset, fLength);
+                String content= fDocument.get(fOffset, fLength);
+                return sContent==/+eq+/content;
+            } catch (BadLocationException x) {
+            }
+        }
+
+        return false;
+    }
+
+    /*
+     * @see java.lang.Object#hashCode()
+     */
+    public override hash_t toHash() {
+        int low= fDocument !is null ? (cast(Object)fDocument).toHash() : 0;
+        return (fOffset << 24) | (fLength << 16) | low;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/TextUtilities.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,718 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.TextUtilities;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+// import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * A collection of text functions.
+ * <p>
+ * This class is neither intended to be instantiated nor subclassed.
+ * </p>
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class TextUtilities {
+
+    /**
+     * Default line delimiters used by the text functions of this class.
+     */
+    public const static String[] DELIMITERS= [ "\n", "\r", "\r\n" ]; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$
+
+    /**
+     * Default line delimiters used by these text functions.
+     *
+     * @deprecated use DELIMITERS instead
+     */
+    public const static String[] fgDelimiters= DELIMITERS;
+
+
+
+    /**
+     * Determines which one of default line delimiters appears first in the list. If none of them the
+     * hint is returned.
+     *
+     * @param text the text to be checked
+     * @param hint the line delimiter hint
+     * @return the line delimiter
+     */
+    public static String determineLineDelimiter(String text, String hint) {
+        try {
+            int[] info= indexOf(DELIMITERS, text, 0);
+            return DELIMITERS[info[1]];
+        } catch (ArrayIndexOutOfBoundsException x) {
+        }
+        return hint;
+    }
+
+    /**
+     * Returns the starting position and the index of the first matching search string
+     * in the given text that is greater than the given offset. If more than one search
+     * string matches with the same starting position then the longest one is returned.
+     *
+     * @param searchStrings the strings to search for
+     * @param text the text to be searched
+     * @param offset the offset at which to start the search
+     * @return an <code>int[]</code> with two elements where the first is the starting offset, the second the index of the found
+     *      search string in the given <code>searchStrings</code> array, returns <code>[-1, -1]</code> if no match exists
+     */
+    public static int[] indexOf(String[] searchStrings, String text, int offset) {
+
+        int[] result= [ -1, -1 ];
+        int zeroIndex= -1;
+
+        for (int i= 0; i < searchStrings.length; i++) {
+
+            int length= searchStrings[i].length();
+
+            if (length is 0) {
+                zeroIndex= i;
+                continue;
+            }
+
+            int index= .indexOf( text, searchStrings[i], offset);
+            if (index >= 0) {
+
+                if (result[0] is -1) {
+                    result[0]= index;
+                    result[1]= i;
+                } else if (index < result[0]) {
+                    result[0]= index;
+                    result[1]= i;
+                } else if (index is result[0] && length > searchStrings[result[1]].length) {
+                    result[0]= index;
+                    result[1]= i;
+                }
+            }
+        }
+
+        if (zeroIndex > -1 && result[0] is -1) {
+            result[0]= 0;
+            result[1]= zeroIndex;
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns the index of the longest search string with which the given text ends or
+     * <code>-1</code> if none matches.
+     *
+     * @param searchStrings the strings to search for
+     * @param text the text to search
+     * @return the index in <code>searchStrings</code> of the longest string with which <code>text</code> ends or <code>-1</code>
+     */
+    public static int endsWith(String[] searchStrings, String text) {
+
+        int index= -1;
+
+        for (int i= 0; i < searchStrings.length; i++) {
+            if (.endsWith(text, searchStrings[i])) {
+                if (index is -1 || searchStrings[i].length() > searchStrings[index].length())
+                    index= i;
+            }
+        }
+
+        return index;
+    }
+
+    /**
+     * Returns the index of the longest search string with which the given text starts or <code>-1</code>
+     * if none matches.
+     *
+     * @param searchStrings the strings to search for
+     * @param text the text to search
+     * @return the index in <code>searchStrings</code> of the longest string with which <code>text</code> starts or <code>-1</code>
+     */
+    public static int startsWith(String[] searchStrings, String text) {
+
+        int index= -1;
+
+        for (int i= 0; i < searchStrings.length; i++) {
+            if (.startsWith(text, searchStrings[i])) {
+                if (index is -1 || searchStrings[i].length() > searchStrings[index].length())
+                    index= i;
+            }
+        }
+
+        return index;
+    }
+
+    /**
+     * Returns the index of the first compare string that equals the given text or <code>-1</code>
+     * if none is equal.
+     *
+     * @param compareStrings the strings to compare with
+     * @param text the text to check
+     * @return the index of the first equal compare string or <code>-1</code>
+     */
+    public static int equals(String[] compareStrings, String text) {
+        for (int i= 0; i < compareStrings.length; i++) {
+            if (.equals(text,compareStrings[i]))
+                return i;
+        }
+        return -1;
+    }
+
+    /**
+     * Returns a document event which is an accumulation of a list of document events,
+     * <code>null</code> if the list of documentEvents is empty.
+     * The document of the document events are ignored.
+     *
+     * @param unprocessedDocument the document to which the document events would be applied
+     * @param documentEvents the list of document events to merge
+     * @return returns the merged document event
+     * @throws BadLocationException might be thrown if document is not in the correct state with respect to document events
+     */
+    public static DocumentEvent mergeUnprocessedDocumentEvents(IDocument unprocessedDocument, List documentEvents)  {
+
+        if (documentEvents.size() is 0)
+            return null;
+
+        final Iterator iterator= documentEvents.iterator();
+        final DocumentEvent firstEvent= cast(DocumentEvent) iterator.next();
+
+        // current merged event
+        final IDocument document= unprocessedDocument;
+        int offset= firstEvent.getOffset();
+        int length= firstEvent.getLength();
+        final StringBuffer text= new StringBuffer(firstEvent.getText() is null ? "" : firstEvent.getText()); //$NON-NLS-1$
+
+        while (iterator.hasNext()) {
+
+            final int delta= text.length() - length;
+
+            final DocumentEvent event= cast(DocumentEvent) iterator.next();
+            final int eventOffset= event.getOffset();
+            final int eventLength= event.getLength();
+            final String eventText= event.getText() is null ? "" : event.getText(); //$NON-NLS-1$
+
+            // event is right from merged event
+            if (eventOffset > offset + length + delta) {
+                final String string= document.get(offset + length, (eventOffset - delta) - (offset + length));
+                text.append(string);
+                text.append(eventText);
+
+                length= (eventOffset - delta) + eventLength - offset;
+
+            // event is left from merged event
+            } else if (eventOffset + eventLength < offset) {
+                final String string= document.get(eventOffset + eventLength, offset - (eventOffset + eventLength));
+                text.select(0,0);
+                text.replace(string);
+                text.select(0,0);
+                text.replace(eventText);
+
+                length= offset + length - eventOffset;
+                offset= eventOffset;
+
+            // events overlap each other
+            } else {
+                final int start= Math.max(0, eventOffset - offset);
+                final int end= Math.min(text.length(), eventLength + eventOffset - offset);
+                text.select(start, end);
+                text.replace(eventText);
+
+                offset= Math.min(offset, eventOffset);
+                final int totalDelta= delta + eventText.length - eventLength;
+                length= text.length() - totalDelta;
+            }
+        }
+
+        return new DocumentEvent(document, offset, length, text.toString());
+    }
+
+    /**
+     * Returns a document event which is an accumulation of a list of document events,
+     * <code>null</code> if the list of document events is empty.
+     * The document events being merged must all refer to the same document, to which
+     * the document changes have been already applied.
+     *
+     * @param documentEvents the list of document events to merge
+     * @return returns the merged document event
+     * @throws BadLocationException might be thrown if document is not in the correct state with respect to document events
+     */
+    public static DocumentEvent mergeProcessedDocumentEvents(List documentEvents)  {
+
+        if (documentEvents.size() is 0)
+            return null;
+
+        final ListIterator iterator= documentEvents.listIterator(documentEvents.size());
+        final DocumentEvent firstEvent= cast(DocumentEvent) iterator.previous();
+
+        // current merged event
+        final IDocument document= firstEvent.getDocument();
+        int offset= firstEvent.getOffset();
+        int length= firstEvent.getLength();
+        int textLength= firstEvent.getText() is null ? 0 : firstEvent.getText().length;
+
+        while (iterator.hasPrevious()) {
+
+            final int delta= length - textLength;
+
+            final DocumentEvent event= cast(DocumentEvent) iterator.previous();
+            final int eventOffset= event.getOffset();
+            final int eventLength= event.getLength();
+            final int eventTextLength= event.getText() is null ? 0 : event.getText().length;
+
+            // event is right from merged event
+            if (eventOffset > offset + textLength + delta) {
+                length= (eventOffset - delta) - (offset + textLength) + length + eventLength;
+                textLength= (eventOffset - delta) + eventTextLength - offset;
+
+            // event is left from merged event
+            } else if (eventOffset + eventTextLength < offset) {
+                length= offset - (eventOffset + eventTextLength) + length + eventLength;
+                textLength= offset + textLength - eventOffset;
+                offset= eventOffset;
+
+            // events overlap each other
+            } else {
+                final int start= Math.max(0, eventOffset - offset);
+                final int end= Math.min(length, eventTextLength + eventOffset - offset);
+                length += eventLength - (end - start);
+
+                offset= Math.min(offset, eventOffset);
+                final int totalDelta= delta + eventLength - eventTextLength;
+                textLength= length - totalDelta;
+            }
+        }
+
+        final String text= document.get(offset, textLength);
+        return new DocumentEvent(document, offset, length, text);
+    }
+
+    /**
+     * Removes all connected document partitioners from the given document and stores them
+     * under their partitioning name in a map. This map is returned. After this method has been called
+     * the given document is no longer connected to any document partitioner.
+     *
+     * @param document the document
+     * @return the map containing the removed partitioners
+     */
+    public static Map removeDocumentPartitioners(IDocument document) {
+        Map partitioners= new HashMap();
+        if (cast(IDocumentExtension3)document ) {
+            IDocumentExtension3 extension3= cast(IDocumentExtension3) document;
+            String[] partitionings= extension3.getPartitionings();
+            for (int i= 0; i < partitionings.length; i++) {
+                IDocumentPartitioner partitioner= extension3.getDocumentPartitioner(partitionings[i]);
+                if (partitioner !is null) {
+                    extension3.setDocumentPartitioner(partitionings[i], null);
+                    partitioner.disconnect();
+                    partitioners.put(stringcast(partitionings[i]), cast(Object)partitioner);
+                }
+            }
+        } else {
+            IDocumentPartitioner partitioner= document.getDocumentPartitioner();
+            if (partitioner !is null) {
+                document.setDocumentPartitioner(null);
+                partitioner.disconnect();
+                partitioners.put(stringcast(IDocumentExtension3.DEFAULT_PARTITIONING), cast(Object)partitioner);
+            }
+        }
+        return partitioners;
+    }
+
+    /**
+     * Connects the given document with all document partitioners stored in the given map under
+     * their partitioning name. This method cleans the given map.
+     *
+     * @param document the document
+     * @param partitioners the map containing the partitioners to be connected
+     * @since 3.0
+     */
+    public static void addDocumentPartitioners(IDocument document, Map partitioners) {
+        if (cast(IDocumentExtension3)document ) {
+            IDocumentExtension3 extension3= cast(IDocumentExtension3) document;
+            Iterator e= partitioners.keySet().iterator();
+            while (e.hasNext()) {
+                String partitioning= stringcast( e.next() );
+                IDocumentPartitioner partitioner= cast(IDocumentPartitioner) partitioners.get(partitioning);
+                partitioner.connect(document);
+                extension3.setDocumentPartitioner(partitioning, partitioner);
+            }
+            partitioners.clear();
+        } else {
+            IDocumentPartitioner partitioner= cast(IDocumentPartitioner) partitioners.get(IDocumentExtension3.DEFAULT_PARTITIONING);
+            partitioner.connect(document);
+            document.setDocumentPartitioner(partitioner);
+        }
+    }
+
+    /**
+     * Returns the content type at the given offset of the given document.
+     *
+     * @param document the document
+     * @param partitioning the partitioning to be used
+     * @param offset the offset
+     * @param preferOpenPartitions <code>true</code> if precedence should be
+     *        given to a open partition ending at <code>offset</code> over a
+     *        closed partition starting at <code>offset</code>
+     * @return the content type at the given offset of the document
+     * @throws BadLocationException if offset is invalid in the document
+     * @since 3.0
+     */
+    public static String getContentType(IDocument document, String partitioning, int offset, bool preferOpenPartitions)  {
+        if (cast(IDocumentExtension3)document ) {
+            IDocumentExtension3 extension3= cast(IDocumentExtension3) document;
+            try {
+                return extension3.getContentType(partitioning, offset, preferOpenPartitions);
+            } catch (BadPartitioningException x) {
+                return IDocument.DEFAULT_CONTENT_TYPE;
+            }
+        }
+
+        return document.getContentType(offset);
+    }
+
+    /**
+     * Returns the partition of the given offset of the given document.
+     *
+     * @param document the document
+     * @param partitioning the partitioning to be used
+     * @param offset the offset
+     * @param preferOpenPartitions <code>true</code> if precedence should be
+     *        given to a open partition ending at <code>offset</code> over a
+     *        closed partition starting at <code>offset</code>
+     * @return the content type at the given offset of this viewer's input
+     *         document
+     * @throws BadLocationException if offset is invalid in the given document
+     * @since 3.0
+     */
+    public static ITypedRegion getPartition(IDocument document, String partitioning, int offset, bool preferOpenPartitions)  {
+        if (cast(IDocumentExtension3)document ) {
+            IDocumentExtension3 extension3= cast(IDocumentExtension3) document;
+            try {
+                return extension3.getPartition(partitioning, offset, preferOpenPartitions);
+            } catch (BadPartitioningException x) {
+                return new TypedRegion(0, document.getLength(), IDocument.DEFAULT_CONTENT_TYPE);
+            }
+        }
+
+        return document.getPartition(offset);
+    }
+
+    /**
+     * Computes and returns the partitioning for the given region of the given
+     * document for the given partitioning name.
+     *
+     * @param document the document
+     * @param partitioning the partitioning name
+     * @param offset the region offset
+     * @param length the region length
+     * @param includeZeroLengthPartitions whether to include zero-length partitions
+     * @return the partitioning for the given region of the given document for
+     *         the given partitioning name
+     * @throws BadLocationException if the given region is invalid for the given
+     *         document
+     * @since 3.0
+     */
+    public static ITypedRegion[] computePartitioning(IDocument document, String partitioning, int offset, int length, bool includeZeroLengthPartitions)  {
+        if (cast(IDocumentExtension3)document ) {
+            IDocumentExtension3 extension3= cast(IDocumentExtension3) document;
+            try {
+                return extension3.computePartitioning(partitioning, offset, length, includeZeroLengthPartitions);
+            } catch (BadPartitioningException x) {
+                return new ITypedRegion[0];
+            }
+        }
+
+        return document.computePartitioning(offset, length);
+    }
+
+    /**
+     * Computes and returns the partition managing position categories for the
+     * given document or <code>null</code> if this was impossible.
+     *
+     * @param document the document
+     * @return the partition managing position categories or <code>null</code>
+     * @since 3.0
+     */
+    public static String[] computePartitionManagingCategories(IDocument document) {
+        if (cast(IDocumentExtension3)document ) {
+            IDocumentExtension3 extension3= cast(IDocumentExtension3) document;
+            String[] partitionings= extension3.getPartitionings();
+            if (partitionings !is null) {
+                Set categories= new HashSet();
+                for (int i= 0; i < partitionings.length; i++) {
+                    IDocumentPartitioner p= extension3.getDocumentPartitioner(partitionings[i]);
+                    if (cast(IDocumentPartitionerExtension2)p ) {
+                        IDocumentPartitionerExtension2 extension2= cast(IDocumentPartitionerExtension2) p;
+                        String[] c= extension2.getManagingPositionCategories();
+                        if (c !is null) {
+                            for (int j= 0; j < c.length; j++)
+                                categories.add(c[j]);
+                        }
+                    }
+                }
+                return stringcast(categories.toArray());
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the default line delimiter for the given document. This is either the delimiter of the first line, or the platform line delimiter if it is
+     * a legal line delimiter or the first one of the legal line delimiters. The default line delimiter should be used when performing document
+     * manipulations that span multiple lines.
+     *
+     * @param document the document
+     * @return the document's default line delimiter
+     * @since 3.0
+     */
+    public static String getDefaultLineDelimiter(IDocument document) {
+
+        if (cast(IDocumentExtension4)document )
+            return (cast(IDocumentExtension4)document).getDefaultLineDelimiter();
+
+        String lineDelimiter= null;
+
+        try {
+            lineDelimiter= document.getLineDelimiter(0);
+        } catch (BadLocationException x) {
+        }
+
+        if (lineDelimiter !is null)
+            return lineDelimiter;
+
+        String sysLineDelimiter= System.getProperty("line.separator"); //$NON-NLS-1$
+        String[] delimiters= document.getLegalLineDelimiters();
+        Assert.isTrue(delimiters.length > 0);
+        for (int i= 0; i < delimiters.length; i++) {
+            if (.equals(delimiters[i], sysLineDelimiter)) {
+                lineDelimiter= sysLineDelimiter;
+                break;
+            }
+        }
+
+        if (lineDelimiter is null)
+            lineDelimiter= delimiters[0];
+
+        return lineDelimiter;
+    }
+
+    /**
+     * Returns <code>true</code> if the two regions overlap. Returns <code>false</code> if one of the
+     * arguments is <code>null</code>.
+     *
+     * @param left the left region
+     * @param right the right region
+     * @return <code>true</code> if the two regions overlap, <code>false</code> otherwise
+     * @since 3.0
+     */
+    public static bool overlaps(IRegion left, IRegion right) {
+
+        if (left is null || right is null)
+            return false;
+
+        int rightEnd= right.getOffset() + right.getLength();
+        int leftEnd= left.getOffset()+ left.getLength();
+
+        if (right.getLength() > 0) {
+            if (left.getLength() > 0)
+                return left.getOffset() < rightEnd && right.getOffset() < leftEnd;
+            return  right.getOffset() <= left.getOffset() && left.getOffset() < rightEnd;
+        }
+
+        if (left.getLength() > 0)
+            return left.getOffset() <= right.getOffset() && right.getOffset() < leftEnd;
+
+        return left.getOffset() is right.getOffset();
+    }
+
+    /**
+     * Returns a copy of the given string array.
+     *
+     * @param array the string array to be copied
+     * @return a copy of the given string array or <code>null</code> when <code>array</code> is <code>null</code>
+     * @since 3.1
+     */
+    public static String[] copy(String[] array) {
+        if (array !is null) {
+            String[] copy= new String[array.length];
+            System.arraycopy(array, 0, copy, 0, array.length);
+            return copy;
+        }
+        return null;
+    }
+
+    /**
+     * Returns a copy of the given integer array.
+     *
+     * @param array the integer array to be copied
+     * @return a copy of the given integer array or <code>null</code> when <code>array</code> is <code>null</code>
+     * @since 3.1
+     */
+    public static int[] copy(int[] array) {
+        if (array !is null) {
+            int[] copy= new int[array.length];
+            System.arraycopy(array, 0, copy, 0, array.length);
+            return copy;
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/TextViewer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,5543 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.TextViewer;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import dwtx.dwtxhelper.regex;
+import tango.text.convert.Format;
+import tango.core.Thread;
+
+import dwt.DWT;
+import dwt.custom.LineBackgroundEvent;
+import dwt.custom.LineBackgroundListener;
+import dwt.custom.MovementEvent;
+import dwt.custom.MovementListener;
+import dwt.custom.ST;
+import dwt.custom.StyleRange;
+import dwt.custom.StyledText;
+import dwt.custom.StyledTextPrintOptions;
+import dwt.custom.VerifyKeyListener;
+import dwt.events.ControlEvent;
+import dwt.events.ControlListener;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.events.MouseAdapter;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.events.SelectionEvent;
+import dwt.events.SelectionListener;
+import dwt.events.TraverseEvent;
+import dwt.events.TraverseListener;
+import dwt.events.VerifyEvent;
+import dwt.events.VerifyListener;
+import dwt.graphics.Color;
+import dwt.graphics.GC;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.printing.PrintDialog;
+import dwt.printing.Printer;
+import dwt.printing.PrinterData;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwt.widgets.ScrollBar;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.internal.text.NonDeletingPositionUpdater;
+import dwtx.jface.internal.text.StickyHoverManager;
+import dwtx.jface.text.hyperlink.HyperlinkManager;
+import dwtx.jface.text.hyperlink.IHyperlinkDetector;
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension;
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter;
+import dwtx.jface.text.hyperlink.HyperlinkManager;
+import dwtx.jface.text.projection.ChildDocument;
+import dwtx.jface.text.projection.ChildDocumentManager;
+import dwtx.jface.viewers.IPostSelectionProvider;
+import dwtx.jface.viewers.ISelection;
+import dwtx.jface.viewers.ISelectionChangedListener;
+import dwtx.jface.viewers.ISelectionProvider;
+import dwtx.jface.viewers.SelectionChangedEvent;
+import dwtx.jface.viewers.Viewer;
+
+
+/**
+ * DWT based implementation of {@link ITextViewer} and its extension interfaces.
+ * Once the viewer and its DWT control have been created the viewer can only
+ * indirectly be disposed by disposing its DWT control.
+ * <p>
+ * Clients are supposed to instantiate a text viewer and subsequently to
+ * communicate with it exclusively using the
+ * {@link dwtx.jface.text.ITextViewer} interface or any of the
+ * implemented extension interfaces.
+ * <p>
+ * A text viewer serves as text operation target. It only partially supports the
+ * external control of the enable state of its text operations. A text viewer is
+ * also a widget token owner. Anything that wants to display an overlay window
+ * on top of a text viewer should implement the
+ * {@link dwtx.jface.text.IWidgetTokenKeeper} interface and participate
+ * in the widget token negotiation between the text viewer and all its potential
+ * widget token keepers.
+ * <p>
+ * This class is not intended to be subclassed outside the JFace Text component.</p>
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class TextViewer : Viewer ,
+                    ITextViewer, ITextViewerExtension, ITextViewerExtension2, ITextViewerExtension4, ITextViewerExtension6, ITextViewerExtension7, ITextViewerExtension8,
+                    IEditingSupportRegistry, ITextOperationTarget, ITextOperationTargetExtension,
+                    IWidgetTokenOwner, IWidgetTokenOwnerExtension, IPostSelectionProvider {
+
+    alias Viewer.fireSelectionChanged fireSelectionChanged;
+
+    /** Internal flag to indicate the debug state. */
+    public static const bool TRACE_ERRORS= false;
+    /** Internal flag to indicate the debug state. */
+    private static const bool TRACE_DOUBLE_CLICK= false;
+
+    /**
+     * Width constraint for text hovers (in characters).
+     * @since 3.4
+     */
+    private static const int TEXT_HOVER_WIDTH_CHARS= 100; //used to be 60 (text font)
+    /**
+     * Height constraint for text hovers (in characters).
+     * @since 3.4
+     */
+    private static const int TEXT_HOVER_HEIGHT_CHARS= 12; //used to be 10 (text font)
+
+    /**
+     * Represents a replace command that brings the text viewer's text widget
+     * back in synchronization with text viewer's document after the document
+     * has been changed.
+     */
+    protected class WidgetCommand {
+
+        /** The document event encapsulated by this command. */
+        public DocumentEvent event;
+        /** The start of the event. */
+        public int start;
+        /** The length of the event. */
+        public int length;
+        /** The inserted and replaced text segments of <code>event</code>. */
+        public String text;
+        /** The replaced text segments of <code>event</code>. */
+        public String preservedText;
+
+        /**
+         * Translates a document event into the presentation coordinates of this text viewer.
+         *
+         * @param e the event to be translated
+         */
+        public void setEvent(DocumentEvent e) {
+
+            event= e;
+
+            start= e.getOffset();
+            length= e.getLength();
+            text= e.getText();
+
+            if (length !is 0) {
+                try {
+
+                    if ( cast(SlaveDocumentEvent)e ) {
+                        SlaveDocumentEvent slave= cast(SlaveDocumentEvent) e;
+                        DocumentEvent master= slave.getMasterEvent();
+                        if (master !is null)
+                            preservedText= master.getDocument().get(master.getOffset(), master.getLength());
+                    } else {
+                        preservedText= e.getDocument().get(e.getOffset(), e.getLength());
+                    }
+
+                } catch (BadLocationException x) {
+                    preservedText= null;
+                    if (TRACE_ERRORS)
+                        System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.WidgetCommand.setEvent")); //$NON-NLS-1$
+                }
+            } else
+                preservedText= null;
+        }
+    }
+
+
+    /**
+     * Connects a text double click strategy to this viewer's text widget.
+     * Calls the double click strategies when the mouse has
+     * been clicked inside the text editor.
+     */
+    class TextDoubleClickStrategyConnector : MouseAdapter , MovementListener {
+
+        /** Internal flag to remember the last double-click selection. */
+        private Point fDoubleClickSelection;
+
+        /*
+         * @see dwt.events.MouseAdapter#mouseUp(dwt.events.MouseEvent)
+         * @since 3.2
+         */
+        public void mouseUp(MouseEvent e) {
+            fDoubleClickSelection= null;
+        }
+
+        /*
+         * @see dwt.custom.MovementListener#getNextOffset(dwt.custom.MovementEvent)
+         * @since 3.3
+         */
+        public void getNextOffset(MovementEvent event) {
+            if (event.movement !is DWT.MOVEMENT_WORD_END)
+                return;
+
+            if (TRACE_DOUBLE_CLICK) {
+                System.out_.println("\n+++"); //$NON-NLS-1$
+                print(event);
+            }
+
+            if (fDoubleClickSelection !is null) {
+                if (fDoubleClickSelection.x <= event.offset && event.offset <= fDoubleClickSelection.y)
+                    event.newOffset= fDoubleClickSelection.y;
+            }
+        }
+
+        /*
+         * @see dwt.custom.MovementListener#getPreviousOffset(dwt.custom.MovementEvent)
+         * @since 3.3
+         */
+        public void getPreviousOffset(MovementEvent event) {
+            if (event.movement !is DWT.MOVEMENT_WORD_START)
+                return;
+
+            if (TRACE_DOUBLE_CLICK) {
+                System.out_.println("\n---"); //$NON-NLS-1$
+                print(event);
+            }
+            if (fDoubleClickSelection is null) {
+                ITextDoubleClickStrategy s= cast(ITextDoubleClickStrategy) selectContentTypePlugin(getSelectedRange().x, fDoubleClickStrategies);
+                if (s !is null) {
+                    StyledText textWidget= getTextWidget();
+                    s.doubleClicked(this.outer);
+                    fDoubleClickSelection= textWidget.getSelection();
+                    event.newOffset= fDoubleClickSelection.x;
+                    if (TRACE_DOUBLE_CLICK)
+                        System.out_.println(Format("- setting selection: x= {}, y= {}", fDoubleClickSelection.x, fDoubleClickSelection.y)); //$NON-NLS-1$ //$NON-NLS-2$
+                }
+            } else {
+                if (fDoubleClickSelection.x <= event.offset && event.offset <= fDoubleClickSelection.y)
+                    event.newOffset= fDoubleClickSelection.x;
+            }
+        }
+    }
+
+    /**
+     * Print trace info about <code>MovementEvent</code>.
+     *
+     * @param e the event to print
+     * @since 3.3
+     */
+    private void print(MovementEvent e) {
+        System.out_.println(Format("line offset: {}", e.lineOffset)); //$NON-NLS-1$
+        System.out_.println(Format("line: {}", e.lineText)); //$NON-NLS-1$
+        System.out_.println(Format("type: {}", e.movement)); //$NON-NLS-1$
+        System.out_.println(Format("offset: {}",  e.offset)); //$NON-NLS-1$
+        System.out_.println(Format("newOffset: {}", e.newOffset)); //$NON-NLS-1$
+    }
+
+    /**
+     * Monitors the area of the viewer's document that is visible in the viewer.
+     * If the area might have changed, it informs the text viewer about this
+     * potential change and its origin. The origin is internally used for optimization
+     * purposes.
+     */
+    class ViewportGuard : MouseAdapter
+        , ControlListener, KeyListener, SelectionListener {
+
+        /*
+         * @see ControlListener#controlResized(ControlEvent)
+         */
+        public void controlResized(ControlEvent e) {
+            updateViewportListeners(RESIZE);
+        }
+
+        /*
+         * @see ControlListener#controlMoved(ControlEvent)
+         */
+        public void controlMoved(ControlEvent e) {
+        }
+
+        /*
+         * @see KeyListener#keyReleased
+         */
+        public void keyReleased(KeyEvent e) {
+            updateViewportListeners(KEY);
+        }
+
+        /*
+         * @see KeyListener#keyPressed
+         */
+        public void keyPressed(KeyEvent e) {
+            updateViewportListeners(KEY);
+        }
+
+        /*
+         * @see MouseListener#mouseUp
+         */
+        public void mouseUp(MouseEvent e) {
+            if (fTextWidget !is null)
+                fTextWidget.removeSelectionListener(this);
+            updateViewportListeners(MOUSE_END);
+        }
+
+        /*
+         * @see MouseListener#mouseDown
+         */
+        public void mouseDown(MouseEvent e) {
+            if (fTextWidget !is null)
+                fTextWidget.addSelectionListener(this);
+        }
+
+        /*
+         * @see SelectionListener#widgetSelected
+         */
+        public void widgetSelected(SelectionEvent e) {
+            if (e.widget is fScroller)
+                updateViewportListeners(SCROLLER);
+            else
+                updateViewportListeners(MOUSE);
+        }
+
+        /*
+         * @see SelectionListener#widgetDefaultSelected
+         */
+        public void widgetDefaultSelected(SelectionEvent e) {}
+    }
+
+    /**
+     * This position updater is used to keep the selection during text shift operations.
+     */
+    static class ShiftPositionUpdater : DefaultPositionUpdater {
+
+        /**
+         * Creates the position updater for the given category.
+         *
+         * @param category the category this updater takes care of
+         */
+        protected this(String category) {
+            super(category);
+        }
+
+        /**
+         * If an insertion happens at the selection's start offset,
+         * the position is extended rather than shifted.
+         */
+        protected void adaptToInsert() {
+
+            int myStart= fPosition.offset;
+            int myEnd=   fPosition.offset + fPosition.length -1;
+            myEnd= Math.max(myStart, myEnd);
+
+            int yoursStart= fOffset;
+            int yoursEnd=   fOffset + fReplaceLength -1;
+            yoursEnd= Math.max(yoursStart, yoursEnd);
+
+            if (myEnd < yoursStart)
+                return;
+
+            if (myStart <= yoursStart) {
+                fPosition.length += fReplaceLength;
+                return;
+            }
+
+            if (myStart > yoursStart)
+                fPosition.offset += fReplaceLength;
+        }
+    }
+
+    /**
+     * Internal document listener on the visible document.
+     */
+    class VisibleDocumentListener : IDocumentListener {
+
+        /*
+         * @see IDocumentListener#documentAboutToBeChanged
+         */
+        public void documentAboutToBeChanged(DocumentEvent e) {
+            if (e.getDocument() is getVisibleDocument())
+                fWidgetCommand.setEvent(e);
+            handleVisibleDocumentAboutToBeChanged(e);
+        }
+
+        /*
+         * @see IDocumentListener#documentChanged
+         */
+        public void documentChanged(DocumentEvent e) {
+            if (fWidgetCommand.event is e)
+                updateTextListeners(fWidgetCommand);
+            fLastSentSelectionChange= null;
+            handleVisibleDocumentChanged(e);
+        }
+    }
+
+    /**
+     * Internal verify listener.
+     */
+    class TextVerifyListener : VerifyListener {
+
+        /**
+         * Indicates whether verify events are forwarded or ignored.
+         * @since 2.0
+         */
+        private bool fForward= true;
+
+        /**
+         * Tells the listener to forward received events.
+         *
+         * @param forward <code>true</code> if forwarding should be enabled.
+         * @since 2.0
+         */
+        public void forward(bool forward) {
+            fForward= forward;
+        }
+
+        /*
+         * @see VerifyListener#verifyText(VerifyEvent)
+         */
+        public void verifyText(VerifyEvent e) {
+            if (fForward)
+                handleVerifyEvent(e);
+        }
+    }
+
+    /**
+     * The viewer's manager responsible for registered verify key listeners.
+     * Uses batches rather than robust iterators because of performance issues.
+     * <p>
+     * The implementation is reentrant, i.e. installed listeners may trigger
+     * further <code>VerifyKeyEvent</code>s that may cause other listeners to be
+     * installed, but not thread safe.
+     * </p>
+     * @since 2.0
+     */
+    class VerifyKeyListenersManager : VerifyKeyListener {
+
+        /**
+         * Represents a batched addListener/removeListener command.
+         */
+        class Batch {
+            /** The index at which to insert the listener. */
+            int index;
+            /** The listener to be inserted. */
+            VerifyKeyListener listener;
+
+            /**
+             * Creates a new batch containing the given listener for the given index.
+             *
+             * @param l the listener to be added
+             * @param i the index at which to insert the listener
+             */
+            public this(VerifyKeyListener l, int i) {
+                listener= l;
+                index= i;
+            }
+        }
+
+        /** List of registered verify key listeners. */
+        private List fListeners;
+        /** List of pending batches. */
+        private List fBatched;
+        /** The reentrance count. */
+        private int fReentranceCount= 0;
+
+        this(){
+            fListeners= new ArrayList();
+            fBatched= new ArrayList();
+        }
+
+        /*
+         * @see VerifyKeyListener#verifyKey(VerifyEvent)
+         */
+        public void verifyKey(VerifyEvent event) {
+            if (fListeners.isEmpty())
+                return;
+
+            try {
+                fReentranceCount++;
+                Iterator iterator= fListeners.iterator();
+                while (iterator.hasNext() && event.doit) {
+                    VerifyKeyListener listener= cast(VerifyKeyListener) iterator.next();
+                    listener.verifyKey(event); // we might trigger reentrant calls on GTK
+                }
+            } finally {
+                fReentranceCount--;
+            }
+            if (fReentranceCount is 0)
+                processBatchedRequests();
+        }
+
+        /**
+         * Processes the pending batched requests.
+         */
+        private void processBatchedRequests() {
+            if (!fBatched.isEmpty()) {
+                Iterator e= fBatched.iterator();
+                while (e.hasNext()) {
+                    Batch batch= cast(Batch) e.next();
+                    insertListener(batch.listener, batch.index);
+                }
+                fBatched.clear();
+            }
+        }
+
+        /**
+         * Returns the number of registered verify key listeners.
+         *
+         * @return the number of registered verify key listeners
+         */
+        public int numberOfListeners() {
+            return fListeners.size();
+        }
+
+        /**
+         * Inserts the given listener at the given index or moves it
+         * to that index.
+         *
+         * @param listener the listener to be inserted
+         * @param index the index of the listener or -1 for remove
+         */
+        public void insertListener(VerifyKeyListener listener, int index) {
+
+            if (index is -1) {
+                removeListener(listener);
+            } else if (listener !is null) {
+
+                if (fReentranceCount > 0) {
+
+                    fBatched.add(new Batch(listener, index));
+
+                } else {
+
+                    int idx= -1;
+
+                    // find index based on identity
+                    int size= fListeners.size();
+                    for (int i= 0; i < size; i++) {
+                        if (cast(Object)listener is fListeners.get(i)) {
+                            idx= i;
+                            break;
+                        }
+                    }
+
+                    // move or add it
+                    if (idx !is index) {
+
+                        if (idx !is -1)
+                            fListeners.remove(idx);
+
+                        if (index > fListeners.size())
+                            fListeners.add(cast(Object)listener);
+                        else
+                            fListeners.add(index, cast(Object)listener);
+                    }
+
+                    if (size is 0)  // checking old size, i.e. current size is size + 1
+                        install();
+                }
+            }
+        }
+
+        /**
+         * Removes the given listener.
+         *
+         * @param listener the listener to be removed
+         */
+        public void removeListener(VerifyKeyListener listener) {
+            if (listener is null)
+                return;
+
+            if (fReentranceCount > 0) {
+
+                fBatched.add(new Batch(listener, -1));
+
+            } else {
+
+                int size= fListeners.size();
+                for (int i= 0; i < size; i++) {
+                    if (cast(Object)listener is fListeners.get(i)) {
+                        fListeners.remove(i);
+                        if (size is 1)  // checking old size, i.e. current size is size - 1
+                            uninstall();
+                        return;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Installs this manager.
+         */
+        private void install() {
+            StyledText textWidget= getTextWidget();
+            if (textWidget !is null && !textWidget.isDisposed())
+                textWidget.addVerifyKeyListener(this);
+        }
+
+        /**
+         * Uninstalls this manager.
+         */
+        private void uninstall() {
+            StyledText textWidget= getTextWidget();
+            if (textWidget !is null && !textWidget.isDisposed())
+                textWidget.removeVerifyKeyListener(this);
+        }
+    }
+
+
+    /**
+     * Reification of a range in which a find replace operation is performed. This range is visually
+     * highlighted in the viewer as long as the replace operation is in progress.
+     *
+     * @since 2.0
+     */
+    class FindReplaceRange : LineBackgroundListener, ITextListener, IPositionUpdater {
+
+        /** Internal name for the position category used to update the range. */
+        private const static String RANGE_CATEGORY= "dwtx.jface.text.TextViewer.find.range"; //$NON-NLS-1$
+
+        /** The highlight color of this range. */
+        private Color fHighlightColor;
+        /** The position used to lively update this range's extent. */
+        private Position fPosition;
+
+        /** Creates a new find/replace range with the given extent.
+         *
+         * @param range the extent of this range
+         */
+        public this(IRegion range) {
+            setRange(range);
+        }
+
+        /**
+         * Sets the extent of this range.
+         *
+         * @param range the extent of this range
+         */
+        public void setRange(IRegion range) {
+            fPosition= new Position(range.getOffset(), range.getLength());
+        }
+
+        /**
+         * Returns the extent of this range.
+         *
+         * @return the extent of this range
+         */
+        public IRegion getRange() {
+            return new Region(fPosition.getOffset(), fPosition.getLength());
+        }
+
+        /**
+         * Sets the highlight color of this range. Causes the range to be redrawn.
+         *
+         * @param color the highlight color
+         */
+        public void setHighlightColor(Color color) {
+            fHighlightColor= color;
+            paint();
+        }
+
+        /*
+         * @see LineBackgroundListener#lineGetBackground(LineBackgroundEvent)
+         * @since 2.0
+         */
+        public void lineGetBackground(LineBackgroundEvent event) {
+            /* Don't use cached line information because of patched redrawing events. */
+
+            if (fTextWidget !is null) {
+                int offset= widgetOffset2ModelOffset(event.lineOffset);
+                if (fPosition.includes(offset))
+                    event.lineBackground= fHighlightColor;
+            }
+        }
+
+        /**
+         * Installs this range. The range registers itself as background
+         * line painter and text listener. Also, it creates a category with the
+         * viewer's document to maintain its own extent.
+         */
+        public void install() {
+            this.outer.addTextListener(this);
+            fTextWidget.addLineBackgroundListener(this);
+
+            IDocument document= this.outer.getDocument();
+            try {
+                document.addPositionCategory(RANGE_CATEGORY);
+                document.addPosition(RANGE_CATEGORY, fPosition);
+                document.addPositionUpdater(this);
+            } catch (BadPositionCategoryException e) {
+                // should not happen
+            } catch (BadLocationException e) {
+                // should not happen
+            }
+
+            paint();
+        }
+
+        /**
+         * Uninstalls this range.
+         * @see #install()
+         */
+        public void uninstall() {
+
+            // http://bugs.eclipse.org/bugs/show_bug.cgi?id=19612
+
+            IDocument document= this.outer.getDocument();
+            if (document !is null) {
+                document.removePositionUpdater(this);
+                document.removePosition(fPosition);
+            }
+
+            if (fTextWidget !is null && !fTextWidget.isDisposed())
+                fTextWidget.removeLineBackgroundListener(this);
+
+            this.outer.removeTextListener(this);
+
+            clear();
+        }
+
+        /**
+         * Clears the highlighting of this range.
+         */
+        private void clear() {
+            if (fTextWidget !is null && !fTextWidget.isDisposed())
+                fTextWidget.redraw();
+        }
+
+        /**
+         * Paints the highlighting of this range.
+         */
+        private void paint() {
+
+            IRegion widgetRegion= modelRange2WidgetRange(fPosition);
+            int offset= widgetRegion.getOffset();
+            int length= widgetRegion.getLength();
+
+            int count= fTextWidget.getCharCount();
+            if (offset + length >= count) {
+                length= count - offset; // clip
+
+                Point upperLeft= fTextWidget.getLocationAtOffset(offset);
+                Point lowerRight= fTextWidget.getLocationAtOffset(offset + length);
+                int width= fTextWidget.getClientArea().width;
+                int height= fTextWidget.getLineHeight(offset + length) + lowerRight.y - upperLeft.y;
+                fTextWidget.redraw(upperLeft.x, upperLeft.y, width, height, false);
+            }
+
+            fTextWidget.redrawRange(offset, length, true);
+        }
+
+        /*
+         * @see ITextListener#textChanged(TextEvent)
+         * @since 2.0
+         */
+        public void textChanged(TextEvent event) {
+            if (event.getViewerRedrawState())
+                paint();
+        }
+
+        /*
+         * @see IPositionUpdater#update(DocumentEvent)
+         * @since 2.0
+         */
+        public void update(DocumentEvent event) {
+            int offset= event.getOffset();
+            int length= event.getLength();
+            int delta= event.getText().length - length;
+
+            if (offset < fPosition.getOffset())
+                fPosition.setOffset(fPosition.getOffset() + delta);
+            else if (offset < fPosition.getOffset() + fPosition.getLength())
+                fPosition.setLength(fPosition.getLength() + delta);
+        }
+    }
+
+    /**
+     * This viewer's find/replace target.
+     */
+    class FindReplaceTarget : IFindReplaceTarget, IFindReplaceTargetExtension, IFindReplaceTargetExtension3 {
+
+        /** The range for this target. */
+        private FindReplaceRange fRange;
+        /** The highlight color of the range of this target. */
+        private Color fScopeHighlightColor;
+        /** The document partitioner remembered in case of a "Replace All". */
+        private Map fRememberedPartitioners;
+        /**
+         * The active rewrite session.
+         * @since 3.1
+         */
+        private DocumentRewriteSession fRewriteSession;
+
+        /*
+         * @see IFindReplaceTarget#getSelectionText()
+         */
+        public String getSelectionText() {
+            Point s= this.outer.getSelectedRange();
+            if (s.x > -1 && s.y > -1) {
+                try {
+                    IDocument document= this.outer.getDocument();
+                    return document.get(s.x, s.y);
+                } catch (BadLocationException x) {
+                }
+            }
+            return ""; //$NON-NLS-1$
+        }
+
+        /*
+         * @see IFindReplaceTarget#replaceSelection(String)
+         */
+        public void replaceSelection(String text) {
+            replaceSelection(text, false);
+        }
+
+        /*
+         * @see IFindReplaceTarget#replaceSelection(String)
+         */
+        public void replaceSelection(String text, bool regExReplace) {
+            Point s= this.outer.getSelectedRange();
+            if (s.x > -1 && s.y > -1) {
+                try {
+                    IRegion matchRegion= this.outer.getFindReplaceDocumentAdapter().replace(text, regExReplace);
+                    int length= -1;
+                    if (matchRegion !is null)
+                        length= matchRegion.getLength();
+
+                    if (text !is null && length > 0)
+                        this.outer.setSelectedRange(s.x, length);
+                } catch (BadLocationException x) {
+                }
+            }
+        }
+
+        /*
+         * @see IFindReplaceTarget#isEditable()
+         */
+        public bool isEditable() {
+            return this.outer.isEditable();
+        }
+
+        /*
+         * @see IFindReplaceTarget#getSelection()
+         */
+        public Point getSelection() {
+            Point modelSelection= this.outer.getSelectedRange();
+            Point widgetSelection= modelSelection2WidgetSelection(modelSelection);
+            return widgetSelection !is null ? widgetSelection : new Point(-1, -1);
+        }
+
+        /*
+         * @see IFindReplaceTarget#findAndSelect(int, String, bool, bool, bool)
+         */
+        public int findAndSelect(int widgetOffset, String findString, bool searchForward, bool caseSensitive, bool wholeWord) {
+            try {
+                return findAndSelect(widgetOffset, findString, searchForward, caseSensitive, wholeWord, false);
+            } catch (PatternSyntaxException x) {
+                return -1;
+            }
+        }
+
+        /*
+         * @see IFindReplaceTarget#findAndSelect(int, String, bool, bool, bool)
+         */
+        public int findAndSelect(int widgetOffset, String findString, bool searchForward, bool caseSensitive, bool wholeWord, bool regExSearch) {
+
+            int modelOffset= widgetOffset is -1 ? -1 : widgetOffset2ModelOffset(widgetOffset);
+
+            if (fRange !is null) {
+                IRegion range= fRange.getRange();
+                modelOffset= this.outer.findAndSelectInRange(modelOffset, findString, searchForward, caseSensitive, wholeWord, range.getOffset(), range.getLength(), regExSearch);
+            } else {
+                modelOffset= this.outer.findAndSelect(modelOffset, findString, searchForward, caseSensitive, wholeWord, regExSearch);
+            }
+
+            widgetOffset= modelOffset is -1 ? -1 : modelOffset2WidgetOffset(modelOffset);
+            return widgetOffset;
+        }
+
+        /*
+         * @see IFindReplaceTarget#canPerformFind()
+         */
+        public bool canPerformFind() {
+            return this.outer.canPerformFind();
+        }
+
+        /*
+         * @see IFindReplaceTargetExtension#beginSession()
+         * @since 2.0
+         */
+        public void beginSession() {
+            fRange= null;
+        }
+
+        /*
+         * @see IFindReplaceTargetExtension#endSession()
+         * @since 2.0
+         */
+        public void endSession() {
+            if (fRange !is null) {
+                fRange.uninstall();
+                fRange= null;
+            }
+        }
+
+        /*
+         * @see IFindReplaceTargetExtension#getScope()
+         * @since 2.0
+         */
+        public IRegion getScope() {
+            return fRange is null ? null : fRange.getRange();
+        }
+
+        /*
+         * @see IFindReplaceTargetExtension#getLineSelection()
+         * @since 2.0
+         */
+        public Point getLineSelection() {
+            Point point= this.outer.getSelectedRange();
+
+            try {
+                IDocument document= this.outer.getDocument();
+
+                // beginning of line
+                int line= document.getLineOfOffset(point.x);
+                int offset= document.getLineOffset(line);
+
+                // end of line
+                IRegion lastLineInfo= document.getLineInformationOfOffset(point.x + point.y);
+                int lastLine= document.getLineOfOffset(point.x + point.y);
+                int length;
+                if (lastLineInfo.getOffset() is point.x + point.y && lastLine > 0)
+                    length= document.getLineOffset(lastLine - 1) + document.getLineLength(lastLine - 1) - offset;
+                else
+                    length= lastLineInfo.getOffset() + lastLineInfo.getLength() - offset;
+
+                return new Point(offset, length);
+
+            } catch (BadLocationException e) {
+                // should not happen
+                return new Point(point.x, 0);
+            }
+        }
+
+        /*
+         * @see IFindReplaceTargetExtension#setSelection(int, int)
+         * @since 2.0
+         */
+        public void setSelection(int modelOffset, int modelLength) {
+            this.outer.setSelectedRange(modelOffset, modelLength);
+        }
+
+        /*
+         * @see IFindReplaceTargetExtension#setScope(IRegion)
+         * @since 2.0
+         */
+        public void setScope(IRegion scope_) {
+            if (fRange !is null)
+                fRange.uninstall();
+
+            if (scope_ is null) {
+                fRange= null;
+                return;
+            }
+
+            fRange= new FindReplaceRange(scope_);
+            fRange.setHighlightColor(fScopeHighlightColor);
+            fRange.install();
+        }
+
+        /*
+         * @see IFindReplaceTargetExtension#setScopeHighlightColor(Color)
+         * @since 2.0
+         */
+        public void setScopeHighlightColor(Color color) {
+            if (fRange !is null)
+                fRange.setHighlightColor(color);
+            fScopeHighlightColor= color;
+        }
+
+        /*
+         * @see IFindReplaceTargetExtension#setReplaceAllMode(bool)
+         * @since 2.0
+         */
+        public void setReplaceAllMode(bool replaceAll) {
+
+            // http://bugs.eclipse.org/bugs/show_bug.cgi?id=18232
+
+            IDocument document= this.outer.getDocument();
+
+            if (replaceAll) {
+
+                if ( cast(IDocumentExtension4)document ) {
+                    IDocumentExtension4 extension= cast(IDocumentExtension4) document;
+                    fRewriteSession= extension.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL);
+                } else {
+                    this.outer.setRedraw(false);
+                    this.outer.startSequentialRewriteMode(false);
+
+                    if (fUndoManager !is null)
+                        fUndoManager.beginCompoundChange();
+
+                    fRememberedPartitioners= TextUtilities.removeDocumentPartitioners(document);
+                }
+
+            } else {
+
+                if ( cast(IDocumentExtension4)document ) {
+                    IDocumentExtension4 extension= cast(IDocumentExtension4) document;
+                    extension.stopRewriteSession(fRewriteSession);
+                } else {
+                    this.outer.setRedraw(true);
+                    this.outer.stopSequentialRewriteMode();
+
+                    if (fUndoManager !is null)
+                        fUndoManager.endCompoundChange();
+
+                    if (fRememberedPartitioners !is null)
+                        TextUtilities.addDocumentPartitioners(document, fRememberedPartitioners);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * The viewer's rewrite target.
+     * @since 2.0
+     */
+    class RewriteTarget : IRewriteTarget {
+
+        /*
+         * @see dwtx.jface.text.IRewriteTarget#beginCompoundChange()
+         */
+        public void beginCompoundChange() {
+            if (fUndoManager !is null)
+                fUndoManager.beginCompoundChange();
+        }
+
+        /*
+         * @see dwtx.jface.text.IRewriteTarget#endCompoundChange()
+         */
+        public void endCompoundChange() {
+            if (fUndoManager !is null)
+                fUndoManager.endCompoundChange();
+        }
+
+        /*
+         * @see dwtx.jface.text.IRewriteTarget#getDocument()
+         */
+        public IDocument getDocument() {
+            return this.outer.getDocument();
+        }
+
+        /*
+         * @see dwtx.jface.text.IRewriteTarget#setRedraw(bool)
+         */
+        public void setRedraw(bool redraw) {
+            this.outer.setRedraw(redraw);
+        }
+    }
+
+    /**
+     * Value object used as key in the text hover configuration table. It is
+     * modifiable only inside this compilation unit to allow the reuse of created
+     * objects for efficiency reasons
+     *
+     * @since 2.1
+     */
+    protected class TextHoverKey {
+
+        /** The content type this key belongs to */
+        private String fContentType;
+        /** The state mask */
+        private int fStateMask;
+
+        /**
+         * Creates a new text hover key for the given content type and state mask.
+         *
+         * @param contentType the content type
+         * @param stateMask the state mask
+         */
+        protected this(String contentType, int stateMask) {
+            //Assert.isNotNull(contentType);
+            fContentType= contentType;
+            fStateMask= stateMask;
+        }
+
+        /*
+         * @see java.lang.Object#equals(java.lang.Object)
+         */
+        public override int opEquals(Object obj) {
+            if (obj is null || obj.classinfo !is this.classinfo )
+                return false;
+            TextHoverKey textHoverKey= cast(TextHoverKey)obj;
+            return textHoverKey.fContentType.equals(fContentType) && textHoverKey.fStateMask is fStateMask;
+        }
+
+        /*
+         * @see java.lang.Object#hashCode()
+         */
+        public override hash_t toHash() {
+            return fStateMask << 16 | .toHash(fContentType);
+        }
+
+        /**
+         * Sets the state mask of this text hover key.
+         *
+         * @param stateMask the state mask
+         */
+        private void setStateMask(int stateMask) {
+            fStateMask= stateMask;
+        }
+    }
+
+    /**
+     * Captures and remembers the viewer state (selection and visual position). {@link TextViewer.ViewerState}
+     * instances are normally used once and then discarded, similar to the following snippet:
+     * <pre>
+     * ViewerState state= new ViewerState(); // remember the state
+     * doStuff(); // operation that may call setRedraw() and perform complex document modifications
+     * state.restore(true); // restore the remembered state
+     * </pre>
+     *
+     * @since 3.3
+     */
+    private final class ViewerState {
+        /** The position tracking the selection. */
+        private Position fSelection;
+        /** <code>true</code> if {@link #fSelection} was originally backwards. */
+        private bool fReverseSelection;
+        /** <code>true</code> if the selection has been updated while in redraw(off) mode. */
+        private bool fSelectionSet;
+        /** The position tracking the visually stable line. */
+        private Position fStableLine;
+        /** The pixel offset of the stable line measured from the client area. */
+        private int fStablePixel;
+
+        /** The position updater for {@link #fSelection} and {@link #fStableLine}. */
+        private IPositionUpdater fUpdater;
+        /** The document that the position updater and the positions are registered with. */
+        private IDocument fUpdaterDocument;
+        /** The position category used by {@link #fUpdater}. */
+        private String fUpdaterCategory;
+
+        /**
+         * Creates a new viewer state instance and connects it to the current document.
+         */
+        public this() {
+            IDocument document= getDocument();
+            if (document !is null)
+                connect(document);
+        }
+
+        /**
+         * Returns the normalized selection, i.e. the the selection length is always non-negative.
+         *
+         * @return the normalized selection
+         */
+        public Point getSelection() {
+            if (fSelection is null)
+                return new Point(-1, -1);
+            return new Point(fSelection.getOffset(), fSelection.getLength());
+        }
+
+        /**
+         * Updates the selection.
+         *
+         * @param offset the new selection offset
+         * @param length the new selection length
+         */
+        public void updateSelection(int offset, int length) {
+            fSelectionSet= true;
+            if (fSelection is null)
+                fSelection= new Position(offset, length);
+            else
+                updatePosition(fSelection, offset, length);
+        }
+
+        /**
+         * Restores the state and disconnects it from the document. The selection is no longer
+         * tracked after this call.
+         *
+         * @param restoreViewport <code>true</code> to restore both selection and viewport,
+         *        <code>false</code> to only restore the selection
+         */
+        public void restore(bool restoreViewport) {
+            if (isConnected())
+                disconnect();
+            if (fSelection !is null) {
+                int offset= fSelection.getOffset();
+                int length= fSelection.getLength();
+                if (fReverseSelection) {
+                    offset-= length;
+                    length= -length;
+                }
+                setSelectedRange(offset, length);
+                if (restoreViewport)
+                    updateViewport();
+            }
+        }
+
+        /**
+         * Updates the viewport, trying to keep the
+         * {@linkplain StyledText#getLinePixel(int) line pixel} of the caret line stable. If the
+         * selection has been updated while in redraw(false) mode, the new selection is revealed.
+         */
+        private void updateViewport() {
+            if (fSelectionSet) {
+                revealRange(fSelection.getOffset(), fSelection.getLength());
+            } else if (fStableLine !is null) {
+                int stableLine;
+                try {
+                    stableLine= fUpdaterDocument.getLineOfOffset(fStableLine.getOffset());
+                } catch (BadLocationException x) {
+                    // ignore and return silently
+                    return;
+                }
+                int stableWidgetLine= getClosestWidgetLineForModelLine(stableLine);
+                if (stableWidgetLine is -1)
+                    return;
+                int linePixel= getTextWidget().getLinePixel(stableWidgetLine);
+                int delta= fStablePixel - linePixel;
+                int topPixel= getTextWidget().getTopPixel();
+                getTextWidget().setTopPixel(topPixel - delta);
+            }
+        }
+
+        /**
+         * Remembers the viewer state.
+         *
+         * @param document the document to remember the state of
+         */
+        private void connect(IDocument document) {
+            Assert.isLegal(document !is null);
+            Assert.isLegal(!isConnected());
+            fUpdaterDocument= document;
+            try {
+                fUpdaterCategory= SELECTION_POSITION_CATEGORY ~ Integer.toString(toHash());
+                fUpdater= new NonDeletingPositionUpdater(fUpdaterCategory);
+                fUpdaterDocument.addPositionCategory(fUpdaterCategory);
+                fUpdaterDocument.addPositionUpdater(fUpdater);
+
+                Point selectionRange= getSelectedRange();
+                fReverseSelection= selectionRange.y < 0;
+                int offset, length;
+                if (fReverseSelection) {
+                    offset= selectionRange.x + selectionRange.y;
+                    length= -selectionRange.y;
+                } else {
+                    offset= selectionRange.x;
+                    length= selectionRange.y;
+                }
+
+                fSelection= new Position(offset, length);
+                fSelectionSet= false;
+                fUpdaterDocument.addPosition(fUpdaterCategory, fSelection);
+
+                int stableLine= getStableLine();
+                int stableWidgetLine= modelLine2WidgetLine(stableLine);
+                fStablePixel= getTextWidget().getLinePixel(stableWidgetLine);
+                IRegion stableLineInfo= fUpdaterDocument.getLineInformation(stableLine);
+                fStableLine= new Position(stableLineInfo.getOffset(), stableLineInfo.getLength());
+                fUpdaterDocument.addPosition(fUpdaterCategory, fStableLine);
+            } catch (BadPositionCategoryException e) {
+                // cannot happen
+                Assert.isTrue(false);
+            } catch (BadLocationException e) {
+                // should not happen except on concurrent modification
+                // ignore and disconnect
+                disconnect();
+            }
+        }
+
+        /**
+         * Updates a position with the given information and clears its deletion state.
+         *
+         * @param position the position to update
+         * @param offset the new selection offset
+         * @param length the new selection length
+         */
+        private void updatePosition(Position position, int offset, int length) {
+            position.setOffset(offset);
+            position.setLength(length);
+            // http://bugs.eclipse.org/bugs/show_bug.cgi?id=32795
+            position.isDeleted_= false;
+        }
+
+        /**
+         * Returns the document line to keep visually stable. If the caret line is (partially)
+         * visible, it is returned, otherwise the topmost (partially) visible line is returned.
+         *
+         * @return the visually stable line of this viewer state
+         */
+        private int getStableLine() {
+            int stableLine; // the model line that we try to keep stable
+            int caretLine= getTextWidget().getLineAtOffset(getTextWidget().getCaretOffset());
+            if (caretLine < JFaceTextUtil.getPartialTopIndex(getTextWidget()) || caretLine > JFaceTextUtil.getPartialBottomIndex(getTextWidget())) {
+                stableLine= JFaceTextUtil.getPartialTopIndex(this.outer);
+            } else {
+                stableLine= widgetLine2ModelLine(caretLine);
+            }
+            return stableLine;
+        }
+
+        /**
+         * Returns <code>true</code> if the viewer state is being tracked, <code>false</code>
+         * otherwise.
+         *
+         * @return the tracking state
+         */
+        private bool isConnected() {
+            return fUpdater !is null;
+        }
+
+        /**
+         * Disconnects from the document.
+         */
+        private void disconnect() {
+            Assert.isTrue(isConnected());
+            try {
+                fUpdaterDocument.removePosition(fUpdaterCategory, fSelection);
+                fUpdaterDocument.removePosition(fUpdaterCategory, fStableLine);
+                fUpdaterDocument.removePositionUpdater(fUpdater);
+                fUpdater= null;
+                fUpdaterDocument.removePositionCategory(fUpdaterCategory);
+                fUpdaterCategory= null;
+            } catch (BadPositionCategoryException x) {
+                // cannot happen
+                Assert.isTrue(false);
+            }
+        }
+    }
+
+    /**
+     * Internal cursor listener i.e. aggregation of mouse and key listener.
+     *
+     * @since 3.0
+     */
+    private class CursorListener : KeyListener, MouseListener {
+
+        /**
+         * Installs this cursor listener.
+         */
+        private void install() {
+            if (fTextWidget !is null && !fTextWidget.isDisposed()) {
+                fTextWidget.addKeyListener(this);
+                fTextWidget.addMouseListener(this);
+            }
+        }
+
+        /**
+         * Uninstalls this cursor listener.
+         */
+        private void uninstall() {
+            if (fTextWidget !is null && !fTextWidget.isDisposed()) {
+                fTextWidget.removeKeyListener(this);
+                fTextWidget.removeMouseListener(this);
+            }
+        }
+
+        /*
+         * @see KeyListener#keyPressed(dwt.events.KeyEvent)
+         */
+        public void keyPressed(KeyEvent event) {
+        }
+
+        /*
+         * @see KeyListener#keyPressed(dwt.events.KeyEvent)
+         */
+        public void keyReleased(KeyEvent e) {
+            if (fTextWidget.getSelectionCount() is 0) {
+                fLastSentSelectionChange= null;
+                queuePostSelectionChanged(e.character is DWT.DEL);
+            }
+        }
+
+        /*
+         * @see MouseListener#mouseDoubleClick(dwt.events.MouseEvent)
+         */
+        public void mouseDoubleClick(MouseEvent e) {
+        }
+
+        /*
+         * @see MouseListener#mouseDown(dwt.events.MouseEvent)
+         */
+        public void mouseDown(MouseEvent e) {
+        }
+
+        /*
+         * @see MouseListener#mouseUp(dwt.events.MouseEvent)
+         */
+        public void mouseUp(MouseEvent event) {
+            if (fTextWidget.getSelectionCount() is 0)
+                queuePostSelectionChanged(false);
+        }
+    }
+
+    /**
+     * Internal listener to document rewrite session state changes.
+     * @since 3.1
+     */
+    private class DocumentRewriteSessionListener : IDocumentRewriteSessionListener {
+
+        /*
+         * @see dwtx.jface.text.IDocumentRewriteSessionListener#documentRewriteSessionChanged(dwtx.jface.text.DocumentRewriteSessionEvent)
+         */
+        public void documentRewriteSessionChanged(DocumentRewriteSessionEvent event) {
+            IRewriteTarget target= this.outer.getRewriteTarget();
+            // FIXME always use setRedraw to avoid flickering due to scrolling
+            // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=158746
+            bool toggleRedraw= true || event.getSession().getSessionType() !is DocumentRewriteSessionType.UNRESTRICTED_SMALL;
+            final bool viewportStabilize= !toggleRedraw;
+            if (DocumentRewriteSessionEvent.SESSION_START is event.getChangeType()) {
+                if (toggleRedraw)
+                    target.setRedraw(false);
+                target.beginCompoundChange();
+                if (viewportStabilize && fViewerState is null)
+                    fViewerState= new ViewerState();
+            } else if (DocumentRewriteSessionEvent.SESSION_STOP is event.getChangeType()) {
+                if (viewportStabilize && fViewerState !is null) {
+                    fViewerState.restore(true);
+                    fViewerState= null;
+                }
+                target.endCompoundChange();
+                if (toggleRedraw)
+                    target.setRedraw(true);
+            }
+        }
+    }
+
+
+    /**
+     * Identifies the scrollbars as originators of a view port change.
+     */
+    protected static final int SCROLLER=    1;
+    /**
+     * Identifies  mouse moves as originators of a view port change.
+     */
+    protected static final int MOUSE=       2;
+    /**
+     * Identifies mouse button up as originator of a view port change.
+     */
+    protected static final int MOUSE_END=   3;
+    /**
+     * Identifies key strokes as originators of a view port change.
+     */
+    protected static final int KEY=         4;
+    /**
+     * Identifies window resizing as originator of a view port change.
+     */
+    protected static final int RESIZE=      5;
+    /**
+     * Identifies internal reasons as originators of a view port change.
+     */
+    protected static final int INTERNAL=    6;
+
+    /** Internal name of the position category used selection preservation during shift. */
+    protected static final String SHIFTING= "__TextViewer_shifting"; //$NON-NLS-1$
+
+    /**
+     * Base position category name used by the selection updater
+     * @since 3.1
+     */
+    private static const String SELECTION_POSITION_CATEGORY= "_textviewer_selection_category"; //$NON-NLS-1$
+    /** The viewer's text widget */
+    private StyledText fTextWidget;
+    /** The viewer's input document */
+    private IDocument fDocument;
+    /** The viewer's visible document */
+    private IDocument fVisibleDocument;
+    /** The viewer's document adapter */
+    private IDocumentAdapter fDocumentAdapter;
+    /** The slave document manager */
+    private ISlaveDocumentManager fSlaveDocumentManager;
+    /** The text viewer's double click strategies connector */
+    private TextDoubleClickStrategyConnector fDoubleClickStrategyConnector;
+    /** The text viewer's view port guard */
+    private ViewportGuard fViewportGuard;
+    /** Caches the graphical coordinate of the first visible line */
+    private int fTopInset= 0;
+    /** The most recent document modification as widget command */
+    private WidgetCommand fWidgetCommand;
+    /** The DWT control's scrollbars */
+    private ScrollBar fScroller;
+    /** Listener on the visible document */
+    private VisibleDocumentListener fVisibleDocumentListener;
+    /** Verify listener */
+    private TextVerifyListener fVerifyListener;
+    /** The most recent widget modification as document command */
+    private DocumentCommand fDocumentCommand;
+    /** The viewer's find/replace target */
+    private IFindReplaceTarget fFindReplaceTarget;
+    /**
+     * The text viewer's hovering controller
+     * @since 2.0
+     */
+    private TextViewerHoverManager fTextHoverManager;
+    /**
+     * The viewer widget token keeper
+     * @since 2.0
+     */
+    private IWidgetTokenKeeper fWidgetTokenKeeper;
+    /**
+     * The viewer's manager of verify key listeners
+     * @since 2.0
+     */
+    private VerifyKeyListenersManager fVerifyKeyListenersManager;
+    /**
+     * The mark position.
+     * @since 2.0
+     */
+    protected Position fMarkPosition;
+    /**
+     * The mark position category.
+     * @since 2.0
+     */
+    private /+const+/ String MARK_POSITION_CATEGORY;
+    /**
+     * The mark position updater
+     * @since 2.0
+     */
+    private /+const+/ IPositionUpdater fMarkPositionUpdater;
+    /**
+     * The flag indicating the redraw behavior
+     * @since 2.0
+     */
+    private int fRedrawCounter= 0;
+    /**
+     * The viewer's rewrite target
+     * @since 2.0
+     */
+    private IRewriteTarget fRewriteTarget;
+    /**
+     * The viewer's cursor listener.
+     * @since 3.0
+     */
+    private CursorListener fCursorListener;
+    /**
+     * Last selection range sent to selection change listeners.
+     * @since 3.0
+     */
+    private IRegion fLastSentSelectionChange;
+    /**
+     * The registered post selection changed listeners.
+     * @since 3.0
+     */
+    private List fPostSelectionChangedListeners;
+    /**
+     * Queued post selection changed events count.
+     * @since 3.0
+     */
+    private /+const+/ int[] fNumberOfPostSelectionChangedEvents;
+    /**
+     * Last selection range sent to post selection change listeners.
+     * @since 3.0
+     */
+    private IRegion fLastSentPostSelectionChange;
+    /**
+     * The set of registered editor helpers.
+     * @since 3.1
+     */
+    private Set fEditorHelpers;
+    /**
+     * The internal rewrite session listener.
+     * @since 3.1
+     */
+    private DocumentRewriteSessionListener fDocumentRewriteSessionListener;
+
+    /** Should the auto indent strategies ignore the next edit operation */
+    protected bool  fIgnoreAutoIndent= false;
+    /** The strings a line is prefixed with on SHIFT_RIGHT and removed from each line on SHIFT_LEFT */
+    protected Map fIndentChars;
+    /** The string a line is prefixed with on PREFIX and removed from each line on STRIP_PREFIX */
+    protected Map fDefaultPrefixChars;
+    /** The text viewer's text double click strategies */
+    protected Map fDoubleClickStrategies;
+    /** The text viewer's undo manager */
+    protected IUndoManager fUndoManager;
+    /** The text viewer's auto indent strategies */
+    protected Map fAutoIndentStrategies;
+    /** The text viewer's text hovers */
+    protected Map fTextHovers;
+    /** All registered view port listeners> */
+    protected List fViewportListeners;
+    /** The last visible vertical position of the top line */
+    protected int fLastTopPixel;
+    /** All registered text listeners */
+    protected List fTextListeners;
+    /** All registered text input listeners */
+    protected List fTextInputListeners;
+    /** The text viewer's event consumer */
+    protected IEventConsumer fEventConsumer;
+    /** Indicates whether the viewer's text presentation should be replaced are modified. */
+    protected bool fReplaceTextPresentation= false;
+    /**
+     * The creator of the text hover control
+     * @since 2.0
+     */
+    protected IInformationControlCreator fHoverControlCreator;
+    /**
+     * The mapping between model and visible document.
+     * @since 2.1
+     */
+    protected IDocumentInformationMapping fInformationMapping;
+    /**
+     * The viewer's paint manager.
+     * @since 2.1
+     */
+    protected PaintManager fPaintManager;
+    /**
+     * The viewers partitioning. I.e. the partitioning name the viewer uses to access partitioning information of its input document.
+     * @since 3.0
+     */
+    protected String fPartitioning;
+    /**
+     * All registered text presentation listeners.
+     * since 3.0
+     */
+    protected List fTextPresentationListeners;
+    /**
+     * The find/replace document adapter.
+     * @since 3.0
+     */
+    protected FindReplaceDocumentAdapter fFindReplaceDocumentAdapter;
+
+    /**
+     * The text viewer's hyperlink detectors.
+     * @since 3.1
+     */
+    protected IHyperlinkDetector[] fHyperlinkDetectors;
+    /**
+     * The text viewer's hyperlink presenter.
+     * @since 3.1
+     */
+    protected IHyperlinkPresenter fHyperlinkPresenter;
+    /**
+     * The text viewer's hyperlink manager.
+     * @since 3.1
+     */
+    protected HyperlinkManager fHyperlinkManager;
+    /**
+     * The DWT key modifier mask which in combination
+     * with the left mouse button triggers the hyperlink mode.
+     * @since 3.1
+     */
+    protected int fHyperlinkStateMask;
+    /**
+     * The viewer state when in non-redraw state, <code>null</code> otherwise.
+     * @since 3.3
+     */
+    private ViewerState fViewerState;
+    /**
+     * The editor's tab converter.
+     * @since 3.3
+     */
+    private IAutoEditStrategy fTabsToSpacesConverter;
+
+
+    //---- Construction and disposal ------------------
+
+    private void instanceInit(){
+        fWidgetCommand= new WidgetCommand();
+        fVisibleDocumentListener= new VisibleDocumentListener();
+        fVerifyListener= new TextVerifyListener();
+        fDocumentCommand= new DocumentCommand();
+        fVerifyKeyListenersManager= new VerifyKeyListenersManager();
+        MARK_POSITION_CATEGORY=Format("__mark_category_{}", toHash()); //$NON-NLS-1$
+        fMarkPositionUpdater= new DefaultPositionUpdater(MARK_POSITION_CATEGORY);
+        fDocumentRewriteSessionListener= new DocumentRewriteSessionListener();
+        fNumberOfPostSelectionChangedEvents= new int[1];
+        fEditorHelpers= new HashSet();
+    }
+    /**
+     * Internal use only
+     */
+    protected this() {
+        instanceInit();
+    }
+
+    /**
+     * Create a new text viewer with the given DWT style bits.
+     * The viewer is ready to use but does not have any plug-in installed.
+     *
+     * @param parent the parent of the viewer's control
+     * @param styles the DWT style bits for the viewer's control,
+     *          <em>if <code>DWT.WRAP</code> is set then a custom document adapter needs to be provided, see {@link #createDocumentAdapter()}
+     */
+    public this(Composite parent, int styles) {
+        instanceInit();
+        createControl(parent, styles);
+    }
+
+    /**
+     * Factory method to create the text widget to be used as the viewer's text widget.
+     *
+     * @param parent the parent of the styled text
+     * @param styles the styles for the styled text
+     * @return the text widget to be used
+     */
+    protected StyledText createTextWidget(Composite parent, int styles) {
+        return new StyledText(parent, styles);
+    }
+
+    /**
+     * Factory method to create the document adapter to be used by this viewer.
+     *
+     * @return the document adapter to be used
+     */
+    protected IDocumentAdapter createDocumentAdapter() {
+        return new DefaultDocumentAdapter();
+    }
+
+    /**
+     * Creates the viewer's DWT control. The viewer's text widget either is
+     * the control or is a child of the control.
+     *
+     * @param parent the parent of the viewer's control
+     * @param styles the DWT style bits for the viewer's control
+     */
+    protected void createControl(Composite parent, int styles) {
+
+        fTextWidget= createTextWidget(parent, styles);
+
+        // Support scroll page upon MOD1+MouseWheel
+        fTextWidget.addListener(DWT.MouseWheel, new class()  Listener {
+
+            public void handleEvent(Event event) {
+                if (((event.stateMask & DWT.MOD1) is 0))
+                    return;
+
+                int topIndex= fTextWidget.getTopIndex();
+                int bottomIndex= JFaceTextUtil.getBottomIndex(fTextWidget);
+
+                if (event.count > 0)
+                    fTextWidget.setTopIndex(2 * topIndex - bottomIndex);
+                else
+                    fTextWidget.setTopIndex(bottomIndex);
+
+                updateViewportListeners(INTERNAL);
+            }
+        });
+
+        fTextWidget.addDisposeListener(
+            new class()  DisposeListener {
+                public void widgetDisposed(DisposeEvent e) {
+                    handleDispose();
+                }
+            }
+        );
+
+        fTextWidget.setFont(parent.getFont());
+        fTextWidget.setDoubleClickEnabled(true);
+
+        /*
+         * Disable DWT Shift+TAB traversal in this viewer
+         * 1GIYQ9K: ITPUI:WINNT - StyledText swallows Shift+TAB
+         */
+        fTextWidget.addTraverseListener(new class()  TraverseListener {
+            public void keyTraversed(TraverseEvent e) {
+                if ((DWT.SHIFT is e.stateMask) && ('\t' is e.character))
+                    e.doit= false;
+            }
+        });
+
+        // where does the first line start
+        fTopInset= -fTextWidget.computeTrim(0, 0, 0, 0).y;
+
+        fVerifyListener.forward(true);
+        fTextWidget.addVerifyListener(fVerifyListener);
+
+        fTextWidget.addSelectionListener(new class()  SelectionListener {
+            public void widgetDefaultSelected(SelectionEvent event) {
+                selectionChanged(event.x, event.y - event.x);
+            }
+            public void widgetSelected(SelectionEvent event) {
+                selectionChanged(event.x, event.y - event.x);
+            }
+        });
+
+        fCursorListener= new CursorListener();
+        fCursorListener.install();
+
+        initializeViewportUpdate();
+    }
+
+    /*
+     * @see Viewer#getControl()
+     */
+    public Control getControl() {
+        return fTextWidget;
+    }
+
+    /*
+     * @see ITextViewer#activatePlugins()
+     */
+    public void activatePlugins() {
+
+        if (fDoubleClickStrategies !is null && !fDoubleClickStrategies.isEmpty() && fDoubleClickStrategyConnector is null) {
+            fDoubleClickStrategyConnector= new TextDoubleClickStrategyConnector();
+            fTextWidget.addWordMovementListener(fDoubleClickStrategyConnector);
+            fTextWidget.addMouseListener(fDoubleClickStrategyConnector);
+        }
+
+        ensureHoverControlManagerInstalled();
+        ensureHyperlinkManagerInstalled();
+
+        if (fUndoManager !is null) {
+            fUndoManager.connect(this);
+            fUndoManager.reset();
+        }
+    }
+
+    /**
+     * After this method has been executed the caller knows that any installed text hover has been installed.
+     */
+    private void ensureHoverControlManagerInstalled() {
+        if (fTextHovers !is null && !fTextHovers.isEmpty() && fHoverControlCreator !is null && fTextHoverManager is null) {
+            fTextHoverManager= new TextViewerHoverManager(this, fHoverControlCreator);
+            fTextHoverManager.install(this.getTextWidget());
+            fTextHoverManager.setSizeConstraints(TEXT_HOVER_WIDTH_CHARS, TEXT_HOVER_HEIGHT_CHARS, false, true);
+            fTextHoverManager.setInformationControlReplacer(new StickyHoverManager(this));
+        }
+    }
+
+    /*
+     * @see ITextViewer#resetPlugins()
+     */
+    public void resetPlugins() {
+        if (fUndoManager !is null)
+            fUndoManager.reset();
+    }
+
+    /**
+     * Frees all resources allocated by this viewer. Internally called when the viewer's
+     * control has been disposed.
+     */
+    protected void handleDispose() {
+
+        setDocument(null);
+
+        if (fPaintManager !is null) {
+            fPaintManager.dispose();
+            fPaintManager= null;
+        }
+
+        removeViewPortUpdate();
+        fViewportGuard= null;
+
+        if (fViewportListeners !is null) {
+            fViewportListeners.clear();
+            fViewportListeners= null;
+        }
+
+        if (fTextListeners !is null) {
+            fTextListeners.clear();
+            fTextListeners= null;
+        }
+
+        if (fTextInputListeners !is null)  {
+            fTextInputListeners.clear();
+            fTextInputListeners= null;
+        }
+
+        if (fPostSelectionChangedListeners !is null)  {
+            fPostSelectionChangedListeners.clear();
+            fPostSelectionChangedListeners= null;
+        }
+
+        if (fAutoIndentStrategies !is null) {
+            fAutoIndentStrategies.clear();
+            fAutoIndentStrategies= null;
+        }
+
+        if (fUndoManager !is null) {
+            fUndoManager.disconnect();
+            fUndoManager= null;
+        }
+
+        if (fDoubleClickStrategies !is null) {
+            fDoubleClickStrategies.clear();
+            fDoubleClickStrategies= null;
+        }
+
+        if (fTextHovers !is null) {
+            fTextHovers.clear();
+            fTextHovers= null;
+        }
+
+        fDoubleClickStrategyConnector= null;
+
+        if (fTextHoverManager !is null) {
+            fTextHoverManager.dispose();
+            fTextHoverManager= null;
+        }
+
+        if (fVisibleDocumentListener !is null) {
+            if (fVisibleDocument !is null)
+                fVisibleDocument.removeDocumentListener(fVisibleDocumentListener);
+            fVisibleDocumentListener= null;
+        }
+
+        if (fDocumentAdapter !is null) {
+            fDocumentAdapter.setDocument(null);
+            fDocumentAdapter= null;
+        }
+
+        if (fSlaveDocumentManager !is null) {
+            if (fVisibleDocument !is null)
+                fSlaveDocumentManager.freeSlaveDocument(fVisibleDocument);
+            fSlaveDocumentManager= null;
+        }
+
+        if (fCursorListener !is null) {
+            fCursorListener.uninstall();
+            fCursorListener= null;
+        }
+
+        if (fHyperlinkManager !is null) {
+            fHyperlinkManager.uninstall();
+            fHyperlinkManager= null;
+        }
+
+        fHyperlinkDetectors= null;
+        fVisibleDocument= null;
+        fDocument= null;
+        fScroller= null;
+
+        fTextWidget= null;
+    }
+
+
+    //---- simple getters and setters
+
+    /*
+     * @see dwtx.jface.text.ITextViewer#getTextWidget()
+     */
+    public StyledText getTextWidget() {
+        return fTextWidget;
+    }
+
+    /**
+     * The delay in milliseconds before an empty selection
+     * changed event is sent by the cursor listener.
+     * <p>
+     * Note: The return value is used to initialize the cursor
+     * listener. To return a non-constant value has no effect.</p>
+     * <p>
+     * The same value (<code>500</code>) is used in <code>OpenStrategy.TIME</code>.</p>
+     *
+     * @return delay in milliseconds
+     * @see dwtx.jface.util.OpenStrategy
+     * @since 3.0
+     */
+    protected int getEmptySelectionChangedEventDelay() {
+        return 500;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @deprecated since 3.1, use
+     *             {@link ITextViewerExtension2#prependAutoEditStrategy(IAutoEditStrategy, String)} and
+     *             {@link ITextViewerExtension2#removeAutoEditStrategy(IAutoEditStrategy, String)} instead
+     */
+    public void setAutoIndentStrategy(IAutoIndentStrategy strategy, String contentType) {
+        setAutoEditStrategies([ strategy ], contentType);
+    }
+
+    /**
+     * Sets the given edit strategy as the only strategy for the given content type.
+     *
+     * @param strategies the auto edit strategies
+     * @param contentType the content type
+     * @since 3.1
+     */
+    protected final void setAutoEditStrategies(IAutoEditStrategy[] strategies, String contentType) {
+        if (fAutoIndentStrategies is null)
+            fAutoIndentStrategies= new HashMap();
+
+        List autoEditStrategies= cast(List) fAutoIndentStrategies.get(contentType);
+
+        if (strategies is null) {
+            if (autoEditStrategies is null)
+                return;
+
+            fAutoIndentStrategies.put(contentType, cast(Object)null);
+
+        } else {
+            if (autoEditStrategies is null) {
+                autoEditStrategies= new ArrayList();
+                fAutoIndentStrategies.put(contentType, cast(Object)autoEditStrategies);
+            }
+
+            autoEditStrategies.clear();
+            autoEditStrategies.addAll(Arrays.asList(arraycast!(Object)(strategies)));
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextViewerExtension2#prependAutoEditStrategy(dwtx.jface.text.IAutoEditStrategy, java.lang.String)
+     * @since 2.1
+     */
+    public void prependAutoEditStrategy(IAutoEditStrategy strategy, String contentType) {
+
+        if (strategy is null || contentType is null)
+            throw new IllegalArgumentException("");
+
+        if (fAutoIndentStrategies is null)
+            fAutoIndentStrategies= new HashMap();
+
+        List autoEditStrategies= cast(List) fAutoIndentStrategies.get(contentType);
+        if (autoEditStrategies is null) {
+            autoEditStrategies= new ArrayList();
+            fAutoIndentStrategies.put(contentType,cast(Object) autoEditStrategies);
+        }
+
+        autoEditStrategies.add(0, cast(Object)strategy);
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextViewerExtension2#removeAutoEditStrategy(dwtx.jface.text.IAutoEditStrategy, java.lang.String)
+     * @since 2.1
+     */
+    public void removeAutoEditStrategy(IAutoEditStrategy strategy, String contentType) {
+        if (fAutoIndentStrategies is null)
+            return;
+
+        List autoEditStrategies= cast(List) fAutoIndentStrategies.get(contentType);
+        if (autoEditStrategies is null)
+            return;
+
+        for (final Iterator iterator= autoEditStrategies.iterator(); iterator.hasNext(); ) {
+            if (iterator.next().opEquals(cast(Object)strategy)) {
+                iterator.remove();
+                break;
+            }
+        }
+
+        if (autoEditStrategies.isEmpty())
+            fAutoIndentStrategies.put(contentType, cast(Object)null);
+    }
+
+    /*
+     * @see ITextViewer#setEventConsumer(IEventConsumer)
+     */
+    public void setEventConsumer(IEventConsumer consumer) {
+        fEventConsumer= consumer;
+    }
+
+    /*
+     * @see ITextViewer#setIndentPrefixes(String[], String)
+     */
+    public void setIndentPrefixes(String[] indentPrefixes, String contentType) {
+
+        int i= -1;
+        bool ok= (indentPrefixes !is null);
+        while (ok &&  ++i < indentPrefixes.length)
+            ok= (indentPrefixes[i] !is null);
+
+        if (ok) {
+
+            if (fIndentChars is null)
+                fIndentChars= new HashMap();
+
+            fIndentChars.put(contentType, new ArrayWrapperObject( stringcast(indentPrefixes)));
+
+        } else if (fIndentChars !is null)
+            fIndentChars.remove(contentType);
+    }
+
+    /*
+     * @see ITextViewer#getTopInset()
+     */
+    public int getTopInset() {
+        return fTopInset;
+    }
+
+    /*
+     * @see ITextViewer#isEditable()
+     */
+    public bool isEditable() {
+        if (fTextWidget is null)
+            return false;
+        return fTextWidget.getEditable();
+    }
+
+    /*
+     * @see ITextViewer#setEditable(bool)
+     */
+    public void setEditable(bool editable) {
+        if (fTextWidget !is null)
+            fTextWidget.setEditable(editable);
+    }
+
+    /*
+     * @see ITextViewer#setDefaultPrefixes
+     * @since 2.0
+     */
+    public void setDefaultPrefixes(String[] defaultPrefixes, String contentType) {
+
+        if (defaultPrefixes !is null && defaultPrefixes.length > 0) {
+            if (fDefaultPrefixChars is null)
+                fDefaultPrefixChars= new HashMap();
+            fDefaultPrefixChars.put(contentType, new ArrayWrapperObject( stringcast(defaultPrefixes)));
+        } else if (fDefaultPrefixChars !is null)
+            fDefaultPrefixChars.remove(contentType);
+    }
+
+    /*
+     * @see ITextViewer#setUndoManager(IUndoManager)
+     */
+    public void setUndoManager(IUndoManager undoManager) {
+        fUndoManager= undoManager;
+    }
+
+    /*
+     * @see ITextViewerExtension6#getUndoManager()
+     * @since 3.1
+     */
+    public IUndoManager getUndoManager() {
+        return fUndoManager;
+    }
+
+    /*
+     * @see ITextViewer#setTextHover(ITextHover, String)
+     */
+    public void setTextHover(ITextHover hover, String contentType) {
+        setTextHover(hover, contentType, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
+    }
+
+    /*
+     * @see ITextViewerExtension2#setTextHover(ITextHover, String, int)
+     * @since 2.1
+     */
+    public void setTextHover(ITextHover hover, String contentType, int stateMask) {
+        TextHoverKey key= new TextHoverKey(contentType, stateMask);
+        if (hover !is null) {
+            if (fTextHovers is null) {
+                fTextHovers= new HashMap();
+            }
+            fTextHovers.put(key, cast(Object)hover);
+        } else if (fTextHovers !is null)
+            fTextHovers.remove(key);
+
+        ensureHoverControlManagerInstalled();
+    }
+
+    /*
+     * @see ITextViewerExtension2#removeTextHovers(String)
+     * @since 2.1
+     */
+    public void removeTextHovers(String contentType) {
+        if (fTextHovers is null)
+            return;
+
+        Iterator iter= (new HashSet(fTextHovers.keySet())).iterator();
+        while (iter.hasNext()) {
+            TextHoverKey key= cast(TextHoverKey)iter.next();
+            if (key.fContentType.equals(contentType))
+                fTextHovers.remove(key);
+        }
+    }
+
+    /**
+     * Returns the text hover for a given offset.
+     *
+     * @param offset the offset for which to return the text hover
+     * @return the text hover for the given offset
+     */
+    protected ITextHover getTextHover(int offset) {
+        return getTextHover(offset, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
+    }
+    package ITextHover getTextHover_package(int offset) {
+        return getTextHover(offset);
+    }
+
+    /**
+     * Returns the text hover for a given offset and a given state mask.
+     *
+     * @param offset the offset for which to return the text hover
+     * @param stateMask the DWT event state mask
+     * @return the text hover for the given offset and state mask
+     * @since 2.1
+     */
+    package ITextHover getTextHover_package(int offset, int stateMask) {
+        return getTextHover(offset,stateMask);
+    }
+    protected ITextHover getTextHover(int offset, int stateMask) {
+        if (fTextHovers is null)
+            return null;
+
+        IDocument document= getDocument();
+        if (document is null)
+            return null;
+
+        try {
+            TextHoverKey key= new TextHoverKey(TextUtilities.getContentType(document, getDocumentPartitioning(), offset, true), stateMask);
+            Object textHover= fTextHovers.get(key);
+            if (textHover is null) {
+                // Use default text hover
+                key.setStateMask(ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
+                textHover= fTextHovers.get(key);
+            }
+            return cast(ITextHover) textHover;
+        } catch (BadLocationException x) {
+            if (TRACE_ERRORS)
+                System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.selectContentTypePlugin")); //$NON-NLS-1$
+        }
+        return null;
+    }
+
+    /**
+     * Returns the text hovering controller of this viewer.
+     *
+     * @return the text hovering controller of this viewer
+     * @since 2.0
+     */
+    protected AbstractInformationControlManager getTextHoveringController() {
+        return fTextHoverManager;
+    }
+
+    /**
+     * Sets the creator for the hover controls.
+     *
+     * @param creator the hover control creator
+     * @since 2.0
+     */
+    public void setHoverControlCreator(IInformationControlCreator creator) {
+        fHoverControlCreator= creator;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 3.4
+     */
+    public void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode) {
+        if (fTextHoverManager is null)
+            return;
+        fTextHoverManager.setHoverEnrichMode(mode);
+    }
+
+    /*
+     * @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper)
+     * @since 2.0
+     */
+     public bool requestWidgetToken(IWidgetTokenKeeper requester) {
+         if (fTextWidget !is null) {
+             if (fWidgetTokenKeeper !is null) {
+                 if (fWidgetTokenKeeper is requester)
+                     return true;
+                 if (fWidgetTokenKeeper.requestWidgetToken(this)) {
+                     fWidgetTokenKeeper= requester;
+                     return true;
+                 }
+            } else {
+                fWidgetTokenKeeper= requester;
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenOwnerExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenKeeper, int)
+     * @since 3.0
+     */
+    public bool requestWidgetToken(IWidgetTokenKeeper requester, int priority) {
+        if (fTextWidget !is null) {
+            if (fWidgetTokenKeeper !is null) {
+
+                if (fWidgetTokenKeeper is requester)
+                    return true;
+
+                bool accepted= false;
+                if ( cast(IWidgetTokenKeeperExtension)fWidgetTokenKeeper )  {
+                    IWidgetTokenKeeperExtension extension= cast(IWidgetTokenKeeperExtension) fWidgetTokenKeeper;
+                    accepted= extension.requestWidgetToken(this, priority);
+                } else  {
+                    accepted= fWidgetTokenKeeper.requestWidgetToken(this);
+                }
+
+                if (accepted) {
+                    fWidgetTokenKeeper= requester;
+                    return true;
+                }
+
+           } else {
+               fWidgetTokenKeeper= requester;
+               return true;
+           }
+       }
+       return false;
+   }
+
+    /*
+     * @see IWidgetTokenOwner#releaseWidgetToken(IWidgetTokenKeeper)
+     * @since 2.0
+     */
+    public void releaseWidgetToken(IWidgetTokenKeeper tokenKeeper) {
+        if (fWidgetTokenKeeper is tokenKeeper)
+            fWidgetTokenKeeper= null;
+    }
+
+
+    //---- Selection
+
+    /*
+     * @see ITextViewer#getSelectedRange()
+     */
+    public Point getSelectedRange() {
+
+        if (!redraws() && fViewerState !is null)
+            return fViewerState.getSelection();
+
+        if (fTextWidget !is null) {
+            Point p= fTextWidget.getSelectionRange();
+            p= widgetSelection2ModelSelection(p);
+            if (p !is null)
+                return p;
+        }
+
+        return new Point(-1, -1);
+    }
+
+    /*
+     * @see ITextViewer#setSelectedRange(int, int)
+     */
+    public void setSelectedRange(int selectionOffset, int selectionLength) {
+
+        if (!redraws()) {
+            if (fViewerState !is null)
+                fViewerState.updateSelection(selectionOffset, selectionLength);
+            return;
+        }
+
+        if (fTextWidget is null)
+            return;
+
+        IRegion widgetSelection= modelRange2ClosestWidgetRange(new Region(selectionOffset, selectionLength));
+        if (widgetSelection !is null) {
+
+            int[] selectionRange= [ widgetSelection.getOffset(), widgetSelection.getLength() ];
+            validateSelectionRange(selectionRange);
+            if (selectionRange[0] >= 0) {
+                fTextWidget.setSelectionRange(selectionRange[0], selectionRange[1]);
+                selectionChanged(selectionRange[0], selectionRange[1]);
+            }
+        }
+    }
+
+    /**
+     * Validates and adapts the given selection range if it is not a valid
+     * widget selection. The widget selection is invalid if it starts or ends
+     * inside a multi-character line delimiter. If so, the selection is adapted to
+     * start <b>after</b> the divided line delimiter and to end <b>before</b>
+     * the divided line delimiter.  The parameter passed in is changed in-place
+     * when being adapted. An adaptation to <code>[-1, -1]</code> indicates
+     * that the selection range could not be validated.
+     * Subclasses may reimplement this method.
+     *
+     * @param selectionRange selectionRange[0] is the offset, selectionRange[1]
+     *              the length of the selection to validate.
+     * @since 2.0
+     */
+    protected void validateSelectionRange(int[] selectionRange) {
+
+        IDocument document= getVisibleDocument();
+        if (document is null) {
+            selectionRange[0]= -1;
+            selectionRange[1]= -1;
+            return;
+        }
+
+        int documentLength= document.getLength();
+        int offset= selectionRange[0];
+        int length= selectionRange[1];
+
+        if (length < 0) {
+            length= - length;
+            offset -= length;
+        }
+
+        if (offset <0)
+            offset= 0;
+
+        if (offset > documentLength)
+            offset= documentLength;
+
+        int delta= (offset + length) - documentLength;
+        if (delta > 0)
+            length -= delta;
+
+        try {
+
+            int lineNumber= document.getLineOfOffset(offset);
+            IRegion lineInformation= document.getLineInformation(lineNumber);
+
+            int lineEnd= lineInformation.getOffset() + lineInformation.getLength();
+            delta= offset - lineEnd;
+            if (delta > 0) {
+                // in the middle of a multi-character line delimiter
+                offset= lineEnd;
+                String delimiter= document.getLineDelimiter(lineNumber);
+                if (delimiter !is null)
+                    offset += delimiter.length;
+            }
+
+            int end= offset + length;
+            lineInformation= document.getLineInformationOfOffset(end);
+            lineEnd= lineInformation.getOffset() + lineInformation.getLength();
+            delta= end - lineEnd;
+            if (delta > 0) {
+                // in the middle of a multi-character line delimiter
+                length -= delta;
+            }
+
+        } catch (BadLocationException x) {
+            selectionRange[0]= -1;
+            selectionRange[1]= -1;
+            return;
+        }
+
+        if (selectionRange[1] < 0) {
+            selectionRange[0]= offset + length;
+            selectionRange[1]= -length;
+        } else {
+            selectionRange[0]= offset;
+            selectionRange[1]= length;
+        }
+    }
+
+    /*
+     * @see Viewer#setSelection(ISelection)
+     */
+    public void setSelection(ISelection selection, bool reveal) {
+        if ( cast(ITextSelection)selection ) {
+            ITextSelection s= cast(ITextSelection) selection;
+            setSelectedRange(s.getOffset(), s.getLength());
+            if (reveal)
+                revealRange(s.getOffset(), s.getLength());
+        }
+    }
+
+    /*
+     * @see Viewer#getSelection()
+     */
+    public ISelection getSelection() {
+        Point p= getSelectedRange();
+        if (p.x is -1 || p.y is -1)
+            return TextSelection.emptySelection();
+
+        return new TextSelection(getDocument(), p.x, p.y);
+    }
+
+    /*
+     * @see ITextViewer#getSelectionProvider()
+     */
+    public ISelectionProvider getSelectionProvider() {
+        return this;
+    }
+
+    /*
+     * @see dwtx.jface.text.IPostSelectionProvider#addPostSelectionChangedListener(dwtx.jface.viewers.ISelectionChangedListener)
+     * @since 3.0
+     */
+    public void addPostSelectionChangedListener(ISelectionChangedListener listener)  {
+
+        Assert.isNotNull(cast(Object)listener);
+
+        if (fPostSelectionChangedListeners is null)
+            fPostSelectionChangedListeners= new ArrayList();
+
+        if (!fPostSelectionChangedListeners.contains(cast(Object)listener))
+            fPostSelectionChangedListeners.add(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.IPostSelectionProvider#removePostSelectionChangedListener(dwtx.jface.viewers.ISelectionChangedListener)
+     * @since 3.0
+     */
+    public void removePostSelectionChangedListener(ISelectionChangedListener listener)  {
+
+        Assert.isNotNull(cast(Object)listener);
+
+        if (fPostSelectionChangedListeners !is null)  {
+            fPostSelectionChangedListeners.remove(cast(Object)listener);
+            if (fPostSelectionChangedListeners.size() is 0)
+                fPostSelectionChangedListeners= null;
+        }
+    }
+
+    /**
+     * Get the text widget's display.
+     *
+     * @return the display or <code>null</code> if the display cannot be retrieved or if the display is disposed
+     * @since 3.0
+     */
+    private Display getDisplay() {
+        if (fTextWidget is null || fTextWidget.isDisposed())
+            return null;
+
+        Display display= fTextWidget.getDisplay();
+        if (display !is null && display.isDisposed())
+            return null;
+
+        return display;
+    }
+
+    /**
+     * Starts a timer to send out a post selection changed event.
+     *
+     * @param fireEqualSelection <code>true</code> iff the event must be fired if the selection does not change
+     * @since 3.0
+     */
+    private void queuePostSelectionChanged(bool fireEqualSelection) {
+        Display display= getDisplay();
+        if (display is null)
+            return;
+
+        fNumberOfPostSelectionChangedEvents[0]++;
+        display.timerExec(getEmptySelectionChangedEventDelay(), new class()  Runnable {
+            const int id;
+            this(){
+                id = fNumberOfPostSelectionChangedEvents[0];
+            }
+            public void run() {
+                if (id is fNumberOfPostSelectionChangedEvents[0]) {
+                    // Check again because this is executed after the delay
+                    if (getDisplay() !is null)  {
+                        Point selection= fTextWidget.getSelectionRange();
+                        if (selection !is null) {
+                            IRegion r= widgetRange2ModelRange(new Region(selection.x, selection.y));
+                            if (fireEqualSelection || (r !is null && !(cast(Object)r).opEquals(cast(Object)fLastSentPostSelectionChange)) || r is null)  {
+                                fLastSentPostSelectionChange= r;
+                                firePostSelectionChanged(selection.x, selection.y);
+                            }
+                        }
+                    }
+                }
+            }
+        });
+    }
+
+    /**
+     * Sends out a text selection changed event to all registered post selection changed listeners.
+     *
+     * @param offset the offset of the newly selected range in the visible document
+     * @param length the length of the newly selected range in the visible document
+     * @since 3.0
+     */
+    protected void firePostSelectionChanged(int offset, int length) {
+        if (redraws()) {
+            IRegion r= widgetRange2ModelRange(new Region(offset, length));
+            ISelection selection= r !is null ? new TextSelection(getDocument(), r.getOffset(), r.getLength()) : TextSelection.emptySelection();
+            SelectionChangedEvent event= new SelectionChangedEvent(this, selection);
+            firePostSelectionChanged(event);
+        }
+    }
+
+    /**
+     * Sends out a text selection changed event to all registered listeners and
+     * registers the selection changed event to be sent out to all post selection
+     * listeners.
+     *
+     * @param offset the offset of the newly selected range in the visible document
+     * @param length the length of the newly selected range in the visible document
+     */
+    protected void selectionChanged(int offset, int length) {
+        queuePostSelectionChanged(true);
+        fireSelectionChanged(offset, length);
+    }
+
+    /**
+     * Sends out a text selection changed event to all registered listeners.
+     *
+     * @param offset the offset of the newly selected range in the visible document
+     * @param length the length of the newly selected range in the visible document
+     * @since 3.0
+     */
+    protected void fireSelectionChanged(int offset, int length) {
+        if (redraws()) {
+            IRegion r= widgetRange2ModelRange(new Region(offset, length));
+            if ((r !is null && !(cast(Object)r).opEquals(cast(Object)fLastSentSelectionChange)) || r is null)  {
+                fLastSentSelectionChange= r;
+                ISelection selection= r !is null ? new TextSelection(getDocument(), r.getOffset(), r.getLength()) : TextSelection.emptySelection();
+                SelectionChangedEvent event= new SelectionChangedEvent(this, selection);
+                fireSelectionChanged(event);
+            }
+        }
+    }
+
+    /**
+     * Sends the given event to all registered post selection changed listeners.
+     *
+     * @param event the selection event
+     * @since 3.0
+     */
+    private void firePostSelectionChanged(SelectionChangedEvent event) {
+        List listeners= fPostSelectionChangedListeners;
+        if (listeners !is null) {
+            listeners= new ArrayList(listeners);
+            for (int i= 0; i < listeners.size(); i++) {
+                ISelectionChangedListener l= cast(ISelectionChangedListener) listeners.get(i);
+                l.selectionChanged(event);
+            }
+        }
+    }
+
+    /**
+     * Sends out a mark selection changed event to all registered listeners.
+     *
+     * @param offset the offset of the mark selection in the visible document, the offset is <code>-1</code> if the mark was cleared
+     * @param length the length of the mark selection, may be negative if the caret is before the mark.
+     * @since 2.0
+     */
+    protected void markChanged(int offset, int length) {
+        if (redraws()) {
+
+            if (offset !is -1) {
+                IRegion r= widgetRange2ModelRange(new Region(offset, length));
+                offset= r.getOffset();
+                length= r.getLength();
+            }
+
+            ISelection selection= new MarkSelection(getDocument(), offset, length);
+            SelectionChangedEvent event= new SelectionChangedEvent(this, selection);
+            fireSelectionChanged(event);
+        }
+    }
+
+
+    //---- Text listeners
+
+    /*
+     * @see ITextViewer#addTextListener(ITextListener)
+     */
+    public void addTextListener(ITextListener listener) {
+
+        Assert.isNotNull(cast(Object)listener);
+
+        if (fTextListeners is null)
+            fTextListeners= new ArrayList();
+
+        if (!fTextListeners.contains(cast(Object)listener))
+            fTextListeners.add(cast(Object)listener);
+    }
+
+    /*
+     * @see ITextViewer#removeTextListener(ITextListener)
+     */
+    public void removeTextListener(ITextListener listener) {
+
+        Assert.isNotNull(cast(Object)listener);
+
+        if (fTextListeners !is null) {
+            fTextListeners.remove(cast(Object)listener);
+            if (fTextListeners.size() is 0)
+                fTextListeners= null;
+        }
+    }
+
+    /**
+     * Informs all registered text listeners about the change specified by the
+     * widget command. This method does not use a robust iterator.
+     *
+     * @param cmd the widget command translated into a text event sent to all text listeners
+     */
+    protected void updateTextListeners(WidgetCommand cmd) {
+        List textListeners= fTextListeners;
+        if (textListeners !is null) {
+            textListeners= new ArrayList(textListeners);
+            DocumentEvent event= cmd.event;
+            if ( cast(SlaveDocumentEvent)event )
+                event= (cast(SlaveDocumentEvent) event).getMasterEvent();
+
+            TextEvent e= new TextEvent(cmd.start, cmd.length, cmd.text, cmd.preservedText, event, redraws());
+            for (int i= 0; i < textListeners.size(); i++) {
+                ITextListener l= cast(ITextListener) textListeners.get(i);
+                l.textChanged(e);
+            }
+        }
+    }
+
+    //---- Text input listeners
+
+    /*
+     * @see ITextViewer#addTextInputListener(ITextInputListener)
+     */
+    public void addTextInputListener(ITextInputListener listener) {
+
+        Assert.isNotNull(cast(Object)listener);
+
+        if (fTextInputListeners is null)
+            fTextInputListeners= new ArrayList();
+
+        if (!fTextInputListeners.contains(cast(Object)listener))
+            fTextInputListeners.add(cast(Object)listener);
+    }
+
+    /*
+     * @see ITextViewer#removeTextInputListener(ITextInputListener)
+     */
+    public void removeTextInputListener(ITextInputListener listener) {
+
+        Assert.isNotNull(cast(Object)listener);
+
+        if (fTextInputListeners !is null) {
+            fTextInputListeners.remove(cast(Object)listener);
+            if (fTextInputListeners.size() is 0)
+                fTextInputListeners= null;
+        }
+    }
+
+    /**
+     * Informs all registered text input listeners about the forthcoming input change,
+     * This method does not use a robust iterator.
+     *
+     * @param oldInput the old input document
+     * @param newInput the new input document
+     */
+    protected void fireInputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
+        List listener= fTextInputListeners;
+        if (listener !is null) {
+            for (int i= 0; i < listener.size(); i++) {
+                ITextInputListener l= cast(ITextInputListener) listener.get(i);
+                l.inputDocumentAboutToBeChanged(oldInput, newInput);
+            }
+        }
+    }
+
+    /**
+     * Informs all registered text input listeners about the successful input change,
+     * This method does not use a robust iterator.
+     *
+     * @param oldInput the old input document
+     * @param newInput the new input document
+     */
+    protected void fireInputDocumentChanged(IDocument oldInput, IDocument newInput) {
+        List listener= fTextInputListeners;
+        if (listener !is null) {
+            for (int i= 0; i < listener.size(); i++) {
+                ITextInputListener l= cast(ITextInputListener) listener.get(i);
+                l.inputDocumentChanged(oldInput, newInput);
+            }
+        }
+    }
+
+    //---- Document
+
+    /*
+     * @see Viewer#getInput()
+     */
+    public Object getInput() {
+        return cast(Object)getDocument();
+    }
+
+    /*
+     * @see ITextViewer#getDocument()
+     */
+    public IDocument getDocument() {
+        return fDocument;
+    }
+
+    /*
+     * @see Viewer#setInput(Object)
+     */
+    public void setInput(Object input) {
+
+        IDocument document= null;
+        if ( cast(IDocument)input )
+            document= cast(IDocument) input;
+
+        setDocument(document);
+    }
+
+    /*
+     * @see ITextViewer#setDocument(IDocument)
+     */
+    public void setDocument(IDocument document) {
+
+        fReplaceTextPresentation= true;
+        fireInputDocumentAboutToBeChanged(fDocument, document);
+
+        IDocument oldDocument= fDocument;
+        fDocument= document;
+
+        setVisibleDocument(fDocument);
+
+        resetPlugins();
+        inputChanged(cast(Object)fDocument, cast(Object)oldDocument);
+
+        fireInputDocumentChanged(oldDocument, fDocument);
+        fLastSentSelectionChange= null;
+        fReplaceTextPresentation= false;
+    }
+
+    /*
+     * @see ITextViewer#setDocument(IDocument, int, int)
+     */
+    public void setDocument(IDocument document, int modelRangeOffset, int modelRangeLength) {
+
+        fReplaceTextPresentation= true;
+        fireInputDocumentAboutToBeChanged(fDocument, document);
+
+        IDocument oldDocument= fDocument;
+        fDocument= document;
+
+        try {
+
+            IDocument slaveDocument= createSlaveDocument(document);
+            updateSlaveDocument(slaveDocument, modelRangeOffset, modelRangeLength);
+            setVisibleDocument(slaveDocument);
+
+        } catch (BadLocationException x) {
+            throw new IllegalArgumentException(JFaceTextMessages.getString("TextViewer.error.invalid_visible_region_1")); //$NON-NLS-1$
+        }
+
+        resetPlugins();
+        inputChanged(cast(Object)fDocument, cast(Object)oldDocument);
+
+        fireInputDocumentChanged(oldDocument, fDocument);
+        fLastSentSelectionChange= null;
+        fReplaceTextPresentation= false;
+    }
+
+    /**
+     * Creates a slave document for the given document if there is a slave document manager
+     * associated with this viewer.
+     *
+     * @param document the master document
+     * @return the newly created slave document
+     * @since 2.1
+     */
+    protected IDocument createSlaveDocument(IDocument document) {
+        ISlaveDocumentManager manager= getSlaveDocumentManager();
+        if (manager !is null) {
+            if (manager.isSlaveDocument(document))
+                return document;
+            return manager.createSlaveDocument(document);
+        }
+        return document;
+    }
+
+    /**
+     * Sets the given slave document to the specified range of its master document.
+     *
+     * @param visibleDocument the slave document
+     * @param visibleRegionOffset the offset of the master document range
+     * @param visibleRegionLength the length of the master document range
+     * @return <code>true</code> if the slave has been adapted successfully
+     * @throws BadLocationException in case the specified range is not valid in the master document
+     * @since 2.1
+     * @deprecated use <code>updateSlaveDocument</code> instead
+     */
+    protected bool updateVisibleDocument(IDocument visibleDocument, int visibleRegionOffset, int visibleRegionLength)  {
+        if ( cast(ChildDocument)visibleDocument ) {
+            ChildDocument childDocument= cast(ChildDocument) visibleDocument;
+
+            IDocument document= childDocument.getParentDocument();
+            int line= document.getLineOfOffset(visibleRegionOffset);
+            int offset= document.getLineOffset(line);
+            int length= (visibleRegionOffset - offset) + visibleRegionLength;
+
+            Position parentRange= childDocument.getParentDocumentRange();
+            if (offset !is parentRange.getOffset() || length !is parentRange.getLength()) {
+                childDocument.setParentDocumentRange(offset, length);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Updates the given slave document to show the specified range of its master document.
+     *
+     * @param slaveDocument the slave document
+     * @param modelRangeOffset the offset of the master document range
+     * @param modelRangeLength the length of the master document range
+     * @return <code>true</code> if the slave has been adapted successfully
+     * @throws BadLocationException in case the specified range is not valid in the master document
+     * @since 3.0
+     */
+    protected bool updateSlaveDocument(IDocument slaveDocument, int modelRangeOffset, int modelRangeLength)  {
+        return updateVisibleDocument(slaveDocument, modelRangeOffset, modelRangeLength);
+    }
+
+
+
+    //---- View ports
+
+    /**
+     * Initializes all listeners and structures required to set up view port listeners.
+     */
+    private void initializeViewportUpdate() {
+
+        if (fViewportGuard !is null)
+            return;
+
+        if (fTextWidget !is null) {
+
+            fViewportGuard= new ViewportGuard();
+            fLastTopPixel= -1;
+
+            fTextWidget.addKeyListener(fViewportGuard);
+            fTextWidget.addMouseListener(fViewportGuard);
+
+            fScroller= fTextWidget.getVerticalBar();
+            if (fScroller !is null)
+                fScroller.addSelectionListener(fViewportGuard);
+        }
+    }
+
+    /**
+     * Removes all listeners and structures required to set up view port listeners.
+     */
+    private void removeViewPortUpdate() {
+
+        if (fTextWidget !is null) {
+
+            fTextWidget.removeKeyListener(fViewportGuard);
+            fTextWidget.removeMouseListener(fViewportGuard);
+
+            if (fScroller !is null && !fScroller.isDisposed()) {
+                fScroller.removeSelectionListener(fViewportGuard);
+                fScroller= null;
+            }
+
+            fViewportGuard= null;
+        }
+    }
+
+    /*
+     * @see ITextViewer#addViewportListener(IViewportListener)
+     */
+    public void addViewportListener(IViewportListener listener) {
+
+        if (fViewportListeners is null) {
+            fViewportListeners= new ArrayList();
+            initializeViewportUpdate();
+        }
+
+        if (!fViewportListeners.contains(cast(Object)listener))
+            fViewportListeners.add(cast(Object)listener);
+    }
+
+    /*
+     * @see ITextViewer#removeViewportListener(IVewportListener)
+     */
+    public void removeViewportListener(IViewportListener listener) {
+        if (fViewportListeners !is null)
+            fViewportListeners.remove(cast(Object)listener);
+    }
+
+    /**
+     * Checks whether the view port changed and if so informs all registered
+     * listeners about the change.
+     *
+     * @param origin describes under which circumstances this method has been called.
+     *
+     * @see IViewportListener
+     */
+    protected void updateViewportListeners(int origin) {
+
+        if (redraws()) {
+            int topPixel= fTextWidget.getTopPixel();
+            if (topPixel >= 0 && topPixel !is fLastTopPixel) {
+                if (fViewportListeners !is null) {
+                    for (int i= 0; i < fViewportListeners.size(); i++) {
+                        IViewportListener l= cast(IViewportListener) fViewportListeners.get(i);
+                        l.viewportChanged(topPixel);
+                    }
+                }
+                fLastTopPixel= topPixel;
+            }
+        }
+    }
+
+    //---- scrolling and revealing
+
+    /*
+     * @see ITextViewer#getTopIndex()
+     */
+    public int getTopIndex() {
+
+        if (fTextWidget !is null) {
+            int top= fTextWidget.getTopIndex();
+            return widgetLine2ModelLine(top);
+        }
+
+        return -1;
+    }
+
+    /*
+     * @see ITextViewer#setTopIndex(int)
+     */
+    public void setTopIndex(int index) {
+
+        if (fTextWidget !is null) {
+
+            int widgetLine= modelLine2WidgetLine(index);
+            if (widgetLine is -1)
+                widgetLine= getClosestWidgetLineForModelLine(index);
+
+            if (widgetLine > -1) {
+                fTextWidget.setTopIndex(widgetLine);
+                    updateViewportListeners(INTERNAL);
+            }
+        }
+    }
+
+    /**
+     * Returns the number of lines that can fully fit into the viewport. This is computed by
+     * dividing the widget's client area height by the widget's line height. The result is only
+     * accurate if the widget does not use variable line heights - for that reason, clients should
+     * not use this method any longer and use the client area height of the text widget to find out
+     * how much content fits into it.
+     *
+     * @return the view port height in lines
+     * @deprecated as of 3.2
+     */
+    protected int getVisibleLinesInViewport() {
+        if (fTextWidget !is null) {
+            Rectangle clArea= fTextWidget.getClientArea();
+            if (!clArea.isEmpty())
+                return clArea.height / fTextWidget.getLineHeight();
+        }
+        return -1;
+    }
+
+    /*
+     * @see ITextViewer#getBottomIndex()
+     */
+    public int getBottomIndex() {
+
+        if (fTextWidget is null)
+            return -1;
+
+        int widgetBottom= JFaceTextUtil.getBottomIndex(fTextWidget);
+        return widgetLine2ModelLine(widgetBottom);
+    }
+
+    /*
+     * @see ITextViewer#getTopIndexStartOffset()
+     */
+    public int getTopIndexStartOffset() {
+
+        if (fTextWidget !is null) {
+            int top= fTextWidget.getTopIndex();
+            try {
+                top= getVisibleDocument().getLineOffset(top);
+                return widgetOffset2ModelOffset(top);
+            } catch (BadLocationException ex) {
+                if (TRACE_ERRORS)
+                    System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.getTopIndexStartOffset")); //$NON-NLS-1$
+            }
+        }
+
+        return -1;
+    }
+
+    /*
+     * @see ITextViewer#getBottomIndexEndOffset()
+     */
+    public int getBottomIndexEndOffset() {
+        try {
+
+            IRegion line= getDocument().getLineInformation(getBottomIndex());
+            int bottomEndOffset= line.getOffset() + line.getLength() - 1;
+
+            IRegion coverage= getModelCoverage();
+            if (coverage is null)
+                return -1;
+
+            int coverageEndOffset=  coverage.getOffset() + coverage.getLength() - 1;
+            return Math.min(coverageEndOffset, bottomEndOffset);
+
+        } catch (BadLocationException ex) {
+            if (TRACE_ERRORS)
+                System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.getBottomIndexEndOffset")); //$NON-NLS-1$
+            return getDocument().getLength() - 1;
+        }
+    }
+
+    /*
+     * @see ITextViewer#revealRange(int, int)
+     */
+    public void revealRange(int start, int length) {
+
+        if (fTextWidget is null || !redraws())
+            return;
+
+        IRegion modelRange= new Region(start, length);
+        IRegion widgetRange= modelRange2ClosestWidgetRange(modelRange);
+        if (widgetRange !is null) {
+
+            int[] range= [ widgetRange.getOffset(), widgetRange.getLength() ];
+            validateSelectionRange(range);
+            if (range[0] >= 0)
+                internalRevealRange(range[0], range[0] + range[1]);
+
+        } else {
+
+            IRegion coverage= getModelCoverage();
+            int cursor= (coverage is null || start < coverage.getOffset()) ? 0 : getVisibleDocument().getLength();
+            internalRevealRange(cursor, cursor);
+        }
+    }
+
+    /**
+     * Reveals the given range of the visible document.
+     *
+     * @param start the start offset of the range
+     * @param end the end offset of the range
+     */
+    protected void internalRevealRange(int start, int end) {
+
+        try {
+
+            IDocument doc= getVisibleDocument();
+
+            int startLine= doc.getLineOfOffset(start);
+            int endLine= doc.getLineOfOffset(end);
+
+            int top= fTextWidget.getTopIndex();
+            if (top > -1) {
+
+                // scroll vertically
+                int bottom= JFaceTextUtil.getBottomIndex(fTextWidget);
+                int lines= bottom - top;
+
+                // if the widget is not scrollable as it is displaying the entire content
+                // setTopIndex won't have any effect.
+
+                if (startLine >= top && startLine <= bottom && endLine >= top && endLine <= bottom ) {
+
+                    // do not scroll at all as it is already visible
+
+                } else {
+
+                    int delta= Math.max(0, lines - (endLine - startLine));
+                    fTextWidget.setTopIndex(startLine - delta/3);
+                    updateViewportListeners(INTERNAL);
+                }
+
+                // scroll horizontally
+
+                if (endLine < startLine) {
+                    endLine += startLine;
+                    startLine= endLine - startLine;
+                    endLine -= startLine;
+                }
+
+                int startPixel= -1;
+                int endPixel= -1;
+
+                if (endLine > startLine) {
+                    // reveal the beginning of the range in the start line
+                    IRegion extent= getExtent(start, start);
+                    startPixel= extent.getOffset() + fTextWidget.getHorizontalPixel();
+                    endPixel= startPixel;
+
+                } else {
+                    IRegion extent= getExtent(start, end);
+                    startPixel= extent.getOffset() + fTextWidget.getHorizontalPixel();
+                    endPixel= startPixel + extent.getLength();
+                }
+
+                int visibleStart= fTextWidget.getHorizontalPixel();
+                int visibleEnd= visibleStart + fTextWidget.getClientArea().width;
+
+                // scroll only if not yet visible
+                if (startPixel < visibleStart || visibleEnd < endPixel) {
+
+                    // set buffer zone to 10 pixels
+                    int bufferZone= 10;
+
+                    int newOffset= visibleStart;
+
+                    int visibleWidth= visibleEnd - visibleStart;
+                    int selectionPixelWidth= endPixel - startPixel;
+
+                    if (startPixel < visibleStart)
+                        newOffset= startPixel;
+                    else if (selectionPixelWidth  + bufferZone < visibleWidth)
+                        newOffset= endPixel + bufferZone - visibleWidth;
+                    else
+                        newOffset= startPixel;
+
+                    float index= (cast(float)newOffset) / (cast(float)getAverageCharWidth());
+
+                    fTextWidget.setHorizontalIndex(cast(int)Math.round(index));
+                }
+
+            }
+        } catch (BadLocationException e) {
+            throw new IllegalArgumentException(JFaceTextMessages.getString("TextViewer.error.invalid_range")); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Returns the width of the text when being drawn into this viewer's widget.
+     *
+     * @param text the string to measure
+     * @return the width of the presentation of the given string
+     * @deprecated use <code>getWidthInPixels(int, int)</code> instead
+     */
+    final protected int getWidthInPixels(String text) {
+        GC gc= new GC(fTextWidget);
+        gc.setFont(fTextWidget.getFont());
+        Point extent= gc.textExtent(text);
+        gc.dispose();
+        return extent.x;
+    }
+
+    /**
+     * Returns the region covered by the given start and end offset.
+     * The result is relative to the upper left corner of the widget
+     * client area.
+     *
+     * @param start offset relative to the start of this viewer's view port
+     *  0 <= offset <= getCharCount()
+     * @param end offset relative to the start of this viewer's view port
+     *  0 <= offset <= getCharCount()
+     * @return the region covered by start and end offset
+     */
+    final protected IRegion getExtent(int start, int end) {
+        if (end > 0 && start < end) {
+            Rectangle bounds= fTextWidget.getTextBounds(start, end - 1);
+            return new Region(bounds.x, bounds.width);
+        }
+
+        return new Region(fTextWidget.getLocationAtOffset(start).x, 0);
+    }
+
+    /**
+     * Returns the width of the representation of a text range in the
+     * visible region of the viewer's document as drawn in this viewer's
+     * widget.
+     *
+     * @param offset the offset of the text range in the visible region
+     * @param length the length of the text range in the visible region
+     * @return the width of the presentation of the specified text range
+     * @since 2.0
+     */
+    final protected int getWidthInPixels(int offset, int length) {
+        return getExtent(offset, offset + length).getLength();
+    }
+
+    /**
+     * Returns the average character width of this viewer's widget.
+     *
+     * @return the average character width of this viewer's widget
+     */
+    final protected int getAverageCharWidth() {
+        return JFaceTextUtil.getAverageCharWidth(getTextWidget());
+    }
+
+    /*
+     * @see Viewer#refresh()
+     */
+    public void refresh() {
+        setDocument(getDocument());
+    }
+
+    //---- visible range support
+
+    /**
+     * Returns the slave document manager
+     *
+     * @return the slave document manager
+     * @since 2.1
+     */
+    protected ISlaveDocumentManager getSlaveDocumentManager() {
+        if (fSlaveDocumentManager is null)
+            fSlaveDocumentManager= createSlaveDocumentManager();
+        return fSlaveDocumentManager;
+    }
+
+    /**
+     * Creates a new slave document manager. This implementation always
+     * returns a <code>ChildDocumentManager</code>.
+     *
+     * @return ISlaveDocumentManager
+     * @since 2.1
+     */
+    protected ISlaveDocumentManager createSlaveDocumentManager() {
+        return new ChildDocumentManager();
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextViewer#invalidateTextPresentation()
+     */
+    public final void invalidateTextPresentation() {
+        if (fVisibleDocument !is null) {
+            fWidgetCommand.event= null;
+            fWidgetCommand.start= 0;
+            fWidgetCommand.length= fVisibleDocument.getLength();
+            fWidgetCommand.text= fVisibleDocument.get();
+            updateTextListeners(fWidgetCommand);
+        }
+    }
+
+    /**
+     * Invalidates the given range of the text presentation.
+     *
+     * @param offset the offset of the range to be invalidated
+     * @param length the length of the range to be invalidated
+     * @since 2.1
+     */
+    public final void invalidateTextPresentation(int offset, int length) {
+        if (fVisibleDocument !is null) {
+
+            IRegion widgetRange= modelRange2WidgetRange(new Region(offset, length));
+            if (widgetRange !is null) {
+
+                fWidgetCommand.event= null;
+                fWidgetCommand.start= widgetRange.getOffset();
+                fWidgetCommand.length= widgetRange.getLength();
+
+                try {
+                    fWidgetCommand.text= fVisibleDocument.get(widgetRange.getOffset(), widgetRange.getLength());
+                    updateTextListeners(fWidgetCommand);
+                } catch (BadLocationException x) {
+                    // can not happen because of previous checking
+                }
+            }
+        }
+    }
+
+    /**
+     * Initializes the text widget with the visual document and
+     * invalidates the overall presentation.
+     */
+    private void initializeWidgetContents() {
+
+        if (fTextWidget !is null && fVisibleDocument !is null) {
+
+            // set widget content
+            if (fDocumentAdapter is null)
+                fDocumentAdapter= createDocumentAdapter();
+
+            fDocumentAdapter.setDocument(fVisibleDocument);
+            fTextWidget.setContent(fDocumentAdapter);
+
+            // invalidate presentation
+            invalidateTextPresentation();
+        }
+    }
+
+    /**
+     * Frees the given document if it is a slave document.
+     *
+     * @param slave the potential slave document
+     * @since 3.0
+     */
+    protected void freeSlaveDocument(IDocument slave) {
+        ISlaveDocumentManager manager= getSlaveDocumentManager();
+        if (manager !is null && manager.isSlaveDocument(slave))
+            manager.freeSlaveDocument(slave);
+    }
+
+    /**
+     * Sets this viewer's visible document. The visible document represents the
+     * visible region of the viewer's input document.
+     *
+     * @param document the visible document
+     */
+    protected void setVisibleDocument(IDocument document) {
+
+        if (fVisibleDocument is document && cast(ChildDocument)fVisibleDocument ) {
+            // optimization for new child documents
+            return;
+        }
+
+        if (fVisibleDocument !is null) {
+            if (fVisibleDocumentListener !is null)
+                fVisibleDocument.removeDocumentListener(fVisibleDocumentListener);
+            if (fVisibleDocument !is document)
+                freeSlaveDocument(fVisibleDocument);
+        }
+
+        fVisibleDocument= document;
+        initializeDocumentInformationMapping(fVisibleDocument);
+
+        initializeWidgetContents();
+
+        fFindReplaceDocumentAdapter= null;
+        if (fVisibleDocument !is null && fVisibleDocumentListener !is null)
+            fVisibleDocument.addDocumentListener(fVisibleDocumentListener);
+    }
+
+    /**
+     * Hook method called when the visible document is about to be changed.
+     * <p>
+     * Subclasses may override.
+     *
+     * @param event the document event
+     * @since 3.0
+     */
+    protected void handleVisibleDocumentAboutToBeChanged(DocumentEvent event) {
+    }
+
+    /**
+     * Hook method called when the visible document has been changed.
+     * <p>
+     * Subclasses may override.
+     *
+     * @param event the document event
+     * @since 3.0
+     */
+    protected void handleVisibleDocumentChanged(DocumentEvent event) {
+    }
+
+    /**
+     * Initializes the document information mapping between the given slave document and
+     * its master document.
+     *
+     * @param visibleDocument the slave document
+     * @since 2.1
+     */
+    protected void initializeDocumentInformationMapping(IDocument visibleDocument) {
+        ISlaveDocumentManager manager= getSlaveDocumentManager();
+        fInformationMapping= manager is null ? null : manager.createMasterSlaveMapping(visibleDocument);
+    }
+
+    /**
+     * Returns the viewer's visible document.
+     *
+     * @return the viewer's visible document
+     */
+    protected IDocument getVisibleDocument() {
+        return fVisibleDocument;
+    }
+
+    /**
+     * Returns the offset of the visible region.
+     *
+     * @return the offset of the visible region
+     */
+    protected int _getVisibleRegionOffset() {
+
+        IDocument document= getVisibleDocument();
+        if ( cast(ChildDocument)document ) {
+            ChildDocument cdoc= cast(ChildDocument) document;
+            return cdoc.getParentDocumentRange().getOffset();
+        }
+
+        return 0;
+    }
+    package int _getVisibleRegionOffset_package() {
+        return _getVisibleRegionOffset();
+    }
+
+    /*
+     * @see ITextViewer#getVisibleRegion()
+     */
+    public IRegion getVisibleRegion() {
+
+        IDocument document= getVisibleDocument();
+        if ( cast(ChildDocument)document ) {
+            Position p= (cast(ChildDocument) document).getParentDocumentRange();
+            return new Region(p.getOffset(), p.getLength());
+        }
+
+        return new Region(0, document is null ? 0 : document.getLength());
+    }
+
+    /*
+     * @see ITextViewer#overlapsWithVisibleRegion(int, int)
+     */
+    public bool overlapsWithVisibleRegion(int start, int length) {
+        IDocument document= getVisibleDocument();
+        if ( cast(ChildDocument)document ) {
+            ChildDocument cdoc= cast(ChildDocument) document;
+            return cdoc.getParentDocumentRange().overlapsWith(start, length);
+        } else if (document !is null) {
+            int size= document.getLength();
+            return (start >= 0 && length >= 0 && start + length <= size);
+        }
+        return false;
+    }
+
+    /*
+     * @see ITextViewer#setVisibleRegion(int, int)
+     */
+    public void setVisibleRegion(int start, int length) {
+
+        IRegion region= getVisibleRegion();
+        if (start is region.getOffset() && length is region.getLength()) {
+            // nothing to change
+            return;
+        }
+
+        setRedraw(false);
+        try {
+
+            IDocument slaveDocument= createSlaveDocument(getVisibleDocument());
+            if (updateSlaveDocument(slaveDocument, start, length))
+                setVisibleDocument(slaveDocument);
+
+        } catch (BadLocationException x) {
+            throw new IllegalArgumentException(JFaceTextMessages.getString("TextViewer.error.invalid_visible_region_2")); //$NON-NLS-1$
+        } finally {
+            setRedraw(true);
+        }
+    }
+
+    /*
+     * @see ITextViewer#resetVisibleRegion()
+     */
+    public void resetVisibleRegion() {
+        ISlaveDocumentManager manager= getSlaveDocumentManager();
+        if (manager !is null) {
+            IDocument slave= getVisibleDocument();
+            IDocument master= manager.getMasterDocument(slave);
+            if (master !is null) {
+                setVisibleDocument(master);
+                manager.freeSlaveDocument(slave);
+            }
+        }
+    }
+
+
+    //--------------------------------------
+
+    /*
+     * @see ITextViewer#setTextDoubleClickStrategy(ITextDoubleClickStrategy, String)
+     */
+    public void setTextDoubleClickStrategy(ITextDoubleClickStrategy strategy, String contentType) {
+
+        if (strategy !is null) {
+            if (fDoubleClickStrategies is null)
+                fDoubleClickStrategies= new HashMap();
+            fDoubleClickStrategies.put(stringcast(contentType), cast(Object)strategy);
+        } else if (fDoubleClickStrategies !is null)
+            fDoubleClickStrategies.remove(contentType);
+    }
+
+    /**
+     * Selects from the given map the one which is registered under
+     * the content type of the partition in which the given offset is located.
+     *
+     * @param plugins the map from which to choose
+     * @param offset the offset for which to find the plug-in
+     * @return the plug-in registered under the offset's content type
+     */
+    protected Object selectContentTypePlugin(int offset, Map plugins) {
+        try {
+            return selectContentTypePlugin(TextUtilities.getContentType(getDocument(), getDocumentPartitioning(), offset, true), plugins);
+        } catch (BadLocationException x) {
+            if (TRACE_ERRORS)
+                System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.selectContentTypePlugin")); //$NON-NLS-1$
+        }
+        return null;
+    }
+
+    /**
+     * Selects from the given <code>plug-ins</code> this one which is
+     * registered for the given content <code>type</code>.
+     *
+     * @param type the type to be used as lookup key
+     * @param plugins the table to be searched
+     * @return the plug-in in the map for the given content type
+     */
+    private Object selectContentTypePlugin(String type, Map plugins) {
+
+        if (plugins is null)
+            return null;
+
+        return plugins.get(type);
+    }
+
+    /**
+     * Hook called on receipt of a <code>VerifyEvent</code>. The event has
+     * been translated into a <code>DocumentCommand</code> which can now be
+     * manipulated by interested parties. By default, the hook forwards the command
+     * to the installed instances of <code>IAutoEditStrategy</code>.
+     *
+     * @param command the document command representing the verify event
+     */
+    protected void customizeDocumentCommand(DocumentCommand command) {
+        if (isIgnoringAutoEditStrategies())
+            return;
+
+        IDocument document= getDocument();
+
+        if (fTabsToSpacesConverter !is null)
+            fTabsToSpacesConverter.customizeDocumentCommand(document, command);
+
+        List strategies= cast(List) selectContentTypePlugin(command.offset, fAutoIndentStrategies);
+        if (strategies is null)
+            return;
+
+        switch (strategies.size()) {
+        // optimization
+        case 0:
+            break;
+
+        case 1:
+            (cast(IAutoEditStrategy) strategies.iterator().next()).customizeDocumentCommand(document, command);
+            break;
+
+        // make iterator robust against adding/removing strategies from within strategies
+        default:
+            strategies= new ArrayList(strategies);
+            for (final Iterator iterator= strategies.iterator(); iterator.hasNext(); )
+                (cast(IAutoEditStrategy) iterator.next()).customizeDocumentCommand(document, command);
+
+            break;
+        }
+    }
+
+    /**
+     * Handles the verify event issued by the viewer's text widget.
+     *
+     * @see VerifyListener#verifyText(VerifyEvent)
+     * @param e the verify event
+     */
+    protected void handleVerifyEvent(VerifyEvent e) {
+
+        if (fEventConsumer !is null) {
+            fEventConsumer.processEvent(e);
+            if (!e.doit)
+                return;
+        }
+
+        IRegion modelRange= event2ModelRange(e);
+        fDocumentCommand.setEvent(e, modelRange);
+        customizeDocumentCommand(fDocumentCommand);
+        if (!fDocumentCommand.fillEvent(e, modelRange)) {
+
+            bool compoundChange= fDocumentCommand.getCommandCount() > 1;
+            try {
+
+                fVerifyListener.forward(false);
+
+                if (compoundChange && fUndoManager !is null)
+                    fUndoManager.beginCompoundChange();
+
+                fDocumentCommand.execute(getDocument());
+
+                if (fTextWidget !is null) {
+                    int documentCaret= fDocumentCommand.caretOffset;
+                    if (documentCaret is -1) {
+                        // old behavior of document command
+                        documentCaret= fDocumentCommand.offset + (fDocumentCommand.text is null ? 0 : fDocumentCommand.text.length());
+                    }
+
+                    int widgetCaret= modelOffset2WidgetOffset(documentCaret);
+                    if (widgetCaret is -1) {
+                        // try to move it to the closest spot
+                        IRegion region= getModelCoverage();
+                        if (region !is null) {
+                            if (documentCaret <= region.getOffset())
+                                widgetCaret= 0;
+                            else if (documentCaret >= region.getOffset() + region.getLength())
+                                widgetCaret= getVisibleRegion().getLength();
+                        }
+                    }
+
+                    if (widgetCaret !is -1) {
+                        // there is a valid widget caret
+                        fTextWidget.setCaretOffset(widgetCaret);
+                    }
+
+                    fTextWidget.showSelection();
+                }
+            } catch (BadLocationException x) {
+
+                if (TRACE_ERRORS)
+                    System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.verifyText")); //$NON-NLS-1$
+
+            } finally {
+
+                if (compoundChange && fUndoManager !is null)
+                    fUndoManager.endCompoundChange();
+
+                fVerifyListener.forward(true);
+
+            }
+        }
+    }
+
+    //---- text manipulation
+
+    /**
+     * Returns whether the marked region of this viewer is empty.
+     *
+     * @return <code>true</code> if the marked region of this viewer is empty, otherwise <code>false</code>
+     * @since 2.0
+     */
+    private bool isMarkedRegionEmpty() {
+        return
+            fTextWidget is null ||
+            fMarkPosition is null ||
+            fMarkPosition.isDeleted() ||
+            modelRange2WidgetRange(fMarkPosition) is null;
+    }
+
+    /*
+     * @see ITextViewer#canDoOperation(int)
+     */
+    public bool canDoOperation(int operation) {
+
+        if (fTextWidget is null || !redraws())
+            return false;
+
+        switch (operation) {
+            case CUT:
+                return isEditable() &&(fTextWidget.getSelectionCount() > 0 || !isMarkedRegionEmpty());
+            case COPY:
+                return fTextWidget.getSelectionCount() > 0 || !isMarkedRegionEmpty();
+            case DELETE:
+            case PASTE:
+                return isEditable();
+            case SELECT_ALL:
+                return true;
+            case SHIFT_LEFT:
+            case SHIFT_RIGHT:
+                return isEditable() && fIndentChars !is null && areMultipleLinesSelected();
+            case PREFIX:
+            case STRIP_PREFIX:
+                return isEditable() && fDefaultPrefixChars !is null;
+            case UNDO:
+                return fUndoManager !is null && fUndoManager.undoable();
+            case REDO:
+                return fUndoManager !is null && fUndoManager.redoable();
+            case PRINT:
+                return isPrintable();
+        }
+
+        return false;
+    }
+
+    /*
+     * @see ITextViewer#doOperation(int)
+     */
+    public void doOperation(int operation) {
+
+        if (fTextWidget is null || !redraws())
+            return;
+
+        Point selection= null;
+
+        switch (operation) {
+
+            case UNDO:
+                if (fUndoManager !is null) {
+                    ignoreAutoEditStrategies(true);
+                    fUndoManager.undo();
+                    ignoreAutoEditStrategies(false);
+                }
+                break;
+            case REDO:
+                if (fUndoManager !is null) {
+                    ignoreAutoEditStrategies(true);
+                    fUndoManager.redo();
+                    ignoreAutoEditStrategies(false);
+                }
+                break;
+            case CUT:
+                if (fTextWidget.getSelectionCount() is 0)
+                    copyMarkedRegion(true);
+                else
+                    fTextWidget.cut();
+
+                selection= fTextWidget.getSelectionRange();
+                fireSelectionChanged(selection.x, selection.y);
+
+                break;
+            case COPY:
+                if (fTextWidget.getSelectionCount() is 0)
+                    copyMarkedRegion(false);
+                else
+                    fTextWidget.copy();
+                break;
+            case PASTE:
+//              ignoreAutoEditStrategies(true);
+                fTextWidget.paste();
+                selection= fTextWidget.getSelectionRange();
+                fireSelectionChanged(selection.x, selection.y);
+//              ignoreAutoEditStrategies(false);
+                break;
+            case DELETE:
+                fTextWidget.invokeAction(ST.DELETE_NEXT);
+                selection= fTextWidget.getSelectionRange();
+                fireSelectionChanged(selection.x, selection.y);
+                break;
+            case SELECT_ALL: {
+                if (getDocument() !is null)
+                    setSelectedRange(0, getDocument().getLength());
+                break;
+            }
+            case SHIFT_RIGHT:
+                shift(false, true, false);
+                break;
+            case SHIFT_LEFT:
+                shift(false, false, false);
+                break;
+            case PREFIX:
+                shift(true, true, true);
+                break;
+            case STRIP_PREFIX:
+                shift(true, false, true);
+                break;
+            case PRINT:
+                print();
+                break;
+        }
+    }
+
+    /**
+     * Tells this viewer whether the registered auto edit strategies should be ignored.
+     *
+     * @param ignore <code>true</code> if the strategies should be ignored.
+     * @since 2.1
+     */
+    protected void ignoreAutoEditStrategies(bool ignore) {
+        if (fIgnoreAutoIndent is ignore)
+            return;
+
+        fIgnoreAutoIndent= ignore;
+
+        IDocument document= getDocument();
+        if ( cast(IDocumentExtension2)document ) {
+            IDocumentExtension2 extension= cast(IDocumentExtension2) document;
+            if (ignore)
+                extension.ignorePostNotificationReplaces();
+            else
+                extension.acceptPostNotificationReplaces();
+        }
+    }
+    package void ignoreAutoEditStrategies_package(bool ignore) {
+        return ignoreAutoEditStrategies(ignore);
+    }
+
+    /**
+     * Returns whether this viewer ignores the registered auto edit strategies.
+     *
+     * @return <code>true</code> if the strategies are ignored
+     * @since 2.1
+     */
+    protected bool isIgnoringAutoEditStrategies() {
+        return fIgnoreAutoIndent;
+    }
+
+    /*
+     * @see ITextOperationTargetExtension#enableOperation(int, bool)
+     * @since 2.0
+     */
+    public void enableOperation(int operation, bool enable) {
+        /*
+         * NO-OP by default.
+         * Will be changed to regularly disable the known operations.
+         */
+    }
+
+    /**
+     * Copies/cuts the marked region.
+     *
+     * @param delete <code>true</code> if the region should be deleted rather than copied.
+     * @since 2.0
+     */
+    protected void copyMarkedRegion(bool delete_) {
+
+        if (fTextWidget is null)
+            return;
+
+        if (fMarkPosition is null || fMarkPosition.isDeleted() || modelRange2WidgetRange(fMarkPosition) is null)
+            return;
+
+        int widgetMarkOffset= modelOffset2WidgetOffset(fMarkPosition.offset);
+        Point selection= fTextWidget.getSelection();
+        if (selection.x <= widgetMarkOffset)
+            fTextWidget.setSelection(selection.x, widgetMarkOffset);
+        else
+            fTextWidget.setSelection(widgetMarkOffset, selection.x);
+
+        if (delete_) {
+            fTextWidget.cut();
+        } else {
+            fTextWidget.copy();
+            fTextWidget.setSelection(selection.x); // restore old cursor position
+        }
+    }
+
+    /**
+     * Deletes the current selection. If the selection has the length 0
+     * the selection is automatically extended to the right - either by 1
+     * or by the length of line delimiter if at the end of a line.
+     *
+     * @deprecated use <code>StyledText.invokeAction</code> instead
+     */
+    protected void deleteText() {
+        fTextWidget.invokeAction(ST.DELETE_NEXT);
+    }
+
+    /**
+     * A block is selected if the character preceding the start of the
+     * selection is a new line character.
+     *
+     * @return <code>true</code> if a block is selected
+     */
+    protected bool isBlockSelected() {
+
+        Point s= getSelectedRange();
+        if (s.y is 0)
+            return false;
+
+        try {
+
+            IDocument document= getDocument();
+            int line= document.getLineOfOffset(s.x);
+            int start= document.getLineOffset(line);
+            return (s.x is start);
+
+        } catch (BadLocationException x) {
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns <code>true</code> if one line is completely selected or if multiple lines are selected.
+     * Being completely selected means that all characters except the new line characters are
+     * selected.
+     *
+     * @return <code>true</code> if one or multiple lines are selected
+     * @since 2.0
+     */
+    protected bool areMultipleLinesSelected() {
+        Point s= getSelectedRange();
+        if (s.y is 0)
+            return false;
+
+        try {
+
+            IDocument document= getDocument();
+            int startLine= document.getLineOfOffset(s.x);
+            int endLine= document.getLineOfOffset(s.x + s.y);
+            IRegion line= document.getLineInformation(startLine);
+            return startLine !is endLine || (s.x is line.getOffset() && s.y is line.getLength());
+
+        } catch (BadLocationException x) {
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the index of the first line whose start offset is in the given text range.
+     *
+     * @param region the text range in characters where to find the line
+     * @return the first line whose start index is in the given range, -1 if there is no such line
+     */
+    private int getFirstCompleteLineOfRegion(IRegion region) {
+
+        try {
+
+            IDocument d= getDocument();
+
+            int startLine= d.getLineOfOffset(region.getOffset());
+
+            int offset= d.getLineOffset(startLine);
+            if (offset >= region.getOffset())
+                return startLine;
+
+            offset= d.getLineOffset(startLine + 1);
+            return (offset > region.getOffset() + region.getLength() ? -1 : startLine + 1);
+
+        } catch (BadLocationException x) {
+            if (TRACE_ERRORS)
+                System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.getFirstCompleteLineOfRegion")); //$NON-NLS-1$
+        }
+
+        return -1;
+    }
+
+
+    /**
+     * Creates a region describing the text block (something that starts at
+     * the beginning of a line) completely containing the current selection.
+     *
+     * @param selection the selection to use
+     * @return the region describing the text block comprising the given selection
+     * @since 2.0
+     */
+    private IRegion getTextBlockFromSelection(Point selection) {
+
+        try {
+            IDocument document= getDocument();
+            IRegion line= document.getLineInformationOfOffset(selection.x);
+            int length= selection.y is 0 ? line.getLength() : selection.y + (selection.x - line.getOffset());
+            return new Region(line.getOffset(), length);
+
+        } catch (BadLocationException x) {
+        }
+
+        return null;
+    }
+
+    /**
+     * Shifts a text block to the right or left using the specified set of prefix characters.
+     * The prefixes must start at the beginning of the line.
+     *
+     * @param useDefaultPrefixes says whether the configured default or indent prefixes should be used
+     * @param right says whether to shift to the right or the left
+     *
+     * @deprecated use shift(bool, bool, bool) instead
+     */
+    protected void shift(bool useDefaultPrefixes, bool right) {
+        shift(useDefaultPrefixes, right, false);
+    }
+
+    /**
+     * Shifts a text block to the right or left using the specified set of prefix characters.
+     * If white space should be ignored the prefix characters must not be at the beginning of
+     * the line when shifting to the left. There may be whitespace in front of the prefixes.
+     *
+     * @param useDefaultPrefixes says whether the configured default or indent prefixes should be used
+     * @param right says whether to shift to the right or the left
+     * @param ignoreWhitespace says whether whitespace in front of prefixes is allowed
+     * @since 2.0
+     */
+    protected void shift(bool useDefaultPrefixes, bool right, bool ignoreWhitespace) {
+        if (fUndoManager !is null)
+            fUndoManager.beginCompoundChange();
+
+        IDocument d= getDocument();
+        Map partitioners= null;
+        DocumentRewriteSession rewriteSession= null;
+        try {
+            Point selection= getSelectedRange();
+            IRegion block= getTextBlockFromSelection(selection);
+            ITypedRegion[] regions= TextUtilities.computePartitioning(d, getDocumentPartitioning(), block.getOffset(), block.getLength(), false);
+
+            int lineCount= 0;
+            int[] lines= new int[regions.length * 2]; // [start line, end line, start line, end line, ...]
+            for (int i= 0, j= 0; i < regions.length; i++, j+= 2) {
+                // start line of region
+                lines[j]= getFirstCompleteLineOfRegion(regions[i]);
+                // end line of region
+                int length= regions[i].getLength();
+                int offset= regions[i].getOffset() + length;
+                if (length > 0)
+                    offset--;
+                lines[j + 1]= (lines[j] is -1 ? -1 : d.getLineOfOffset(offset));
+                lineCount += lines[j + 1] - lines[j] + 1;
+            }
+
+            if ( cast(IDocumentExtension4)d ) {
+                IDocumentExtension4 extension= cast(IDocumentExtension4) d;
+                rewriteSession= extension.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL);
+            } else {
+                setRedraw(false);
+                startSequentialRewriteMode(true);
+            }
+            if (lineCount >= 20)
+                partitioners= TextUtilities.removeDocumentPartitioners(d);
+
+            // Perform the shift operation.
+            Map map= (useDefaultPrefixes ? fDefaultPrefixChars : fIndentChars);
+                for (int i= 0, j= 0; i < regions.length; i++, j += 2) {
+                String[] prefixes= stringArrayFromObject(selectContentTypePlugin(regions[i].getType(), map));
+                if (prefixes !is null && prefixes.length > 0 && lines[j] >= 0 && lines[j + 1] >= 0) {
+                    if (right)
+                        shiftRight(lines[j], lines[j + 1], prefixes[0]);
+                    else
+                        shiftLeft(lines[j], lines[j + 1], prefixes, ignoreWhitespace);
+                }
+            }
+
+        } catch (BadLocationException x) {
+            if (TRACE_ERRORS)
+                System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.shift_1")); //$NON-NLS-1$
+
+        } finally {
+
+            if (partitioners !is null)
+                TextUtilities.addDocumentPartitioners(d, partitioners);
+
+            if ( cast(IDocumentExtension4)d ) {
+                IDocumentExtension4 extension= cast(IDocumentExtension4) d;
+                extension.stopRewriteSession(rewriteSession);
+            } else {
+                stopSequentialRewriteMode();
+                setRedraw(true);
+            }
+
+            if (fUndoManager !is null)
+                fUndoManager.endCompoundChange();
+        }
+    }
+
+    /**
+     * Shifts the specified lines to the right inserting the given prefix
+     * at the beginning of each line
+     *
+     * @param prefix the prefix to be inserted
+     * @param startLine the first line to shift
+     * @param endLine the last line to shift
+     * @since 2.0
+     */
+    private void shiftRight(int startLine, int endLine, String prefix) {
+
+        try {
+
+            IDocument d= getDocument();
+            while (startLine <= endLine) {
+                d.replace(d.getLineOffset(startLine++), 0, prefix);
+            }
+
+        } catch (BadLocationException x) {
+            if (TRACE_ERRORS)
+                System.out_.println("TextViewer.shiftRight: BadLocationException"); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Shifts the specified lines to the right or to the left. On shifting to the right
+     * it insert <code>prefixes[0]</code> at the beginning of each line. On shifting to the
+     * left it tests whether each of the specified lines starts with one of the specified
+     * prefixes and if so, removes the prefix.
+     *
+     * @param startLine the first line to shift
+     * @param endLine the last line to shift
+     * @param prefixes the prefixes to be used for shifting
+     * @param ignoreWhitespace <code>true</code> if whitespace should be ignored, <code>false</code> otherwise
+     * @since 2.0
+     */
+    private void shiftLeft(int startLine, int endLine, String[] prefixes, bool ignoreWhitespace) {
+
+        IDocument d= getDocument();
+
+        try {
+
+            IRegion[] occurrences= new IRegion[endLine - startLine + 1];
+
+            // find all the first occurrences of prefix in the given lines
+            for (int i= 0; i < occurrences.length; i++) {
+
+                IRegion line= d.getLineInformation(startLine + i);
+                String text= d.get(line.getOffset(), line.getLength());
+
+                int index= -1;
+                int[] found= TextUtilities.indexOf(prefixes, text, 0);
+                if (found[0] !is -1) {
+                    if (ignoreWhitespace) {
+                        String s= d.get(line.getOffset(), found[0]);
+                        s= s.trim();
+                        if (s.length() is 0)
+                            index= line.getOffset() + found[0];
+                    } else if (found[0] is 0)
+                        index= line.getOffset();
+                }
+
+                if (index > -1) {
+                    // remember where prefix is in line, so that it can be removed
+                    int length= prefixes[found[1]].length();
+                    if (length is 0 && !ignoreWhitespace && line.getLength() > 0) {
+                        // found a non-empty line which cannot be shifted
+                        return;
+                    }
+                    occurrences[i]= new Region(index, length);
+                } else {
+                    // found a line which cannot be shifted
+                    return;
+                }
+            }
+
+            // OK - change the document
+            int decrement= 0;
+            for (int i= 0; i < occurrences.length; i++) {
+                IRegion r= occurrences[i];
+                d.replace(r.getOffset() - decrement, r.getLength(), ""); //$NON-NLS-1$
+                decrement += r.getLength();
+            }
+
+        } catch (BadLocationException x) {
+            if (TRACE_ERRORS)
+                System.out_.println("TextViewer.shiftLeft: BadLocationException"); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Returns whether the shown text can be printed.
+     *
+     * @return the viewer's printable mode
+     */
+    protected bool isPrintable() {
+        /*
+         * 1GK7Q10: ITPUI:WIN98 - internal error after invoking print at editor view
+         * Changed from returning true to testing the length of the printer queue
+         */
+        PrinterData[] printerList= Printer.getPrinterList();
+        return (printerList !is null && printerList.length > 0);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 3.4
+     */
+    public void print(StyledTextPrintOptions options) {
+        final PrintDialog dialog= new PrintDialog(fTextWidget.getShell(), DWT.PRIMARY_MODAL);
+        final PrinterData data= dialog.open();
+
+        if (data !is null) {
+            final Printer printer= new Printer(data);
+            final Runnable styledTextPrinter= fTextWidget.print(printer, options);
+
+            void threadrun() {
+                styledTextPrinter.run();
+                printer.dispose();
+            }
+            Thread printingThread= new Thread( &threadrun );
+            printingThread.name = "Printing"; //$NON-NLS-1$
+            printingThread.start();
+        }
+    }
+
+    /**
+     * Brings up a print dialog and calls <code>printContents(Printer)</code>
+     * which performs the actual print.
+     */
+    protected void print() {
+        StyledTextPrintOptions options= new StyledTextPrintOptions();
+        options.printTextFontStyle= true;
+        options.printTextForeground= true;
+        print(options);
+    }
+
+    //------ find support
+
+    /**
+     * Adheres to the contract of {@link IFindReplaceTarget#canPerformFind()}.
+     *
+     * @return <code>true</code> if find can be performed, <code>false</code> otherwise
+     */
+    protected bool canPerformFind() {
+        IDocument d= getVisibleDocument();
+        return (fTextWidget !is null && d !is null && d.getLength() > 0);
+    }
+
+    /**
+     * Adheres to the contract of {@link IFindReplaceTarget#findAndSelect(int, String, bool, bool, bool)}.
+     *
+     * @param startPosition the start position
+     * @param findString the find string specification
+     * @param forwardSearch the search direction
+     * @param caseSensitive <code>true</code> if case sensitive, <code>false</code> otherwise
+     * @param wholeWord <code>true</code> if match must be whole words, <code>false</code> otherwise
+     * @return the model offset of the first match
+     * @deprecated as of 3.0 use {@link #findAndSelect(int, String, bool, bool, bool, bool)}
+     */
+    protected int findAndSelect(int startPosition, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord) {
+        try {
+            return findAndSelect(startPosition, findString, forwardSearch, caseSensitive, wholeWord, false);
+        } catch (IllegalStateException ex) {
+            return -1;
+        } catch (PatternSyntaxException ex) {
+            return -1;
+        }
+    }
+
+    /**
+     * Adheres to the contract of
+     * {@link dwtx.jface.text.IFindReplaceTargetExtension3#findAndSelect(int, String, bool, bool, bool, bool)}.
+     *
+     * @param startPosition the start position
+     * @param findString the find string specification
+     * @param forwardSearch the search direction
+     * @param caseSensitive <code>true</code> if case sensitive, <code>false</code> otherwise
+     * @param wholeWord <code>true</code> if matches must be whole words, <code>false</code> otherwise
+     * @param regExSearch <code>true</code> if <code>findString</code> is a regular expression, <code>false</code> otherwise
+     * @return the model offset of the first match
+     *
+     */
+    protected int findAndSelect(int startPosition, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord, bool regExSearch) {
+        if (fTextWidget is null)
+            return -1;
+
+        try {
+
+            int widgetOffset= (startPosition is -1 ? startPosition : modelOffset2WidgetOffset(startPosition));
+            FindReplaceDocumentAdapter adapter= getFindReplaceDocumentAdapter();
+            IRegion matchRegion= adapter.find(widgetOffset, findString, forwardSearch, caseSensitive, wholeWord, regExSearch);
+            if (matchRegion !is null) {
+                int widgetPos= matchRegion.getOffset();
+                int length= matchRegion.getLength();
+
+                // Prevents setting of widget selection with line delimiters at beginning or end
+                char startChar= adapter.charAt(widgetPos);
+                char endChar= adapter.charAt(widgetPos+length-1);
+                bool borderHasLineDelimiter= startChar is '\n' || startChar is '\r' || endChar is '\n' || endChar is '\r';
+                bool redraws_= redraws();
+                if (borderHasLineDelimiter && redraws_)
+                    setRedraw(false);
+
+                if (redraws()) {
+                    fTextWidget.setSelectionRange(widgetPos, length);
+                    internalRevealRange(widgetPos, widgetPos + length);
+                    selectionChanged(widgetPos, length);
+                } else {
+                    setSelectedRange(widgetOffset2ModelOffset(widgetPos), length);
+                    if (redraws_)
+                        setRedraw(true);
+                }
+
+                return widgetOffset2ModelOffset(widgetPos);
+            }
+
+        } catch (BadLocationException x) {
+            if (TRACE_ERRORS)
+                System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.findAndSelect")); //$NON-NLS-1$
+        }
+
+        return -1;
+    }
+
+    /**
+     * Adheres to the contract of {@link dwtx.jface.text.IFindReplaceTargetExtension3#findAndSelect(int, String, bool, bool, bool, bool)}.
+     *
+     * @param startPosition the start position
+     * @param findString the find string specification
+     * @param forwardSearch the search direction
+     * @param caseSensitive <code>true</code> if case sensitive, <code>false</code> otherwise
+     * @param wholeWord <code>true</code> if matches must be whole words, <code>false</code> otherwise
+     * @param rangeOffset the search scope offset
+     * @param rangeLength the search scope length
+     * @param regExSearch <code>true</code> if <code>findString</code> is a regular expression, <code>false</code> otherwise
+     * @return the model offset of the first match
+     * @since 3.0
+     */
+    protected int findAndSelectInRange(int startPosition, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord, int rangeOffset, int rangeLength, bool regExSearch) {
+        if (fTextWidget is null)
+            return -1;
+
+        try {
+
+            int modelOffset;
+            if (forwardSearch && (startPosition is -1 || startPosition < rangeOffset)) {
+                modelOffset= rangeOffset;
+            } else if (!forwardSearch && (startPosition is -1 || startPosition > rangeOffset + rangeLength)) {
+                modelOffset= rangeOffset + rangeLength;
+            } else {
+                modelOffset= startPosition;
+            }
+
+            int widgetOffset= modelOffset2WidgetOffset(modelOffset);
+            if (widgetOffset is -1)
+                return -1;
+
+            FindReplaceDocumentAdapter adapter= getFindReplaceDocumentAdapter();
+            IRegion matchRegion= adapter.find(widgetOffset, findString, forwardSearch, caseSensitive, wholeWord, regExSearch);
+            int widgetPos= -1;
+            int length= 0;
+            if (matchRegion !is null) {
+                widgetPos= matchRegion.getOffset();
+                length= matchRegion.getLength();
+            }
+            int modelPos= widgetPos is -1 ? -1 : widgetOffset2ModelOffset(widgetPos);
+
+            if (widgetPos !is -1 && (modelPos < rangeOffset || modelPos + length > rangeOffset + rangeLength))
+                widgetPos= -1;
+
+            if (widgetPos > -1) {
+
+                // Prevents setting of widget selection with line delimiters at beginning or end
+                char startChar= adapter.charAt(widgetPos);
+                char endChar= adapter.charAt(widgetPos+length-1);
+                bool borderHasLineDelimiter= startChar is '\n' || startChar is '\r' || endChar is '\n' || endChar is '\r';
+                bool redraws_= redraws();
+                if (borderHasLineDelimiter && redraws_)
+                    setRedraw(false);
+
+                if (redraws()) {
+                    fTextWidget.setSelectionRange(widgetPos, length);
+                    internalRevealRange(widgetPos, widgetPos + length);
+                    selectionChanged(widgetPos, length);
+                } else {
+                    setSelectedRange(modelPos, length);
+                    if (redraws_)
+                        setRedraw(true);
+                }
+
+                return modelPos;
+            }
+
+
+        } catch (BadLocationException x) {
+            if (TRACE_ERRORS)
+                System.out_.println(JFaceTextMessages.getString("TextViewer.error.bad_location.findAndSelect")); //$NON-NLS-1$
+        }
+
+        return -1;
+    }
+
+    //---------- text presentation support
+
+    /*
+     * @see ITextViewer#setTextColor(Color)
+     */
+    public void setTextColor(Color color) {
+        if (color !is null)
+            setTextColor(color, 0, getDocument().getLength(), true);
+    }
+
+    /*
+     * @see ITextViewer#setTextColor(Color, start, length, bool)
+     */
+    public void setTextColor(Color color, int start, int length, bool controlRedraw) {
+        if (fTextWidget !is null) {
+
+            StyleRange s= new StyleRange();
+            s.foreground= color;
+            s.start= start;
+            s.length= length;
+
+            s= modelStyleRange2WidgetStyleRange(s);
+            if (s !is null) {
+                if (controlRedraw)
+                    fTextWidget.setRedraw(false);
+                try {
+                    fTextWidget.setStyleRange(s);
+                } finally {
+                    if (controlRedraw)
+                        fTextWidget.setRedraw(true);
+                }
+            }
+        }
+    }
+
+    /**
+     * Adds the given presentation to the viewer's style information.
+     *
+     * @param presentation the presentation to be added
+     */
+    private void addPresentation(TextPresentation presentation) {
+
+        StyleRange range= presentation.getDefaultStyleRange();
+        if (range !is null) {
+
+            range= modelStyleRange2WidgetStyleRange(range);
+            if (range !is null)
+                fTextWidget.setStyleRange(range);
+
+            ArrayList ranges= new ArrayList(presentation.getDenumerableRanges());
+            Iterator e= presentation.getNonDefaultStyleRangeIterator();
+            while (e.hasNext()) {
+                range= cast(StyleRange) e.next();
+                range= modelStyleRange2WidgetStyleRange(range);
+                if (range !is null)
+                    ranges.add(range);
+            }
+
+            if (!ranges.isEmpty())
+                fTextWidget.replaceStyleRanges(0, 0, arraycast!(StyleRange)(ranges.toArray()));
+
+        } else {
+            IRegion region= modelRange2WidgetRange(presentation.getCoverage());
+            if (region is null)
+                return;
+
+            List list= new ArrayList(presentation.getDenumerableRanges());
+            Iterator e= presentation.getAllStyleRangeIterator();
+            while (e.hasNext()) {
+                range= cast(StyleRange) e.next();
+                range= modelStyleRange2WidgetStyleRange(range);
+                if (range !is null)
+                    list.add(range);
+            }
+
+            if (!list.isEmpty()) {
+                StyleRange[] ranges= new StyleRange[list.size()];
+                list.toArray(ranges);
+                fTextWidget.replaceStyleRanges(region.getOffset(), region.getLength(), ranges);
+            }
+        }
+    }
+
+    /**
+     * Applies the given presentation to the given text widget. Helper method.
+     *
+     * @param presentation the style information
+     * @since 2.1
+     */
+    private void applyTextPresentation(TextPresentation presentation) {
+
+        List list= new ArrayList(presentation.getDenumerableRanges());
+        Iterator e= presentation.getAllStyleRangeIterator();
+        while (e.hasNext()) {
+            StyleRange range= cast(StyleRange) e.next();
+            range= modelStyleRange2WidgetStyleRange(range);
+            if (range !is null)
+                list.add(range);
+        }
+
+        if (!list.isEmpty()) {
+            StyleRange[] ranges= new StyleRange[list.size()];
+            list.toArray(ranges);
+            fTextWidget.setStyleRanges(ranges);
+        }
+    }
+
+    /**
+     * Returns the visible region if it is not equal to the whole document.
+     * Otherwise returns <code>null</code>.
+     *
+     * @return the viewer's visible region if smaller than input document, otherwise <code>null</code>
+     */
+    protected IRegion _internalGetVisibleRegion() {
+
+        IDocument document= getVisibleDocument();
+        if ( cast(ChildDocument)document ) {
+            Position p= (cast(ChildDocument) document).getParentDocumentRange();
+            return new Region(p.getOffset(), p.getLength());
+        }
+
+        return null;
+    }
+
+    /*
+     * @see ITextViewer#changeTextPresentation(TextPresentation, bool)
+     */
+    public void changeTextPresentation(TextPresentation presentation, bool controlRedraw) {
+
+        if (presentation is null || !redraws())
+            return;
+
+        if (fTextWidget is null)
+            return;
+
+
+        /*
+         * Call registered text presentation listeners
+         * and let them apply their presentation.
+         */
+        if (fTextPresentationListeners !is null) {
+            ArrayList listeners= new ArrayList(fTextPresentationListeners);
+            for (int i= 0, size= listeners.size(); i < size; i++) {
+                ITextPresentationListener listener= cast(ITextPresentationListener)listeners.get(i);
+                listener.applyTextPresentation(presentation);
+            }
+        }
+
+        if (presentation.isEmpty())
+            return;
+
+        if (controlRedraw)
+            fTextWidget.setRedraw(false);
+
+        if (fReplaceTextPresentation)
+            applyTextPresentation(presentation);
+        else
+            addPresentation(presentation);
+
+        if (controlRedraw)
+            fTextWidget.setRedraw(true);
+    }
+
+    /*
+     * @see ITextViewer#getFindReplaceTarget()
+     */
+    public IFindReplaceTarget getFindReplaceTarget() {
+        if (fFindReplaceTarget is null)
+            fFindReplaceTarget= new FindReplaceTarget();
+        return fFindReplaceTarget;
+    }
+
+    /**
+     * Returns the find/replace document adapter.
+     *
+     * @return the find/replace document adapter.
+     * @since 3.0
+     */
+    protected FindReplaceDocumentAdapter getFindReplaceDocumentAdapter() {
+        if (fFindReplaceDocumentAdapter is null)
+            fFindReplaceDocumentAdapter= new FindReplaceDocumentAdapter(getVisibleDocument());
+        return fFindReplaceDocumentAdapter;
+    }
+
+    /*
+     * @see ITextViewer#getTextOperationTarget()
+     */
+    public ITextOperationTarget getTextOperationTarget() {
+        return this;
+    }
+
+    /*
+     * @see ITextViewerExtension#appendVerifyKeyListener(VerifyKeyListener)
+     * @since 2.0
+     */
+    public void appendVerifyKeyListener(VerifyKeyListener listener) {
+        int index= fVerifyKeyListenersManager.numberOfListeners();
+        fVerifyKeyListenersManager.insertListener(listener, index);
+    }
+
+    /*
+     * @see ITextViewerExtension#prependVerifyKeyListener(VerifyKeyListener)
+     * @since 2.0
+     */
+    public void prependVerifyKeyListener(VerifyKeyListener listener) {
+        fVerifyKeyListenersManager.insertListener(listener, 0);
+
+    }
+
+    /*
+     * @see ITextViewerExtension#removeVerifyKeyListener(VerifyKeyListener)
+     * @since 2.0
+     */
+    public void removeVerifyKeyListener(VerifyKeyListener listener) {
+        fVerifyKeyListenersManager.removeListener(listener);
+    }
+
+    /*
+     * @see ITextViewerExtension#getMark()
+     * @since 2.0
+     */
+    public int getMark() {
+        return fMarkPosition is null || fMarkPosition.isDeleted() ? -1 : fMarkPosition.getOffset();
+    }
+
+    /*
+     * @see ITextViewerExtension#setMark(int)
+     * @since 2.0
+     */
+    public void setMark(int offset) {
+
+        // clear
+        if (offset is -1) {
+            if (fMarkPosition !is null && !fMarkPosition.isDeleted()) {
+
+                IDocument document= getDocument();
+                if (document !is null)
+                    document.removePosition(fMarkPosition);
+            }
+
+            fMarkPosition= null;
+
+            markChanged(-1, 0);
+
+        // set
+        } else {
+
+            IDocument document= getDocument();
+            if (document is null) {
+                fMarkPosition= null;
+                return;
+            }
+
+            if (fMarkPosition !is null)
+                document.removePosition(fMarkPosition);
+
+            fMarkPosition= null;
+
+            try {
+
+                Position position= new Position(offset);
+                document.addPosition(MARK_POSITION_CATEGORY, position);
+                fMarkPosition= position;
+
+            } catch (BadLocationException e) {
+                return;
+            } catch (BadPositionCategoryException e) {
+                return;
+            }
+
+            markChanged(modelOffset2WidgetOffset(fMarkPosition.offset), 0);
+        }
+    }
+
+    /*
+     * @see Viewer#inputChanged(Object, Object)
+     * @since 2.0
+     */
+    protected void inputChanged(Object newInput, Object oldInput) {
+
+        IDocument oldDocument= cast(IDocument) oldInput;
+        if (oldDocument !is null) {
+
+            if (fMarkPosition !is null && !fMarkPosition.isDeleted())
+                oldDocument.removePosition(fMarkPosition);
+
+            try {
+                oldDocument.removePositionUpdater(fMarkPositionUpdater);
+                oldDocument.removePositionCategory(MARK_POSITION_CATEGORY);
+
+            } catch (BadPositionCategoryException e) {
+            }
+        }
+
+        fMarkPosition= null;
+
+        if ( cast(IDocumentExtension4)oldDocument ) {
+            IDocumentExtension4 document= cast(IDocumentExtension4) oldDocument;
+            document.removeDocumentRewriteSessionListener(fDocumentRewriteSessionListener);
+        }
+
+        super.inputChanged(newInput, oldInput);
+
+        if ( cast(IDocumentExtension4)newInput ) {
+            IDocumentExtension4 document= cast(IDocumentExtension4) newInput;
+            document.addDocumentRewriteSessionListener(fDocumentRewriteSessionListener);
+        }
+
+        IDocument newDocument= cast(IDocument) newInput;
+        if (newDocument !is null) {
+            newDocument.addPositionCategory(MARK_POSITION_CATEGORY);
+            newDocument.addPositionUpdater(fMarkPositionUpdater);
+        }
+    }
+
+    /**
+     * Informs all text listeners about the change of the viewer's redraw state.
+     * @since 2.0
+     */
+    private void fireRedrawChanged() {
+        fWidgetCommand.start= 0;
+        fWidgetCommand.length= 0;
+        fWidgetCommand.text= null;
+        fWidgetCommand.event= null;
+        updateTextListeners(fWidgetCommand);
+    }
+
+    /**
+     * Enables the redrawing of this text viewer.
+     * @since 2.0
+     */
+    protected void enabledRedrawing() {
+        enabledRedrawing(-1);
+    }
+    /**
+     * Enables the redrawing of this text viewer.
+     *
+     * @param topIndex the top index to be set or <code>-1</code>
+     * @since 3.0
+     */
+    protected void enabledRedrawing(int topIndex) {
+        if ( cast(IDocumentAdapterExtension)fDocumentAdapter ) {
+            IDocumentAdapterExtension extension= cast(IDocumentAdapterExtension) fDocumentAdapter;
+            StyledText textWidget= getTextWidget();
+            if (textWidget !is null && !textWidget.isDisposed()) {
+                extension.resumeForwardingDocumentChanges();
+                if (topIndex > -1) {
+                    try {
+                        setTopIndex(topIndex);
+                    } catch (IllegalArgumentException x) {
+                        // changes don't allow for the previous top pixel
+                    }
+                }
+            }
+        }
+
+        if (fViewerState !is null) {
+            fViewerState.restore(topIndex is -1);
+            fViewerState= null;
+        }
+
+        if (fTextWidget !is null && !fTextWidget.isDisposed())
+            fTextWidget.setRedraw(true);
+
+        fireRedrawChanged();
+    }
+
+    /**
+     * Disables the redrawing of this text viewer. Subclasses may extend.
+     * @since 2.0
+     */
+    protected void disableRedrawing() {
+        if (fViewerState is null)
+            fViewerState= new ViewerState();
+
+        if ( cast(IDocumentAdapterExtension)fDocumentAdapter ) {
+            IDocumentAdapterExtension extension= cast(IDocumentAdapterExtension) fDocumentAdapter;
+            extension.stopForwardingDocumentChanges();
+        }
+
+        if (fTextWidget !is null && !fTextWidget.isDisposed())
+            fTextWidget.setRedraw(false);
+
+        fireRedrawChanged();
+    }
+
+    /*
+     * @see ITextViewerExtension#setRedraw(bool)
+     * @since 2.0
+     */
+    public final void setRedraw(bool redraw) {
+        setRedraw(redraw, -1);
+    }
+
+    /**
+     * Basically same functionality as
+     * <code>ITextViewerExtension.setRedraw(bool)</code>. Adds a way for
+     * subclasses to pass in a desired top index that should be used when
+     * <code>redraw</code> is <code>true</code>. If <code>topIndex</code>
+     * is -1, this method is identical to
+     * <code>ITextViewerExtension.setRedraw(bool)</code>.
+     *
+     * @see ITextViewerExtension#setRedraw(bool)
+     *
+     * @param redraw
+     * @param topIndex
+     * @since 3.0
+     */
+    protected final void setRedraw(bool redraw, int topIndex) {
+        if (!redraw) {
+
+            ++ fRedrawCounter;
+            if (fRedrawCounter is 1)
+                disableRedrawing();
+
+        } else {
+            -- fRedrawCounter;
+            if (fRedrawCounter is 0) {
+                if (topIndex is -1)
+                    enabledRedrawing();
+                else
+                    enabledRedrawing(topIndex);
+            }
+        }
+    }
+
+    /**
+     * Returns whether this viewer redraws itself.
+     *
+     * @return <code>true</code> if this viewer redraws itself
+     * @since 2.0
+     */
+    protected final bool redraws() {
+        return fRedrawCounter <= 0;
+    }
+
+    /**
+     * Starts  the sequential rewrite mode of the viewer's document.
+     *
+     * @param normalized <code>true</code> if the rewrite is performed from the start to the end of the document
+     * @since 2.0
+     * @deprecated since 3.1 use {@link IDocumentExtension4#startRewriteSession(DocumentRewriteSessionType)} instead
+     */
+    protected final void startSequentialRewriteMode(bool normalized) {
+        IDocument document= getDocument();
+        if ( cast(IDocumentExtension)document ) {
+            IDocumentExtension extension= cast(IDocumentExtension) document;
+            extension.startSequentialRewrite(normalized);
+        }
+    }
+
+    /**
+     * Sets the sequential rewrite mode of the viewer's document.
+     *
+     * @since 2.0
+     * @deprecated since 3.1 use {@link IDocumentExtension4#stopRewriteSession(DocumentRewriteSession)} instead
+     */
+    protected final void stopSequentialRewriteMode() {
+        IDocument document= getDocument();
+        if ( cast(IDocumentExtension)document ) {
+            IDocumentExtension extension= cast(IDocumentExtension) document;
+            extension.stopSequentialRewrite();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextViewerExtension#getRewriteTarget()
+     * @since 2.0
+     */
+    public IRewriteTarget getRewriteTarget() {
+        if (fRewriteTarget is null)
+            fRewriteTarget= new RewriteTarget();
+        return fRewriteTarget;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextViewerExtension2#getCurrentTextHover()
+     */
+    public ITextHover getCurrentTextHover() {
+        if (fTextHoverManager is null)
+            return null;
+        return fTextHoverManager.getCurrentTextHover_package();
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextViewerExtension2#getHoverEventLocation()
+     */
+    public Point getHoverEventLocation() {
+        if (fTextHoverManager is null)
+            return null;
+        return fTextHoverManager.getHoverEventLocation_package();
+    }
+
+    /**
+     * Returns the paint manager of this viewer.
+     *
+     * @return the paint manager of this viewer
+     * @since 2.1
+     */
+    protected PaintManager getPaintManager() {
+        if (fPaintManager is null)
+            fPaintManager= new PaintManager(this);
+        return fPaintManager;
+    }
+
+    /**
+     * Adds the given  painter to this viewer. If the painter is already registered
+     * this method is without effect.
+     *
+     * @param painter the painter to be added
+     * @since 2.1
+     */
+    public void addPainter(IPainter painter) {
+        getPaintManager().addPainter(painter);
+    }
+
+    /**
+     * Removes the given painter from this viewer. If the painter has previously not been
+     * added to this viewer this method is without effect.
+     *
+     * @param painter the painter to be removed
+     * @since 2.1
+     */
+    public void removePainter(IPainter painter) {
+        getPaintManager().removePainter(painter);
+    }
+
+    // ----------------------------------- conversions -------------------------------------------------------
+
+    /**
+     * Implements the contract of {@link ITextViewerExtension5#modelLine2WidgetLine(int)}.
+     *
+     * @param modelLine the model line
+     * @return the corresponding widget line or <code>-1</code>
+     * @since 2.1
+     */
+    public int modelLine2WidgetLine(int modelLine) {
+        if (fInformationMapping is null)
+            return modelLine;
+
+        try {
+            return fInformationMapping.toImageLine(modelLine);
+        } catch (BadLocationException x) {
+    }
+
+        return -1;
+    }
+
+    /**
+     * Implements the contract of {@link ITextViewerExtension5#modelOffset2WidgetOffset(int)}.
+     *
+     * @param modelOffset the model offset
+     * @return the corresponding widget offset or <code>-1</code>
+     * @since 2.1
+     */
+    public int modelOffset2WidgetOffset(int modelOffset) {
+        if (fInformationMapping is null)
+            return modelOffset;
+
+        try {
+            return fInformationMapping.toImageOffset(modelOffset);
+        } catch (BadLocationException x) {
+        }
+
+        return -1;
+    }
+
+    /**
+     * Implements the contract of {@link ITextViewerExtension5#modelRange2WidgetRange(IRegion)}.
+     *
+     * @param modelRange the model range
+     * @return the corresponding widget range or <code>null</code>
+     * @since 2.1
+     */
+    public IRegion modelRange2WidgetRange(IRegion modelRange) {
+        if (fInformationMapping is null)
+            return modelRange;
+
+        try {
+
+            if (modelRange.getLength() < 0) {
+                Region reversed= new Region(modelRange.getOffset() + modelRange.getLength(), -modelRange.getLength());
+                IRegion result= fInformationMapping.toImageRegion(reversed);
+                if (result !is null)
+                    return new Region(result.getOffset() + result.getLength(), -result.getLength());
+            }
+            return fInformationMapping.toImageRegion(modelRange);
+
+        } catch (BadLocationException x) {
+        }
+
+        return null;
+    }
+
+    /**
+     * Similar to {@link #modelRange2WidgetRange(IRegion)}, but more forgiving:
+     * if <code>modelRange</code> describes a region entirely hidden in the
+     * image, then this method returns the zero-length region at the offset of
+     * the folded region.
+     *
+     * @param modelRange the model range
+     * @return the corresponding widget range, or <code>null</code>
+     * @since 3.1
+     */
+    protected IRegion modelRange2ClosestWidgetRange(IRegion modelRange) {
+        if (!( cast(IDocumentInformationMappingExtension2)fInformationMapping ))
+            return modelRange2WidgetRange(modelRange);
+
+        try {
+            if (modelRange.getLength() < 0) {
+                Region reversed= new Region(modelRange.getOffset() + modelRange.getLength(), -modelRange.getLength());
+                IRegion result= (cast(IDocumentInformationMappingExtension2) fInformationMapping).toClosestImageRegion(reversed);
+                if (result !is null)
+                    return new Region(result.getOffset() + result.getLength(), -result.getLength());
+            }
+            return (cast(IDocumentInformationMappingExtension2) fInformationMapping).toClosestImageRegion(modelRange);
+
+        } catch (BadLocationException x) {
+        }
+
+        return null;
+    }
+
+    /**
+     * Implements the contract of {@link ITextViewerExtension5#widgetLine2ModelLine(int)}.
+     *
+     * @param widgetLine the widget line
+     * @return the corresponding model line
+     * @since 2.1
+     */
+    public int widgetlLine2ModelLine(int widgetLine) {
+        return widgetLine2ModelLine(widgetLine);
+    }
+
+    /**
+     * Implements the contract of {@link ITextViewerExtension5#widgetLine2ModelLine(int)}.
+     *
+     * @param widgetLine the widget line
+     * @return the corresponding model line or <code>-1</code>
+     * @since 3.0
+     */
+    public int widgetLine2ModelLine(int widgetLine) {
+        if (fInformationMapping is null)
+            return widgetLine;
+
+        try {
+            return fInformationMapping.toOriginLine(widgetLine);
+        } catch (BadLocationException x) {
+        }
+
+        return -1;
+    }
+
+    /**
+     * Implements the contract of {@link ITextViewerExtension5#widgetOffset2ModelOffset(int)}.
+     *
+     * @param widgetOffset the widget offset
+     * @return the corresponding model offset or <code>-1</code>
+     * @since 2.1
+     */
+    public int widgetOffset2ModelOffset(int widgetOffset) {
+        if (fInformationMapping is null)
+            return widgetOffset;
+
+        try {
+            return fInformationMapping.toOriginOffset(widgetOffset);
+        } catch (BadLocationException x) {
+            if (widgetOffset is getVisibleDocument().getLength()) {
+                IRegion coverage= fInformationMapping.getCoverage();
+                return coverage.getOffset() + coverage.getLength();
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Implements the contract of {@link ITextViewerExtension5#widgetRange2ModelRange(IRegion)}.
+     *
+     * @param widgetRange the widget range
+     * @return the corresponding model range or <code>null</code>
+     * @since 2.1
+     */
+    public IRegion widgetRange2ModelRange(IRegion widgetRange) {
+        if (fInformationMapping is null)
+            return widgetRange;
+
+        try {
+
+            if (widgetRange.getLength() < 0) {
+                Region reveresed= new Region(widgetRange.getOffset() + widgetRange.getLength(), -widgetRange.getLength());
+                IRegion result= fInformationMapping.toOriginRegion(reveresed);
+                return new Region(result.getOffset() + result.getLength(), -result.getLength());
+            }
+
+            return fInformationMapping.toOriginRegion(widgetRange);
+
+        } catch (BadLocationException x) {
+            int modelOffset= widgetOffset2ModelOffset(widgetRange.getOffset());
+            if (modelOffset > -1) {
+                int modelEndOffset= widgetOffset2ModelOffset(widgetRange.getOffset() + widgetRange.getLength());
+                if (modelEndOffset > -1)
+                    return new Region(modelOffset, modelEndOffset - modelOffset);
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Implements the contract of {@link ITextViewerExtension5#getModelCoverage()}.
+     *
+     * @return the model coverage
+     * @since 2.1
+     */
+    public IRegion getModelCoverage() {
+        if (fInformationMapping is null) {
+            IDocument document= getDocument();
+            if (document is null)
+                return null;
+            return new Region(0, document.getLength());
+        }
+
+        return fInformationMapping.getCoverage();
+    }
+
+    /**
+     * Returns the line of the widget whose corresponding line in the viewer's document
+     * is closest to the given line in the viewer's document or <code>-1</code>.
+     *
+     * @param modelLine the line in the viewer's document
+     * @return the line in the widget that corresponds best to the given line in the viewer's document or <code>-1</code>
+     * @since 2.1
+     */
+    protected int getClosestWidgetLineForModelLine(int modelLine) {
+        if (fInformationMapping is null)
+            return modelLine;
+
+        try {
+            return fInformationMapping.toClosestImageLine(modelLine);
+        } catch (BadLocationException x) {
+        }
+
+        return -1;
+    }
+
+    /**
+     * Translates a style range given relative to the viewer's document into style
+     * ranges relative to the viewer's widget or <code>null</code>.
+     *
+     * @param range the style range in the coordinates of the viewer's document
+     * @return the style range in the coordinates of the viewer's widget or <code>null</code>
+     * @since 2.1
+     */
+    protected StyleRange modelStyleRange2WidgetStyleRange(StyleRange range) {
+        IRegion region= modelRange2WidgetRange(new Region(range.start, range.length));
+        if (region !is null) {
+            StyleRange result= cast(StyleRange) range.clone();
+            result.start= region.getOffset();
+            result.length= region.getLength();
+            return result;
+        }
+        return null;
+    }
+
+    /**
+     * Same as {@link #modelRange2WidgetRange(IRegion)} just for a {@link dwtx.jface.text.Position}.
+     *
+     * @param modelPosition the position describing a range in the viewer's document
+     * @return a region describing a range in the viewer's widget
+     * @since 2.1
+     */
+    protected IRegion modelRange2WidgetRange(Position modelPosition) {
+        return modelRange2WidgetRange(new Region(modelPosition.getOffset(), modelPosition.getLength()));
+    }
+
+    /**
+     * Translates the widget region of the given verify event into
+     * the corresponding region of the viewer's document.
+     *
+     * @param event the verify event
+     * @return the region of the viewer's document corresponding to the verify event
+     * @since 2.1
+     */
+    protected IRegion event2ModelRange(VerifyEvent event) {
+
+        Region region= null;
+        if (event.start <= event.end)
+            region= new Region(event.start, event.end - event.start);
+        else
+            region= new Region(event.end, event.start - event.end);
+
+        return widgetRange2ModelRange(region);
+    }
+
+    /**
+     * Translates the given widget selection into the corresponding region
+     * of the viewer's document or returns <code>null</code> if this fails.
+     *
+     * @param widgetSelection the widget selection
+     * @return the region of the viewer's document corresponding to the widget selection or <code>null</code>
+     * @since 2.1
+     */
+    protected Point widgetSelection2ModelSelection(Point widgetSelection) {
+        IRegion region= new Region(widgetSelection.x, widgetSelection.y);
+        region= widgetRange2ModelRange(region);
+        return region is null ? null : new Point(region.getOffset(), region.getLength());
+    }
+
+    /**
+     * Translates the given selection range of the viewer's document into
+     * the corresponding widget range or returns <code>null</code> of this fails.
+     *
+     * @param modelSelection the selection range of the viewer's document
+     * @return the widget range corresponding to the selection range or <code>null</code>
+     * @since 2.1
+     */
+    protected Point modelSelection2WidgetSelection(Point modelSelection) {
+        if (fInformationMapping is null)
+            return modelSelection;
+
+        try {
+            IRegion region= new Region(modelSelection.x, modelSelection.y);
+            region= fInformationMapping.toImageRegion(region);
+            if (region !is null)
+                return new Point(region.getOffset(), region.getLength());
+        } catch (BadLocationException x) {
+        }
+
+        return null;
+    }
+
+    /**
+     * Implements the contract of {@link ITextViewerExtension5#widgetLineOfWidgetOffset(int)}.
+     *
+     * @param widgetOffset the widget offset
+     * @return  the corresponding widget line or <code>-1</code>
+     * @since 2.1
+     */
+    public int widgetLineOfWidgetOffset(int widgetOffset) {
+        IDocument document= getVisibleDocument();
+        if (document !is null) {
+            try {
+                return document.getLineOfOffset(widgetOffset);
+            } catch (BadLocationException e) {
+            }
+        }
+        return -1;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextViewerExtension4#moveFocusToWidgetToken()
+     * @since 3.0
+     */
+    public bool moveFocusToWidgetToken() {
+        if ( cast(IWidgetTokenKeeperExtension)fWidgetTokenKeeper ) {
+            IWidgetTokenKeeperExtension extension= cast(IWidgetTokenKeeperExtension) fWidgetTokenKeeper;
+            return extension.setFocus(this);
+        }
+        return false;
+    }
+
+    /**
+     * Sets the document partitioning of this viewer. The partitioning is used by this viewer to
+     * access partitioning information of the viewers input document.
+     *
+     * @param partitioning the partitioning name
+     * @since 3.0
+     */
+    public void setDocumentPartitioning(String partitioning) {
+        fPartitioning= partitioning;
+    }
+
+    /**
+     * Returns the document partitioning for this viewer.
+     *
+     * @return the document partitioning for this viewer
+     * @since 3.0
+     */
+    protected String getDocumentPartitioning() {
+        return fPartitioning;
+    }
+
+    //---- Text presentation listeners ----
+
+    /*
+     * @see ITextViewerExtension4#addTextPresentationListener(ITextPresentationListener)
+     * @since 3.0
+     */
+    public void addTextPresentationListener(ITextPresentationListener listener) {
+
+        Assert.isNotNull(cast(Object)listener);
+
+        if (fTextPresentationListeners is null)
+            fTextPresentationListeners= new ArrayList();
+
+        if (!fTextPresentationListeners.contains(cast(Object)listener))
+            fTextPresentationListeners.add(cast(Object)listener);
+    }
+
+    /*
+     * @see ITextViewerExtension4#removeTextPresentationListener(ITextPresentationListener)
+     * @since 3.0
+     */
+    public void removeTextPresentationListener(ITextPresentationListener listener) {
+
+        Assert.isNotNull(cast(Object)listener);
+
+        if (fTextPresentationListeners !is null) {
+            fTextPresentationListeners.remove(cast(Object)listener);
+            if (fTextPresentationListeners.size() is 0)
+                fTextPresentationListeners= null;
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IEditingSupportRegistry#registerHelper(dwtx.jface.text.IEditingSupport)
+     * @since 3.1
+     */
+    public void register(IEditingSupport helper) {
+        Assert.isLegal(helper !is null);
+        fEditorHelpers.add(cast(Object)helper);
+    }
+
+    /*
+     * @see dwtx.jface.text.IEditingSupportRegistry#deregisterHelper(dwtx.jface.text.IEditingSupport)
+     * @since 3.1
+     */
+    public void unregister(IEditingSupport helper) {
+        fEditorHelpers.remove(cast(Object)helper);
+    }
+
+    /*
+     * @see dwtx.jface.text.IEditingSupportRegistry#getCurrentHelpers()
+     * @since 3.1
+     */
+    public IEditingSupport[] getRegisteredSupports() {
+        return arraycast!(IEditingSupport)( fEditorHelpers.toArray());
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextViewerExtension6#setHyperlinkDetectors(dwtx.jface.text.hyperlink.IHyperlinkDetector[], int)
+     * @since 3.1
+     */
+    public void setHyperlinkDetectors(IHyperlinkDetector[] hyperlinkDetectors, int eventStateMask) {
+        if (fHyperlinkDetectors !is null) {
+            for (int i= 0; i < fHyperlinkDetectors.length; i++) {
+                if (cast(IHyperlinkDetectorExtension)fHyperlinkDetectors[i] )
+                    (cast(IHyperlinkDetectorExtension)fHyperlinkDetectors[i]).dispose();
+            }
+        }
+
+        bool enable= hyperlinkDetectors !is null && hyperlinkDetectors.length > 0;
+        fHyperlinkStateMask= eventStateMask;
+        fHyperlinkDetectors= hyperlinkDetectors;
+        if (enable) {
+            if (fHyperlinkManager !is null) {
+                fHyperlinkManager.setHyperlinkDetectors(fHyperlinkDetectors);
+                fHyperlinkManager.setHyperlinkStateMask(fHyperlinkStateMask);
+            }
+            ensureHyperlinkManagerInstalled();
+        } else {
+            if (fHyperlinkManager !is null)
+                fHyperlinkManager.uninstall();
+            fHyperlinkManager= null;
+        }
+    }
+
+    /**
+     * Sets the hyperlink presenter.
+     * <p>
+     * This is only valid as long as the hyperlink manager hasn't
+     * been created yet.
+     * </p>
+     *
+     * @param hyperlinkPresenter the hyperlink presenter
+     * @throws IllegalStateException if the hyperlink manager has already been created
+     * @since 3.1
+     */
+    public void setHyperlinkPresenter(IHyperlinkPresenter hyperlinkPresenter)  {
+        if (fHyperlinkManager !is null)
+            throw new IllegalStateException();
+
+        fHyperlinkPresenter= hyperlinkPresenter;
+        ensureHyperlinkManagerInstalled();
+    }
+
+    /**
+     * Ensures that the hyperlink manager has been
+     * installed if a hyperlink detector is available.
+     *
+     * @since 3.1
+     */
+    private void ensureHyperlinkManagerInstalled() {
+        if (fHyperlinkDetectors !is null && fHyperlinkDetectors.length > 0 && fHyperlinkPresenter !is null && fHyperlinkManager is null) {
+            HyperlinkManager.DETECTION_STRATEGY strategy= fHyperlinkPresenter.canShowMultipleHyperlinks() ? HyperlinkManager.ALL : HyperlinkManager.FIRST;
+            fHyperlinkManager= new HyperlinkManager(strategy);
+            fHyperlinkManager.install(this, fHyperlinkPresenter, fHyperlinkDetectors, fHyperlinkStateMask);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextViewerExtension7#setTabsToSpacesConverter(dwtx.jface.text.IAutoEditStrategy)
+     * @since 3.3
+     */
+    public void setTabsToSpacesConverter(IAutoEditStrategy converter) {
+        fTabsToSpacesConverter= converter;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/TextViewerHoverManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,541 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.TextViewerHoverManager;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+import tango.core.Thread;
+
+import dwt.custom.StyledText;
+import dwt.events.MouseEvent;
+import dwt.events.MouseMoveListener;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Display;
+import dwtx.core.runtime.ILog;
+import dwtx.core.runtime.IStatus;
+import dwtx.core.runtime.Platform;
+import dwtx.core.runtime.Status;
+
+
+/**
+ * This manager controls the layout, content, and visibility of an information
+ * control in reaction to mouse hover events issued by the text widget of a
+ * text viewer. It overrides <code>computeInformation</code>, so that the
+ * computation is performed in a dedicated background thread. This implies
+ * that the used <code>ITextHover</code> objects must be capable of
+ * operating in a non-UI thread.
+ *
+ * @since 2.0
+ */
+class TextViewerHoverManager : AbstractHoverInformationControlManager , IWidgetTokenKeeper, IWidgetTokenKeeperExtension {
+
+
+    /**
+     * Priority of the hovers managed by this manager.
+     * Default value: <code>0</code>;
+     * @since 3.0
+     */
+    public const static int WIDGET_PRIORITY= 0;
+
+
+    /** The text viewer */
+    private TextViewer fTextViewer;
+    /** The hover information computation thread */
+    private Thread fThread;
+    /** The stopper of the computation thread */
+    private ITextListener fStopper;
+    /** Internal monitor */
+    private Object fMutex;
+    /** The currently shown text hover. */
+    private /+volatile+/ ITextHover fTextHover;
+    /**
+     * Tells whether the next mouse hover event
+     * should be processed.
+     * @since 3.0
+     */
+    private bool fProcessMouseHoverEvent= true;
+    /**
+     * Internal mouse move listener.
+     * @since 3.0
+     */
+    private MouseMoveListener fMouseMoveListener;
+    /**
+     * Internal view port listener.
+     * @since 3.0
+     */
+    private IViewportListener fViewportListener;
+
+
+    /**
+     * Creates a new text viewer hover manager specific for the given text viewer.
+     * The manager uses the given information control creator.
+     *
+     * @param textViewer the viewer for which the controller is created
+     * @param creator the information control creator
+     */
+    public this(TextViewer textViewer, IInformationControlCreator creator) {
+        fMutex= new Object();
+        super(creator);
+        fTextViewer= textViewer;
+        fStopper= new class() ITextListener {
+            public void textChanged(TextEvent event) {
+                synchronized (fMutex) {
+                    if (fThread !is null) {
+implMissing(__FILE__,__LINE__);
+// DWT FIXME: how to handle Thread.interrupt?
+//                         fThread.interrupt();
+                        fThread= null;
+                    }
+                }
+            }
+        };
+        fViewportListener= new class()  IViewportListener {
+            /*
+             * @see dwtx.jface.text.IViewportListener#viewportChanged(int)
+             */
+            public void viewportChanged(int verticalOffset) {
+                fProcessMouseHoverEvent= false;
+            }
+        };
+        fTextViewer.addViewportListener(fViewportListener);
+        fMouseMoveListener= new class()  MouseMoveListener {
+            /*
+             * @see MouseMoveListener#mouseMove(MouseEvent)
+             */
+            public void mouseMove(MouseEvent event) {
+                fProcessMouseHoverEvent= true;
+            }
+        };
+        fTextViewer.getTextWidget().addMouseMoveListener(fMouseMoveListener);
+    }
+
+    /**
+     * Determines all necessary details and delegates the computation into
+     * a background thread.
+     */
+    protected void computeInformation() {
+
+        if (!fProcessMouseHoverEvent) {
+            setInformation(cast(Object)null, null);
+            return;
+        }
+
+        Point location= getHoverEventLocation();
+        int offset= computeOffsetAtLocation(location.x, location.y);
+        if (offset is -1) {
+            setInformation(cast(Object)null, null);
+            return;
+        }
+
+        final ITextHover hover= fTextViewer.getTextHover_package(offset, getHoverEventStateMask());
+        if (hover is null) {
+            setInformation(cast(Object)null, null);
+            return;
+        }
+
+        final IRegion region= hover.getHoverRegion(fTextViewer, offset);
+        if (region is null) {
+            setInformation(cast(Object)null, null);
+            return;
+        }
+
+        final Rectangle area= JFaceTextUtil.computeArea(region, fTextViewer);
+        if (area is null || area.isEmpty()) {
+            setInformation(cast(Object)null, null);
+            return;
+        }
+
+        if (fThread !is null) {
+            setInformation(cast(Object)null, null);
+            return;
+        }
+
+            void threadrun() {
+                // http://bugs.eclipse.org/bugs/show_bug.cgi?id=17693
+                bool hasFinished= false;
+                try {
+                    if (fThread !is null) {
+                        Object information;
+                        try {
+                            if ( cast(ITextHoverExtension2)hover )
+                                information= (cast(ITextHoverExtension2)hover).getHoverInfo2(fTextViewer, region);
+                            else
+                                information= stringcast(hover.getHoverInfo(fTextViewer, region));
+                        } catch (ArrayIndexOutOfBoundsException x) {
+                            /*
+                             * This code runs in a separate thread which can
+                             * lead to text offsets being out of bounds when
+                             * computing the hover info (see bug 32848).
+                             */
+                            information= null;
+                        }
+
+                        if ( cast(ITextHoverExtension)hover )
+                            setCustomInformationControlCreator((cast(ITextHoverExtension) hover).getHoverControlCreator());
+                        else
+                            setCustomInformationControlCreator(null);
+
+                        setInformation(information, area);
+                        if (information !is null)
+                            fTextHover= hover;
+                    } else {
+                        setInformation(cast(Object)null, null);
+                    }
+                    hasFinished= true;
+                } catch (RuntimeException ex) {
+                    String PLUGIN_ID= "dwtx.jface.text"; //$NON-NLS-1$
+                    ILog log= Platform.getLog(Platform.getBundle(PLUGIN_ID));
+                    log.log(new Status(IStatus.ERROR, PLUGIN_ID, IStatus.OK, "Unexpected runtime error while computing a text hover", ex)); //$NON-NLS-1$
+                } finally {
+                    synchronized (fMutex) {
+                        if (fTextViewer !is null)
+                            fTextViewer.removeTextListener(fStopper);
+                        fThread= null;
+                        // https://bugs.eclipse.org/bugs/show_bug.cgi?id=44756
+                        if (!hasFinished)
+                            setInformation(cast(Object)null, null);
+                    }
+                }
+            }
+        fThread= new Thread( &threadrun );
+        fThread.name = "Text Viewer Hover Presenter"; //$NON-NLS-1$
+
+        fThread.isDaemon(true);
+        fThread.priority(Thread.PRIORITY_MIN);
+        synchronized (fMutex) {
+            fTextViewer.addTextListener(fStopper);
+            fThread.start();
+        }
+    }
+
+    /**
+     * As computation is done in the background, this method is
+     * also called in the background thread. Delegates the control
+     * flow back into the UI thread, in order to allow displaying the
+     * information in the information control.
+     */
+    protected void presentInformation() {
+        if (fTextViewer is null)
+            return;
+
+        StyledText textWidget= fTextViewer.getTextWidget();
+        if (textWidget !is null && !textWidget.isDisposed()) {
+            Display display= textWidget.getDisplay();
+            if (display is null)
+                return;
+
+            display.asyncExec(new class()  Runnable {
+                public void run() {
+                    doPresentInformation();
+                }
+            });
+        }
+    }
+
+    /*
+     * @see AbstractInformationControlManager#presentInformation()
+     */
+    protected void doPresentInformation() {
+        super.presentInformation();
+    }
+
+    /**
+     * Computes the document offset underlying the given text widget coordinates.
+     * This method uses a linear search as it cannot make any assumption about
+     * how the document is actually presented in the widget. (Covers cases such
+     * as bidirectional text.)
+     *
+     * @param x the horizontal coordinate inside the text widget
+     * @param y the vertical coordinate inside the text widget
+     * @return the document offset corresponding to the given point
+     */
+    private int computeOffsetAtLocation(int x, int y) {
+
+        try {
+
+            StyledText styledText= fTextViewer.getTextWidget();
+            int widgetOffset= styledText.getOffsetAtLocation(new Point(x, y));
+            Point p= styledText.getLocationAtOffset(widgetOffset);
+            if (p.x > x)
+                widgetOffset--;
+
+            if ( cast(ITextViewerExtension5)fTextViewer ) {
+                ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer;
+                return extension.widgetOffset2ModelOffset(widgetOffset);
+            }
+
+            return widgetOffset + fTextViewer._getVisibleRegionOffset_package();
+
+        } catch (IllegalArgumentException e) {
+            return -1;
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#showInformationControl(dwt.graphics.Rectangle)
+     */
+    protected void showInformationControl(Rectangle subjectArea) {
+        if (fTextViewer !is null && fTextViewer.requestWidgetToken(this, WIDGET_PRIORITY))
+            super.showInformationControl(subjectArea);
+        else
+            if (DEBUG)
+                System.out_.println("TextViewerHoverManager#showInformationControl(..) did not get widget token"); //$NON-NLS-1$
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl()
+     */
+    protected void hideInformationControl() {
+        try {
+            fTextHover= null;
+            super.hideInformationControl();
+        } finally {
+            if (fTextViewer !is null)
+                fTextViewer.releaseWidgetToken(this);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#replaceInformationControl(bool)
+     * @since 3.4
+     */
+    void replaceInformationControl(bool takeFocus) {
+        if (fTextViewer !is null)
+            fTextViewer.releaseWidgetToken(this);
+        super.replaceInformationControl(takeFocus);
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#handleInformationControlDisposed()
+     */
+    protected void handleInformationControlDisposed() {
+        try {
+            super.handleInformationControlDisposed();
+        } finally {
+            if (fTextViewer !is null)
+                fTextViewer.releaseWidgetToken(this);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeper#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner)
+     */
+    public bool requestWidgetToken(IWidgetTokenOwner owner) {
+        fTextHover= null;
+        super.hideInformationControl();
+        return true;
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeperExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner, int)
+     * @since 3.0
+     */
+    public bool requestWidgetToken(IWidgetTokenOwner owner, int priority) {
+        if (priority > WIDGET_PRIORITY) {
+            fTextHover= null;
+            super.hideInformationControl();
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeperExtension#setFocus(dwtx.jface.text.IWidgetTokenOwner)
+     * @since 3.0
+     */
+    public bool setFocus(IWidgetTokenOwner owner) {
+        if (! hasInformationControlReplacer())
+            return false;
+
+        IInformationControl iControl= getCurrentInformationControl();
+        if (canReplace(iControl)) {
+            if (cancelReplacingDelay())
+                replaceInformationControl(true);
+
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns the currently shown text hover or <code>null</code> if no text
+     * hover is shown.
+     *
+     * @return the currently shown text hover or <code>null</code>
+     */
+    protected ITextHover getCurrentTextHover() {
+        return fTextHover;
+    }
+    package ITextHover getCurrentTextHover_package() {
+        return getCurrentTextHover();
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractHoverInformationControlManager#dispose()
+     * @since 3.0
+     */
+    public void dispose() {
+        if (fTextViewer !is null) {
+            fTextViewer.removeViewportListener(fViewportListener);
+            fViewportListener= null;
+
+            StyledText st= fTextViewer.getTextWidget();
+            if (st !is null && !st.isDisposed())
+                st.removeMouseMoveListener(fMouseMoveListener);
+            fMouseMoveListener= null;
+        }
+        super.dispose();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/TextViewerUndoManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,588 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.TextViewerUndoManager;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+
+
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.widgets.Display;
+import dwt.widgets.Shell;
+import dwtx.core.commands.ExecutionException;
+import dwtx.core.commands.operations.IUndoContext;
+import dwtx.jface.dialogs.MessageDialog;
+import dwtx.text.undo.DocumentUndoEvent;
+import dwtx.text.undo.DocumentUndoManager;
+import dwtx.text.undo.DocumentUndoManagerRegistry;
+import dwtx.text.undo.IDocumentUndoListener;
+import dwtx.text.undo.IDocumentUndoManager;
+
+
+/**
+ * Implementation of {@link dwtx.jface.text.IUndoManager} using the shared
+ * document undo manager.
+ * <p>
+ * It registers with the connected text viewer as text input listener, and obtains
+ * its undo manager from the current document.  It also monitors mouse and keyboard
+ * activities in order to partition the stream of text changes into undo-able
+ * edit commands.
+ * <p>
+ * This class is not intended to be subclassed.
+ * </p>
+ *
+ * @see ITextViewer
+ * @see ITextInputListener
+ * @see IDocumentUndoManager
+ * @see MouseListener
+ * @see KeyListener
+ * @see DocumentUndoManager
+ *
+ * @since 3.2
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class TextViewerUndoManager : IUndoManager, IUndoManagerExtension {
+
+
+    /**
+     * Internal listener to mouse and key events.
+     */
+    private class KeyAndMouseListener : MouseListener, KeyListener {
+
+        /*
+         * @see MouseListener#mouseDoubleClick
+         */
+        public void mouseDoubleClick(MouseEvent e) {
+        }
+
+        /*
+         * If the right mouse button is pressed, the current editing command is closed
+         * @see MouseListener#mouseDown
+         */
+        public void mouseDown(MouseEvent e) {
+            if (e.button is 1)
+                if (isConnected())
+                    fDocumentUndoManager.commit();
+        }
+
+        /*
+         * @see MouseListener#mouseUp
+         */
+        public void mouseUp(MouseEvent e) {
+        }
+
+        /*
+         * @see KeyListener#keyPressed
+         */
+        public void keyReleased(KeyEvent e) {
+        }
+
+        /*
+         * On cursor keys, the current editing command is closed
+         * @see KeyListener#keyPressed
+         */
+        public void keyPressed(KeyEvent e) {
+            switch (e.keyCode) {
+                case DWT.ARROW_UP:
+                case DWT.ARROW_DOWN:
+                case DWT.ARROW_LEFT:
+                case DWT.ARROW_RIGHT:
+                    if (isConnected()) {
+                        fDocumentUndoManager.commit();
+                    }
+                    break;
+            }
+        }
+    }
+
+
+    /**
+     * Internal text input listener.
+     */
+    private class TextInputListener : ITextInputListener {
+
+        /*
+         * @see dwtx.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument)
+         */
+        public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
+            disconnectDocumentUndoManager();
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextInputListener#inputDocumentChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument)
+         */
+        public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+            connectDocumentUndoManager(newInput);
+        }
+    }
+
+
+    /**
+     * Internal document undo listener.
+     */
+    private class DocumentUndoListener : IDocumentUndoListener {
+
+        /*
+         * @see dwtx.jface.text.IDocumentUndoListener#documentUndoNotification(DocumentUndoEvent)
+         */
+        public void documentUndoNotification(DocumentUndoEvent event ){
+            if (!isConnected()) return;
+
+            int eventType= event.getEventType();
+            if (((eventType & DocumentUndoEvent.ABOUT_TO_UNDO) !is 0) || ((eventType & DocumentUndoEvent.ABOUT_TO_REDO) !is 0))  {
+                if (event.isCompound()) {
+                    ITextViewerExtension extension= null;
+                    if ( cast(ITextViewerExtension)fTextViewer )
+                        extension= cast(ITextViewerExtension) fTextViewer;
+
+                    if (extension !is null)
+                        extension.setRedraw(false);
+                }
+                fTextViewer.getTextWidget().getDisplay().syncExec(new class()  Runnable {
+                    public void run() {
+                        if ( cast(TextViewer)fTextViewer )
+                            (cast(TextViewer)fTextViewer).ignoreAutoEditStrategies_package(true);
+                    }
+                });
+
+            } else if (((eventType & DocumentUndoEvent.UNDONE) !is 0) || ((eventType & DocumentUndoEvent.REDONE) !is 0))  {
+                fTextViewer.getTextWidget().getDisplay().syncExec(new class()  Runnable {
+                    public void run() {
+                        if ( cast(TextViewer)fTextViewer )
+                            (cast(TextViewer)fTextViewer).ignoreAutoEditStrategies_package(false);
+                    }
+                });
+                if (event.isCompound()) {
+                    ITextViewerExtension extension= null;
+                    if ( cast(ITextViewerExtension)fTextViewer )
+                        extension= cast(ITextViewerExtension) fTextViewer;
+
+                    if (extension !is null)
+                        extension.setRedraw(true);
+                }
+
+                // Reveal the change if this manager's viewer has the focus.
+                if (fTextViewer !is null) {
+                    StyledText widget= fTextViewer.getTextWidget();
+                    if (widget !is null && !widget.isDisposed() && (widget.isFocusControl()))// || fTextViewer.getTextWidget() is control))
+                        selectAndReveal(event.getOffset(), event.getText() is null ? 0 : event.getText().length());
+                }
+            }
+        }
+
+    }
+
+    /** The internal key and mouse event listener */
+    private KeyAndMouseListener fKeyAndMouseListener;
+    /** The internal text input listener */
+    private TextInputListener fTextInputListener;
+
+
+    /** The text viewer the undo manager is connected to */
+    private ITextViewer fTextViewer;
+
+    /** The undo level */
+    private int fUndoLevel;
+
+    /** The document undo manager that is active. */
+    private IDocumentUndoManager fDocumentUndoManager;
+
+    /** The document that is active. */
+    private IDocument fDocument;
+
+    /** The document undo listener */
+    private IDocumentUndoListener fDocumentUndoListener;
+
+    /**
+     * Creates a new undo manager who remembers the specified number of edit commands.
+     *
+     * @param undoLevel the length of this manager's history
+     */
+    public this(int undoLevel) {
+        fUndoLevel= undoLevel;
+    }
+
+    /**
+     * Returns whether this undo manager is connected to a text viewer.
+     *
+     * @return <code>true</code> if connected, <code>false</code> otherwise
+     */
+    private bool isConnected() {
+        return fTextViewer !is null && fDocumentUndoManager !is null;
+    }
+
+    /*
+     * @see IUndoManager#beginCompoundChange
+     */
+    public void beginCompoundChange() {
+        if (isConnected()) {
+            fDocumentUndoManager.beginCompoundChange();
+        }
+    }
+
+
+    /*
+     * @see IUndoManager#endCompoundChange
+     */
+    public void endCompoundChange() {
+        if (isConnected()) {
+            fDocumentUndoManager.endCompoundChange();
+        }
+    }
+
+    /**
+     * Registers all necessary listeners with the text viewer.
+     */
+    private void addListeners() {
+        StyledText text= fTextViewer.getTextWidget();
+        if (text !is null) {
+            fKeyAndMouseListener= new KeyAndMouseListener();
+            text.addMouseListener(fKeyAndMouseListener);
+            text.addKeyListener(fKeyAndMouseListener);
+            fTextInputListener= new TextInputListener();
+            fTextViewer.addTextInputListener(fTextInputListener);
+        }
+    }
+
+    /**
+     * Unregister all previously installed listeners from the text viewer.
+     */
+    private void removeListeners() {
+        StyledText text= fTextViewer.getTextWidget();
+        if (text !is null) {
+            if (fKeyAndMouseListener !is null) {
+                text.removeMouseListener(fKeyAndMouseListener);
+                text.removeKeyListener(fKeyAndMouseListener);
+                fKeyAndMouseListener= null;
+            }
+            if (fTextInputListener !is null) {
+                fTextViewer.removeTextInputListener(fTextInputListener);
+                fTextInputListener= null;
+            }
+        }
+    }
+
+    /**
+     * Shows the given exception in an error dialog.
+     *
+     * @param title the dialog title
+     * @param ex the exception
+     */
+    private void openErrorDialog(String title, Exception ex) {
+        Shell shell= null;
+        if (isConnected()) {
+            StyledText st= fTextViewer.getTextWidget();
+            if (st !is null && !st.isDisposed())
+                shell= st.getShell();
+        }
+        if (Display.getCurrent() !is null)
+            MessageDialog.openError(shell, title, ex.msg/+getLocalizedMessage()+/);
+        else {
+            Display display;
+            Shell finalShell= shell;
+            if (finalShell !is null)
+                display= finalShell.getDisplay();
+            else
+                display= Display.getDefault();
+            display.syncExec(dgRunnable((Shell finalShell_, String title_, Exception ex_ ) {
+                MessageDialog.openError(finalShell_, title_, ex_.msg/+getLocalizedMessage()+/);
+            },finalShell, title, ex ));
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#setMaximalUndoLevel(int)
+     */
+    public void setMaximalUndoLevel(int undoLevel) {
+        fUndoLevel= Math.max(0, undoLevel);
+        if (isConnected()) {
+            fDocumentUndoManager.setMaximalUndoLevel(fUndoLevel);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#connect(dwtx.jface.text.ITextViewer)
+     */
+    public void connect(ITextViewer textViewer) {
+        if (fTextViewer is null && textViewer !is null) {
+            fTextViewer= textViewer;
+            addListeners();
+        }
+        IDocument doc= fTextViewer.getDocument();
+        connectDocumentUndoManager(doc);
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#disconnect()
+     */
+    public void disconnect() {
+        if (fTextViewer !is null) {
+            removeListeners();
+            fTextViewer= null;
+        }
+        disconnectDocumentUndoManager();
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#reset()
+     */
+    public void reset() {
+        if (isConnected())
+            fDocumentUndoManager.reset();
+
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#redoable()
+     */
+    public bool redoable() {
+        if (isConnected())
+            return fDocumentUndoManager.redoable();
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#undoable()
+     */
+    public bool undoable() {
+        if (isConnected())
+            return fDocumentUndoManager.undoable();
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#redo()
+     */
+    public void redo() {
+        if (isConnected()) {
+            try {
+                fDocumentUndoManager.redo();
+            } catch (ExecutionException ex) {
+                openErrorDialog(JFaceTextMessages.getString("DefaultUndoManager.error.redoFailed.title"), ex); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManager#undo()
+     */
+    public void undo() {
+        if (isConnected()) {
+            try {
+                fDocumentUndoManager.undo();
+            } catch (ExecutionException ex) {
+                openErrorDialog(JFaceTextMessages.getString("DefaultUndoManager.error.undoFailed.title"), ex); //$NON-NLS-1$
+            }
+        }
+    }
+
+    /**
+     * Selects and reveals the specified range.
+     *
+     * @param offset the offset of the range
+     * @param length the length of the range
+     */
+    private void selectAndReveal(int offset, int length) {
+        if ( cast(ITextViewerExtension5)fTextViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer;
+            extension.exposeModelRange(new Region(offset, length));
+        } else if (!fTextViewer.overlapsWithVisibleRegion(offset, length))
+            fTextViewer.resetVisibleRegion();
+
+        fTextViewer.setSelectedRange(offset, length);
+        fTextViewer.revealRange(offset, length);
+    }
+
+    /*
+     * @see dwtx.jface.text.IUndoManagerExtension#getUndoContext()
+     */
+    public IUndoContext getUndoContext() {
+        if (isConnected()) {
+            return fDocumentUndoManager.getUndoContext();
+        }
+        return null;
+    }
+
+    private void connectDocumentUndoManager(IDocument document) {
+        disconnectDocumentUndoManager();
+        if (document !is null) {
+            fDocument= document;
+            DocumentUndoManagerRegistry.connect(fDocument);
+            fDocumentUndoManager= DocumentUndoManagerRegistry.getDocumentUndoManager(fDocument);
+            fDocumentUndoManager.connect(this);
+            setMaximalUndoLevel(fUndoLevel);
+            fDocumentUndoListener= new DocumentUndoListener();
+            fDocumentUndoManager.addDocumentUndoListener(fDocumentUndoListener);
+        }
+    }
+
+    private void disconnectDocumentUndoManager() {
+        if (fDocumentUndoManager !is null) {
+            fDocumentUndoManager.disconnect(this);
+            DocumentUndoManagerRegistry.disconnect(fDocument);
+            fDocumentUndoManager.removeDocumentUndoListener(fDocumentUndoListener);
+            fDocumentUndoListener= null;
+            fDocumentUndoManager= null;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/TreeLineTracker.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1531 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.TreeLineTracker;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.text.convert.Format;
+import tango.core.Exception;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.AbstractLineTracker;
+
+/**
+ * Abstract implementation of <code>ILineTracker</code>. It lets the definition of line
+ * delimiters to subclasses. Assuming that '\n' is the only line delimiter, this abstract
+ * implementation defines the following line scheme:
+ * <ul>
+ * <li> "" -> [0,0]
+ * <li> "a" -> [0,1]
+ * <li> "\n" -> [0,1], [1,0]
+ * <li> "a\n" -> [0,2], [2,0]
+ * <li> "a\nb" -> [0,2], [2,1]
+ * <li> "a\nbc\n" -> [0,2], [2,3], [5,0]
+ * </ul>
+ * <p>
+ * This class must be subclassed.
+ * </p>
+ * <p>
+ * <strong>Performance:</strong> The query operations perform in <i>O(log n)</i> where <var>n</var>
+ * is the number of lines in the document. The modification operations roughly perform in <i>O(l *
+ * log n)</i> where <var>n</var> is the number of lines in the document and <var>l</var> is the
+ * sum of the number of removed, added or modified lines.
+ * </p>
+ *
+ * @since 3.2
+ */
+abstract class TreeLineTracker : ILineTracker {
+    /*
+     * Differential Balanced Binary Tree
+     *
+     * Assumption: lines cannot overlap => there exists a total ordering of the lines by their offset,
+     * which is the same as the ordering by line number
+     *
+     * Base idea: store lines in a binary search tree
+     *   - the key is the line number / line offset
+     *     -> lookup_line is O(log n)
+     *     -> lookup_offset is O(log n)
+     *   - a change in a line somewhere will change any succeeding line numbers / line offsets
+     *     -> replace is O(n)
+     *
+     * Differential tree: instead of storing the key (line number, line offset) directly, every node
+     * stores the difference between its key and its parent's key
+     *   - the sort key is still the line number / line offset, but it remains "virtual"
+     *   - inserting a node (a line) really increases the virtual key of all succeeding nodes (lines), but this
+     *     fact will not be realized in the key information encoded in the nodes.
+     *     -> any change only affects the nodes in the node's parent chain, although more bookkeeping
+     *         has to be done when changing a node or balancing the tree
+     *        -> replace is O(log n)
+     *     -> line offsets and line numbers have to be computed when walking the tree from the root /
+     *         from a node
+     *        -> still O(log n)
+     *
+     * The balancing algorithm chosen does not depend on the differential tree property. An AVL tree
+     * implementation has been chosen for simplicity.
+     */
+
+    /*
+     * Turns assertions on/off. Don't make this a a debug option for performance reasons - this way
+     * the compiler can optimize the asserts away.
+     */
+    private static const bool ASSERT= false;
+
+    /**
+     * The empty delimiter of the last line. The last line and only the last line must have this
+     * zero-length delimiter.
+     */
+    private static const String NO_DELIM= ""; //$NON-NLS-1$
+
+    /**
+     * A node represents one line. Its character and line offsets are 0-based and relative to the
+     * subtree covered by the node. All nodes under the left subtree represent lines before, all
+     * nodes under the right subtree lines after the current node.
+     */
+    private static final class Node {
+        this(int length, String delimiter) {
+            this.length= length;
+            this.delimiter= delimiter;
+        }
+        /**
+         * The line index in this node's line tree, or equivalently, the number of lines in the left
+         * subtree.
+         */
+        int line;
+        /**
+         * The line offset in this node's line tree, or equivalently, the number of characters in
+         * the left subtree.
+         */
+        int offset;
+        /** The number of characters in this line. */
+        int length;
+        /** The line delimiter of this line, needed to answer the delimiter query. */
+        String delimiter;
+        /** The parent node, <code>null</code> if this is the root node. */
+        Node parent;
+        /** The left subtree, possibly <code>null</code>. */
+        Node left;
+        /** The right subtree, possibly <code>null</code>. */
+        Node right;
+        /** The balance factor. */
+        byte balance;
+
+        /*
+         * @see java.lang.Object#toString()
+         */
+        public final override String toString() {
+            String bal;
+            switch (balance) {
+                case 0:
+                    bal= "="; //$NON-NLS-1$
+                    break;
+                case 1:
+                    bal= "+"; //$NON-NLS-1$
+                    break;
+                case 2:
+                    bal= "++"; //$NON-NLS-1$
+                    break;
+                case -1:
+                    bal= "-"; //$NON-NLS-1$
+                    break;
+                case -2:
+                    bal= "--"; //$NON-NLS-1$
+                    break;
+                default:
+                    bal= Byte.toString(balance);
+            }
+            return Format("[{}+{}+{}|{}|{}]", offset, pureLength(), delimiter.length, line, bal ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+        }
+
+        /**
+         * Returns the pure (without the line delimiter) length of this line.
+         *
+         * @return the pure line length
+         */
+        int pureLength() {
+            return length - delimiter.length;
+        }
+    }
+
+    /**
+     * The root node of the tree, never <code>null</code>.
+     */
+    private Node fRoot;
+
+    /**
+     * Creates a new line tracker.
+     */
+    protected this() {
+        fRoot= new Node(0, NO_DELIM);
+    }
+
+    /**
+     * Package visible constructor for creating a tree tracker from a list tracker.
+     *
+     * @param tracker
+     */
+    this(ListLineTracker tracker) {
+        fRoot= new Node(0, NO_DELIM);
+        final List lines= tracker.getLines();
+        final int n= lines.size();
+        if (n is 0)
+            return;
+
+        Line line= cast(Line) lines.get(0);
+        String delim= line.delimiter;
+        if (delim is null)
+            delim= NO_DELIM;
+        int length= line.length;
+        fRoot= new Node(length, delim);
+        Node node= fRoot;
+
+        for (int i= 1; i < n; i++) {
+            line= cast(Line) lines.get(i);
+            delim= line.delimiter;
+            if (delim is null)
+                delim= NO_DELIM;
+            length= line.length;
+            node= insertAfter(node, length, delim);
+        }
+
+        if (node.delimiter !is NO_DELIM)
+            insertAfter(node, 0, NO_DELIM);
+
+        if (ASSERT) checkTree();
+    }
+
+    /**
+     * Returns the node (line) including a certain offset. If the offset is between two
+     * lines, the line starting at <code>offset</code> is returned.
+     * <p>
+     * This means that for offsets smaller than the length, the following holds:
+     * </p>
+     * <p>
+     * <code>line.offset <= offset < line.offset + offset.length</code>.
+     * </p>
+     * <p>
+     * If <code>offset</code> is the document length, then this is true:
+     * </p>
+     * <p>
+     * <code>offset= line.offset + line.length</code>.
+     * </p>
+     *
+     * @param offset a document offset
+     * @return the line starting at or containing <code>offset</code>
+     * @throws BadLocationException if the offset is invalid
+     */
+    private Node nodeByOffset(int offset)  {
+        /*
+         * Works for any binary search tree.
+         */
+        int remaining= offset;
+        Node node= fRoot;
+        int line= 0;
+
+        while (true) {
+            if (node is null)
+                fail(offset);
+
+            if (remaining < node.offset) {
+                node= node.left;
+            } else {
+                remaining -= node.offset;
+                line+= node.line;
+                if (remaining < node.length
+                        || remaining is node.length && node.right is null) { // last line
+                    break;
+                }
+                remaining -= node.length;
+                line ++;
+                node= node.right;
+            }
+        }
+
+        return node;
+    }
+    /**
+     * Returns the line number for the given offset. If the offset is between two lines, the line
+     * starting at <code>offset</code> is returned. The last line is returned if
+     * <code>offset</code> is equal to the document length.
+     *
+     * @param offset a document offset
+     * @return the line number starting at or containing <code>offset</code>
+     * @throws BadLocationException if the offset is invalid
+     */
+    private int lineByOffset(int offset)  {
+        /*
+         * Works for any binary search tree.
+         */
+        int remaining= offset;
+        Node node= fRoot;
+        int line= 0;
+
+        while (true) {
+            if (node is null)
+                fail(offset);
+
+            if (remaining < node.offset) {
+                node= node.left;
+            } else {
+                remaining -= node.offset;
+                line+= node.line;
+                if (remaining < node.length || remaining is node.length && node.right is null) // last line
+                    return  line;
+
+                remaining -= node.length;
+                line ++;
+                node= node.right;
+            }
+        }
+    }
+
+    /**
+     * Returns the node (line) with the given line number. Note that the last line is always
+     * incomplete, i.e. has the {@link #NO_DELIM} delimiter.
+     *
+     * @param line a line number
+     * @return the line with the given line number
+     * @throws BadLocationException if the line is invalid
+     */
+    private Node nodeByLine(int line)  {
+        /*
+         * Works for any binary search tree.
+         */
+        int remaining= line;
+        int offset= 0;
+        Node node= fRoot;
+
+        while (true) {
+            if (node is null)
+                fail(line);
+
+            if (remaining is node.line)
+                break;
+            if (remaining < node.line) {
+                node= node.left;
+            } else {
+                remaining -= node.line + 1;
+                offset += node.offset + node.length;
+                node= node.right;
+            }
+        }
+
+        return node;
+    }
+
+    /**
+     * Returns the offset for the given line number. Note that the
+     * last line is always incomplete, i.e. has the {@link #NO_DELIM} delimiter.
+     *
+     * @param line a line number
+     * @return the line offset with the given line number
+     * @throws BadLocationException if the line is invalid
+     */
+    private int offsetByLine(int line)  {
+        /*
+         * Works for any binary search tree.
+         */
+        int remaining= line;
+        int offset= 0;
+        Node node= fRoot;
+
+        while (true) {
+            if (node is null)
+                fail(line);
+
+            if (remaining is node.line)
+                return offset + node.offset;
+
+            if (remaining < node.line) {
+                node= node.left;
+            } else {
+                remaining -= node.line + 1;
+                offset += node.offset + node.length;
+                node= node.right;
+            }
+        }
+    }
+
+    /**
+     * Left rotation - the given node is rotated down, its right child is rotated up, taking the
+     * previous structural position of <code>node</code>.
+     *
+     * @param node the node to rotate around
+     */
+    private void rotateLeft(Node node) {
+        if (ASSERT) Assert.isNotNull(node);
+        Node child= node.right;
+        if (ASSERT) Assert.isNotNull(child);
+        bool leftChild= node.parent is null || node is node.parent.left;
+
+        // restructure
+        setChild(node.parent, child, leftChild);
+
+        setChild(node, child.left, false);
+        setChild(child, node, true);
+
+        // update relative info
+        // child becomes the new parent, its line and offset counts increase as the former parent
+        // moves under child's left subtree
+        child.line += node.line + 1;
+        child.offset += node.offset + node.length;
+    }
+
+    /**
+     * Right rotation - the given node is rotated down, its left child is rotated up, taking the
+     * previous structural position of <code>node</code>.
+     *
+     * @param node the node to rotate around
+     */
+    private void rotateRight(Node node) {
+        if (ASSERT) Assert.isNotNull(node);
+        Node child= node.left;
+        if (ASSERT) Assert.isNotNull(child);
+        bool leftChild= node.parent is null || node is node.parent.left;
+
+        setChild(node.parent, child, leftChild);
+
+        setChild(node, child.right, true);
+        setChild(child, node, false);
+
+        // update relative info
+        // node loses its left subtree, except for what it keeps in its new subtree
+        // this is exactly the amount in child
+        node.line -= child.line + 1;
+        node.offset -= child.offset + child.length;
+    }
+
+    /**
+     * Helper method for moving a child, ensuring that parent pointers are set correctly.
+     *
+     * @param parent the new parent of <code>child</code>, <code>null</code> to replace the
+     *        root node
+     * @param child the new child of <code>parent</code>, may be <code>null</code>
+     * @param isLeftChild <code>true</code> if <code>child</code> shall become
+     *        <code>parent</code>'s left child, <code>false</code> if it shall become
+     *        <code>parent</code>'s right child
+     */
+    private void setChild(Node parent, Node child, bool isLeftChild) {
+        if (parent is null) {
+            if (child is null)
+                fRoot= new Node(0, NO_DELIM);
+            else
+                fRoot= child;
+        } else {
+            if (isLeftChild)
+                parent.left= child;
+            else
+                parent.right= child;
+        }
+        if (child !is null)
+            child.parent= parent;
+    }
+
+    /**
+     * A left rotation around <code>parent</code>, whose structural position is replaced by
+     * <code>node</code>.
+     *
+     * @param node the node moving up and left
+     * @param parent the node moving left and down
+     */
+    private void singleLeftRotation(Node node, Node parent) {
+        rotateLeft(parent);
+        node.balance= 0;
+        parent.balance= 0;
+    }
+
+    /**
+     * A right rotation around <code>parent</code>, whose structural position is replaced by
+     * <code>node</code>.
+     *
+     * @param node the node moving up and right
+     * @param parent the node moving right and down
+     */
+    private void singleRightRotation(Node node, Node parent) {
+        rotateRight(parent);
+        node.balance= 0;
+        parent.balance= 0;
+    }
+
+    /**
+     * A double left rotation, first rotating right around <code>node</code>, then left around
+     * <code>parent</code>.
+     *
+     * @param node the node that will be rotated right
+     * @param parent the node moving left and down
+     */
+    private void rightLeftRotation(Node node, Node parent) {
+        Node child= node.left;
+        rotateRight(node);
+        rotateLeft(parent);
+        if (child.balance is 1) {
+            node.balance= 0;
+            parent.balance= -1;
+            child.balance= 0;
+        } else if (child.balance is 0) {
+            node.balance= 0;
+            parent.balance= 0;
+        } else if (child.balance is -1) {
+            node.balance= 1;
+            parent.balance= 0;
+            child.balance= 0;
+        }
+    }
+
+    /**
+     * A double right rotation, first rotating left around <code>node</code>, then right around
+     * <code>parent</code>.
+     *
+     * @param node the node that will be rotated left
+     * @param parent the node moving right and down
+     */
+    private void leftRightRotation(Node node, Node parent) {
+        Node child= node.right;
+        rotateLeft(node);
+        rotateRight(parent);
+        if (child.balance is -1) {
+            node.balance= 0;
+            parent.balance= 1;
+            child.balance= 0;
+        } else if (child.balance is 0) {
+            node.balance= 0;
+            parent.balance= 0;
+        } else if (child.balance is 1) {
+            node.balance= -1;
+            parent.balance= 0;
+            child.balance= 0;
+        }
+    }
+
+    /**
+     * Inserts a line with the given length and delimiter after <code>node</code>.
+     *
+     * @param node the predecessor of the inserted node
+     * @param length the line length of the inserted node
+     * @param delimiter the delimiter of the inserted node
+     * @return the inserted node
+     */
+    private Node insertAfter(Node node, int length, String delimiter) {
+        /*
+         * An insertion really shifts the key of all succeeding nodes. Hence we insert the added node
+         * between node and the successor of node. The added node becomes either the right child
+         * of the predecessor node, or the left child of the successor node.
+         */
+        Node added= new Node(length, delimiter);
+
+        if (node.right is null)
+            setChild(node, added, false);
+        else
+            setChild(successorDown(node.right), added, true);
+
+        // parent chain update
+        updateParentChain(added, length, 1);
+        updateParentBalanceAfterInsertion(added);
+
+        return added;
+    }
+
+    /**
+     * Updates the balance information in the parent chain of node until it reaches the root or
+     * finds a node whose balance violates the AVL constraint, which is the re-balanced.
+     *
+     * @param node the child of the first node that needs balance updating
+     */
+    private void updateParentBalanceAfterInsertion(Node node) {
+        Node parent= node.parent;
+        while (parent !is null) {
+            if (node is parent.left)
+                parent.balance--;
+            else
+                parent.balance++;
+
+            switch (parent.balance) {
+                case 1:
+                case -1:
+                    node= parent;
+                    parent= node.parent;
+                    continue;
+                case -2:
+                    rebalanceAfterInsertionLeft(node);
+                    break;
+                case 2:
+                    rebalanceAfterInsertionRight(node);
+                    break;
+                case 0:
+                    break;
+                default:
+                    if (ASSERT)
+                        Assert.isTrue(false);
+            }
+            return;
+        }
+    }
+
+    /**
+     * Re-balances a node whose parent has a double positive balance.
+     *
+     * @param node the node to re-balance
+     */
+    private void rebalanceAfterInsertionRight(Node node) {
+        Node parent= node.parent;
+        if (node.balance is 1) {
+            singleLeftRotation(node, parent);
+        } else if (node.balance is -1) {
+            rightLeftRotation(node, parent);
+        } else if (ASSERT) {
+            Assert.isTrue(false);
+        }
+    }
+
+    /**
+     * Re-balances a node whose parent has a double negative balance.
+     *
+     * @param node the node to re-balance
+     */
+    private void rebalanceAfterInsertionLeft(Node node) {
+        Node parent= node.parent;
+        if (node.balance is -1) {
+            singleRightRotation(node, parent);
+        } else if (node.balance is 1) {
+            leftRightRotation(node, parent);
+        } else if (ASSERT) {
+            Assert.isTrue(false);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#replace(int, int, java.lang.String)
+     */
+    public final void replace(int offset, int length, String text)  {
+        if (ASSERT) checkTree();
+
+        // Inlined nodeByOffset as we need both node and offset
+        int remaining= offset;
+        Node first= fRoot;
+        int firstNodeOffset;
+
+        while (true) {
+            if (first is null)
+                fail(offset);
+
+            if (remaining < first.offset) {
+                first= first.left;
+            } else {
+                remaining -= first.offset;
+                if (remaining < first.length
+                        || remaining is first.length && first.right is null) { // last line
+                    firstNodeOffset= offset - remaining;
+                    break;
+                }
+                remaining -= first.length;
+                first= first.right;
+            }
+        }
+        // Inline nodeByOffset end
+        if (ASSERT) Assert.isTrue(first !is null);
+
+        Node last;
+        if (offset + length < firstNodeOffset + first.length)
+            last= first;
+        else
+            last= nodeByOffset(offset + length);
+        if (ASSERT) Assert.isTrue(last !is null);
+
+        int firstLineDelta= firstNodeOffset + first.length - offset;
+        if (first is last)
+            replaceInternal(first, text, length, firstLineDelta);
+        else
+            replaceFromTo(first, last, text, length, firstLineDelta);
+
+        if (ASSERT) checkTree();
+    }
+
+    /**
+     * Replace happening inside a single line.
+     *
+     * @param node the affected node
+     * @param text the added text
+     * @param length the replace length, &lt; <code>firstLineDelta</code>
+     * @param firstLineDelta the number of characters from the replacement offset to the end of
+     *        <code>node</code> &gt; <code>length</code>
+     */
+    private void replaceInternal(Node node, String text, int length, int firstLineDelta) {
+        // 1) modification on a single line
+
+        AbstractLineTracker_DelimiterInfo info= text is null ? null : nextDelimiterInfo(text, 0);
+
+        if (info is null || info.delimiter is null) {
+            // a) trivial case: insert into a single node, no line mangling
+            int added= text is null ? 0 : text.length;
+            updateLength(node, added - length);
+        } else {
+            // b) more lines to add between two chunks of the first node
+            // remember what we split off the first line
+            int remainder= firstLineDelta - length;
+            String remDelim= node.delimiter;
+
+            // join the first line with the first added
+            int consumed= info.delimiterIndex + info.delimiterLength;
+            int delta= consumed - firstLineDelta;
+            updateLength(node, delta);
+            node.delimiter= info.delimiter;
+
+            // Inline addlines start
+            info= nextDelimiterInfo(text, consumed);
+            while (info !is null) {
+                int lineLen= info.delimiterIndex - consumed + info.delimiterLength;
+                node= insertAfter(node, lineLen, info.delimiter);
+                consumed += lineLen;
+                info= nextDelimiterInfo(text, consumed);
+            }
+            // Inline addlines end
+
+            // add remaining chunk merged with last (incomplete) additional line
+            insertAfter(node, remainder + text.length - consumed, remDelim);
+        }
+    }
+
+    /**
+     * Replace spanning from one node to another.
+     *
+     * @param node the first affected node
+     * @param last the last affected node
+     * @param text the added text
+     * @param length the replace length, &gt;= <code>firstLineDelta</code>
+     * @param firstLineDelta the number of characters removed from the replacement offset to the end
+     *        of <code>node</code>, &lt;= <code>length</code>
+     */
+    private void replaceFromTo(Node node, Node last, String text, int length, int firstLineDelta) {
+        // 2) modification covers several lines
+
+        // delete intermediate nodes
+        // TODO could be further optimized: replace intermediate lines with intermediate added lines
+        // to reduce re-balancing
+        Node successor_= successor(node);
+        while (successor_ !is last) {
+            length -= successor_.length;
+            Node toDelete= successor_;
+            successor_= successor(successor_);
+            updateLength(toDelete, -toDelete.length);
+        }
+
+        AbstractLineTracker_DelimiterInfo info= text is null ? null : nextDelimiterInfo(text, 0);
+
+        if (info is null || info.delimiter is null) {
+            int added= text is null ? 0 : text.length;
+
+            // join the two lines if there are no lines added
+            join(node, last, added - length);
+
+        } else {
+
+            // join the first line with the first added
+            int consumed= info.delimiterIndex + info.delimiterLength;
+            updateLength(node, consumed - firstLineDelta);
+            node.delimiter= info.delimiter;
+            length -= firstLineDelta;
+
+            // Inline addLines start
+            info= nextDelimiterInfo(text, consumed);
+            while (info !is null) {
+                int lineLen= info.delimiterIndex - consumed + info.delimiterLength;
+                node= insertAfter(node, lineLen, info.delimiter);
+                consumed += lineLen;
+                info= nextDelimiterInfo(text, consumed);
+            }
+            // Inline addLines end
+
+            updateLength(last, text.length - consumed - length);
+        }
+    }
+
+    /**
+     * Joins two consecutive node lines, additionally adjusting the resulting length of the combined
+     * line by <code>delta</code>. The first node gets deleted.
+     *
+     * @param one the first node to join
+     * @param two the second node to join
+     * @param delta the delta to apply to the remaining single node
+     */
+    private void join(Node one, Node two, int delta) {
+        int oneLength= one.length;
+        updateLength(one, -oneLength);
+        updateLength(two, oneLength + delta);
+    }
+
+    /**
+     * Adjusts the length of a node by <code>delta</code>, also adjusting the parent chain of
+     * <code>node</code>. If the node's length becomes zero and is not the last (incomplete)
+     * node, it is deleted after the update.
+     *
+     * @param node the node to adjust
+     * @param delta the character delta to add to the node's length
+     */
+    private void updateLength(Node node, int delta) {
+        if (ASSERT) Assert.isTrue(node.length  + delta >= 0);
+
+        // update the node itself
+        node.length += delta;
+
+        // check deletion
+        int lineDelta;
+        bool delete__= node.length is 0 && node.delimiter !is NO_DELIM;
+        if (delete__)
+            lineDelta= -1;
+        else
+            lineDelta= 0;
+
+        // update parent chain
+        if (delta !is 0 || lineDelta !is 0)
+            updateParentChain(node, delta, lineDelta);
+
+        if (delete__)
+            delete_(node);
+    }
+
+    /**
+     * Updates the differential indices following the parent chain. All nodes from
+     * <code>from.parent</code> to the root are updated.
+     *
+     * @param node the child of the first node to update
+     * @param deltaLength the character delta
+     * @param deltaLines the line delta
+     */
+    private void updateParentChain(Node node, int deltaLength, int deltaLines) {
+        updateParentChain(node, null, deltaLength, deltaLines);
+    }
+
+    /**
+     * Updates the differential indices following the parent chain. All nodes from
+     * <code>from.parent</code> to <code>to</code> (exclusive) are updated.
+     *
+     * @param from the child of the first node to update
+     * @param to the first node not to update
+     * @param deltaLength the character delta
+     * @param deltaLines the line delta
+     */
+    private void updateParentChain(Node from, Node to, int deltaLength, int deltaLines) {
+        Node parent= from.parent;
+        while (parent !is to) {
+            // only update node if update comes from left subtree
+            if (from is parent.left) {
+                parent.offset += deltaLength;
+                parent.line += deltaLines;
+            }
+            from= parent;
+            parent= from.parent;
+        }
+    }
+
+    /**
+     * Deletes a node from the tree, re-balancing it if necessary. The differential indices in the
+     * node's parent chain have to be updated in advance to calling this method. Generally, don't
+     * call <code>delete</code> directly, but call
+     * {@link #updateLength(Node, int) update_length(node, -node.length)} to properly remove a
+     * node.
+     *
+     * @param node the node to delete.
+     */
+    private void delete_(Node node) {
+        if (ASSERT) Assert.isTrue(node !is null);
+        if (ASSERT) Assert.isTrue(node.length is 0);
+
+        Node parent= node.parent;
+        Node toUpdate; // the parent of the node that lost a child
+        bool lostLeftChild;
+        bool isLeftChild= parent is null || node is parent.left;
+
+        if (node.left is null || node.right is null) {
+            // 1) node has one child at max - replace parent's pointer with the only child
+            // also handles the trivial case of no children
+            Node replacement= node.left is null ? node.right : node.left;
+            setChild(parent, replacement, isLeftChild);
+            toUpdate= parent;
+            lostLeftChild= isLeftChild;
+            // no updates to do - subtrees stay as they are
+        } else if (node.right.left is null) {
+            // 2a) node's right child has no left child - replace node with right child, giving node's
+            // left subtree to the right child
+            Node replacement= node.right;
+            setChild(parent, replacement, isLeftChild);
+            setChild(replacement, node.left, true);
+            replacement.line= node.line;
+            replacement.offset= node.offset;
+            replacement.balance= node.balance;
+            toUpdate= replacement;
+            lostLeftChild= false;
+//      } else if (node.left.right is null) {
+//          // 2b) symmetric case
+//          Node replacement= node.left;
+//          set_child(parent, replacement, isLeftChild);
+//          set_child(replacement, node.right, false);
+//          replacement.balance= node.balance;
+//          toUpdate= replacement;
+//          lostLeftChild= true;
+        } else {
+            // 3) hard case - replace node with its successor
+            Node successor_= successor(node);
+
+            // successor exists (otherwise node would not have right child, case 1)
+            if (ASSERT) Assert.isNotNull(successor_);
+            // successor has no left child (a left child would be the real successor of node)
+            if (ASSERT) Assert.isTrue(successor_.left is null);
+            if (ASSERT) Assert.isTrue(successor_.line is 0);
+            // successor is the left child of its parent (otherwise parent would be smaller and
+            // hence the real successor)
+            if (ASSERT) Assert.isTrue(successor_ is successor_.parent.left);
+            // successor is not a child of node (would have been covered by 2a)
+            if (ASSERT) Assert.isTrue(successor_.parent !is node);
+
+            toUpdate= successor_.parent;
+            lostLeftChild= true;
+
+            // update relative indices
+            updateParentChain(successor_, node, -successor_.length, -1);
+
+            // delete successor from its current place - like 1)
+            setChild(toUpdate, successor_.right, true);
+
+            // move node's subtrees to its successor
+            setChild(successor_, node.right, false);
+            setChild(successor_, node.left, true);
+
+            // replace node by successor in its parent
+            setChild(parent, successor_, isLeftChild);
+
+            // update the successor
+            successor_.line= node.line;
+            successor_.offset= node.offset;
+            successor_.balance= node.balance;
+        }
+
+        updateParentBalanceAfterDeletion(toUpdate, lostLeftChild);
+    }
+
+    /**
+     * Updates the balance information in the parent chain of node.
+     *
+     * @param node the first node that needs balance updating
+     * @param wasLeftChild <code>true</code> if the deletion happened on <code>node</code>'s
+     *        left subtree, <code>false</code> if it occurred on <code>node</code>'s right
+     *        subtree
+     */
+    private void updateParentBalanceAfterDeletion(Node node, bool wasLeftChild) {
+        while (node !is null) {
+            if (wasLeftChild)
+                node.balance++;
+            else
+                node.balance--;
+
+            Node parent= node.parent;
+            if (parent !is null)
+                wasLeftChild= node is parent.left;
+
+            switch (node.balance) {
+                case 1:
+                case -1:
+                    return; // done, no tree change
+                case -2:
+                    if (rebalanceAfterDeletionRight(node.left))
+                        return;
+                    break; // propagate up
+                case 2:
+                    if (rebalanceAfterDeletionLeft(node.right))
+                        return;
+                    break; // propagate up
+                case 0:
+                    break; // propagate up
+                default:
+                    if (ASSERT)
+                        Assert.isTrue(false);
+            }
+
+            node= parent;
+        }
+    }
+
+    /**
+     * Re-balances a node whose parent has a double positive balance.
+     *
+     * @param node the node to re-balance
+     * @return <code>true</code> if the re-balancement leaves the height at
+     *         <code>node.parent</code> constant, <code>false</code> if the height changed
+     */
+    private bool rebalanceAfterDeletionLeft(Node node) {
+        Node parent= node.parent;
+        if (node.balance is 1) {
+            singleLeftRotation(node, parent);
+            return false;
+        } else if (node.balance is -1) {
+            rightLeftRotation(node, parent);
+            return false;
+        } else if (node.balance is 0) {
+            rotateLeft(parent);
+            node.balance= -1;
+            parent.balance= 1;
+            return true;
+        } else {
+            if (ASSERT) Assert.isTrue(false);
+            return true;
+        }
+    }
+
+    /**
+     * Re-balances a node whose parent has a double negative balance.
+     *
+     * @param node the node to re-balance
+     * @return <code>true</code> if the re-balancement leaves the height at
+     *         <code>node.parent</code> constant, <code>false</code> if the height changed
+     */
+    private bool rebalanceAfterDeletionRight(Node node) {
+        Node parent= node.parent;
+        if (node.balance is -1) {
+            singleRightRotation(node, parent);
+            return false;
+        } else if (node.balance is 1) {
+            leftRightRotation(node, parent);
+            return false;
+        } else if (node.balance is 0) {
+            rotateRight(parent);
+            node.balance= 1;
+            parent.balance= -1;
+            return true;
+        } else {
+            if (ASSERT) Assert.isTrue(false);
+            return true;
+        }
+    }
+
+    /**
+     * Returns the successor of a node, <code>null</code> if node is the last node.
+     *
+     * @param node a node
+     * @return the successor of <code>node</code>, <code>null</code> if there is none
+     */
+    private Node successor(Node node) {
+        if (node.right !is null)
+            return successorDown(node.right);
+
+        return successorUp(node);
+    }
+
+    /**
+     * Searches the successor of <code>node</code> in its parent chain.
+     *
+     * @param node a node
+     * @return the first node in <code>node</code>'s parent chain that is reached from its left
+     *         subtree, <code>null</code> if there is none
+     */
+    private Node successorUp(Node node) {
+        Node child= node;
+        Node parent= child.parent;
+        while (parent !is null) {
+            if (child is parent.left)
+                return parent;
+            child= parent;
+            parent= child.parent;
+        }
+        if (ASSERT) Assert.isTrue(node.delimiter is NO_DELIM);
+        return null;
+    }
+
+    /**
+     * Searches the left-most node in a given subtree.
+     *
+     * @param node a node
+     * @return the left-most node in the given subtree
+     */
+    private Node successorDown(Node node) {
+        Node child= node.left;
+        while (child !is null) {
+            node= child;
+            child= node.left;
+        }
+        return node;
+    }
+
+    /* miscellaneous */
+
+    /**
+     * Throws an exception.
+     *
+     * @param offset the illegal character or line offset that caused the exception
+     * @throws BadLocationException always
+     */
+    private void fail(int offset)  {
+        throw new BadLocationException();
+    }
+
+    /**
+     * Returns the information about the first delimiter found in the given
+     * text starting at the given offset.
+     *
+     * @param text the text to be searched
+     * @param offset the offset in the given text
+     * @return the information of the first found delimiter or <code>null</code>
+     */
+    protected abstract AbstractLineTracker_DelimiterInfo nextDelimiterInfo(String text, int offset);
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineDelimiter(int)
+     */
+    public final String getLineDelimiter(int line)  {
+        Node node= nodeByLine(line);
+        return node.delimiter is NO_DELIM ? null : node.delimiter;
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#computeNumberOfLines(java.lang.String)
+     */
+    public final int computeNumberOfLines(String text) {
+        int count= 0;
+        int start= 0;
+        AbstractLineTracker_DelimiterInfo delimiterInfo= nextDelimiterInfo(text, start);
+        while (delimiterInfo !is null && delimiterInfo.delimiterIndex > -1) {
+            ++count;
+            start= delimiterInfo.delimiterIndex + delimiterInfo.delimiterLength;
+            delimiterInfo= nextDelimiterInfo(text, start);
+        }
+        return count;
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getNumberOfLines()
+     */
+    public final int getNumberOfLines() {
+        // TODO track separately?
+        Node node= fRoot;
+        int lines= 0;
+        while (node !is null) {
+            lines += node.line + 1;
+            node= node.right;
+        }
+        return lines;
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getNumberOfLines(int, int)
+     */
+    public final int getNumberOfLines(int offset, int length)  {
+        if (length is 0)
+            return 1;
+
+        int startLine= lineByOffset(offset);
+        int endLine= lineByOffset(offset + length);
+
+        return endLine - startLine + 1;
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineOffset(int)
+     */
+    public final int getLineOffset(int line)  {
+        return offsetByLine(line);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineLength(int)
+     */
+    public final int getLineLength(int line)  {
+        Node node= nodeByLine(line);
+        return node.length;
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineNumberOfOffset(int)
+     */
+    public final int getLineNumberOfOffset(int offset)  {
+        return lineByOffset(offset);
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineInformationOfOffset(int)
+     */
+    public final IRegion getLineInformationOfOffset(int offset)  {
+        // Inline nodeByOffset start as we need both node and offset
+        int remaining= offset;
+        Node node= fRoot;
+        int lineOffset;
+
+        while (true) {
+            if (node is null)
+                fail(offset);
+
+            if (remaining < node.offset) {
+                node= node.left;
+            } else {
+                remaining -= node.offset;
+                if (remaining < node.length
+                        || remaining is node.length && node.right is null) { // last line
+                    lineOffset= offset - remaining;
+                    break;
+                }
+                remaining -= node.length;
+                node= node.right;
+            }
+        }
+        // Inline nodeByOffset end
+        return new Region(lineOffset, node.pureLength());
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#getLineInformation(int)
+     */
+    public final IRegion getLineInformation(int line)  {
+        try {
+            // Inline nodeByLine start
+            int remaining= line;
+            int offset= 0;
+            Node node= fRoot;
+
+            while (true) {
+                if (node is null)
+                    fail(line);
+
+                if (remaining is node.line) {
+                    offset += node.offset;
+                    break;
+                }
+                if (remaining < node.line) {
+                    node= node.left;
+                } else {
+                    remaining -= node.line + 1;
+                    offset += node.offset + node.length;
+                    node= node.right;
+                }
+            }
+            // Inline nodeByLine end
+            return new Region(offset, node.pureLength());
+        } catch (BadLocationException x) {
+            /*
+             * FIXME: this really strange behavior is mandated by the previous line tracker
+             * implementation and included here for compatibility. See
+             * LineTrackerTest3#testFunnyLastLineCompatibility().
+             */
+            if (line > 0 && line is getNumberOfLines()) {
+                line= line - 1;
+                // Inline nodeByLine start
+                int remaining= line;
+                int offset= 0;
+                Node node= fRoot;
+
+                while (true) {
+                    if (node is null)
+                        fail(line);
+
+                    if (remaining is node.line) {
+                        offset+= node.offset;
+                        break;
+                    }
+                    if (remaining < node.line) {
+                        node= node.left;
+                    } else {
+                        remaining -= node.line + 1;
+                        offset += node.offset + node.length;
+                        node= node.right;
+                    }
+                }
+                Node last= node;
+                // Inline nodeByLine end
+                if (last.length > 0)
+                    return new Region(offset + last.length, 0);
+            }
+            throw x;
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ILineTracker#set(java.lang.String)
+     */
+    public final void set(String text) {
+        fRoot= new Node(0, NO_DELIM);
+        try {
+            replace(0, 0, text);
+        } catch (BadLocationException x) {
+            throw new AssertException(__FILE__,__LINE__);
+        }
+    }
+
+    /*
+     * @see java.lang.Object#toString()
+     */
+    public override String toString() {
+        int depth= computeDepth(fRoot);
+        int WIDTH= 30;
+        int leaves= cast(int) Math.pow( cast(real)2, cast(uint) depth - 1);
+        int width= WIDTH * leaves;
+        String empty= "."; //$NON-NLS-1$
+
+        List roots= new LinkedList();
+        roots.add(fRoot);
+        StringBuffer buf= new StringBuffer((width + 1) * depth);
+        int nodes= 1;
+        int indents= leaves;
+        char[] space= new char[leaves * WIDTH / 2];
+        Arrays.fill(space, ' ');
+        for(int d= 0; d < depth; d++) {
+            // compute indent
+            indents /= 2;
+            int spaces= Math.max(0, indents * WIDTH - WIDTH / 2);
+            // print nodes
+            for (ListIterator it= roots.listIterator(); it.hasNext();) {
+                // pad before
+                buf.append(space[ 0 .. spaces]);
+
+                Node node= cast(Node) it.next();
+                String box;
+                // replace the node with its children
+                if (node is null) {
+                    it.add(cast(Object)null);
+                    box= empty;
+                } else {
+                    it.set(node.left);
+                    it.add(node.right);
+                    box= node.toString();
+                }
+
+                // draw the node, pad to WIDTH
+                int pad_left= (WIDTH - box.length() + 1) / 2;
+                int pad_right= WIDTH - box.length() - pad_left;
+                buf.append(space[ 0 .. pad_left]);
+                buf.append(box);
+                buf.append(space[ 0 .. pad_right]);
+
+                // pad after
+                buf.append(space[ 0 .. spaces]);
+            }
+
+            buf.append('\n');
+            nodes *= 2;
+        }
+
+        return buf.toString();
+    }
+
+    /**
+     * Recursively computes the depth of the tree. Only used by {@link #toString()}.
+     *
+     * @param root the subtree to compute the depth of, may be <code>null</code>
+     * @return the depth of the given tree, 0 if it is <code>null</code>
+     */
+    private byte computeDepth(Node root) {
+        if (root is null)
+            return 0;
+
+        return cast(byte) (Math.max(computeDepth(root.left), computeDepth(root.right)) + 1);
+    }
+
+    /**
+     * Debug-only method that checks the tree structure and the differential offsets.
+     */
+    private void checkTree() {
+        checkTreeStructure(fRoot);
+
+        try {
+            checkTreeOffsets(nodeByOffset(0), [0, 0], null);
+        } catch (BadLocationException x) {
+            throw new AssertException(__FILE__,__LINE__);
+        }
+    }
+
+    /**
+     * Debug-only method that validates the tree structure below <code>node</code>. I.e. it
+     * checks whether all parent/child pointers are consistent and whether the AVL balance
+     * information is correct.
+     *
+     * @param node the node to validate
+     * @return the depth of the tree under <code>node</code>
+     */
+    private byte checkTreeStructure(Node node) {
+        if (node is null)
+            return 0;
+
+        byte leftDepth= checkTreeStructure(node.left);
+        byte rightDepth= checkTreeStructure(node.right);
+        Assert.isTrue(node.balance is rightDepth - leftDepth);
+        Assert.isTrue(node.left is null || node.left.parent is node);
+        Assert.isTrue(node.right is null || node.right.parent is node);
+
+        return cast(byte) (Math.max(rightDepth, leftDepth) + 1);
+    }
+
+    /**
+     * Debug-only method that checks the differential offsets of the tree, starting at
+     * <code>node</code> and continuing until <code>last</code>.
+     *
+     * @param node the first <code>Node</code> to check, may be <code>null</code>
+     * @param offLen an array of length 2, with <code>offLen[0]</code> the expected offset of
+     *        <code>node</code> and <code>offLen[1]</code> the expected line of
+     *        <code>node</code>
+     * @param last the last <code>Node</code> to check, may be <code>null</code>
+     * @return an <code>int[]</code> of length 2, with the first element being the character
+     *         length of <code>node</code>'s subtree, and the second element the number of lines
+     *         in <code>node</code>'s subtree
+     */
+    private int[] checkTreeOffsets(Node node, int[] offLen, Node last) {
+        if (node is last)
+            return offLen;
+
+        Assert.isTrue(node.offset is offLen[0]);
+        Assert.isTrue(node.line is offLen[1]);
+
+        if (node.right !is null) {
+            int[] result= checkTreeOffsets(successorDown(node.right), new int[2], node);
+            offLen[0] += result[0];
+            offLen[1] += result[1];
+        }
+
+        offLen[0] += node.length;
+        offLen[1]++;
+        return checkTreeOffsets(node.parent, offLen, last);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/TypedPosition.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,224 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.TypedPosition;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Convenience class for positions that have a type, similar to
+ * {@link dwtx.jface.text.ITypedRegion}.
+ * <p>
+ * As {@link dwtx.jface.text.Position},<code>TypedPosition</code> can
+ * not be used as key in hash tables as it overrides <code>equals</code> and
+ * <code>hashCode</code> as it would be a value object.
+ */
+public class TypedPosition : Position {
+
+    /** The type of the region described by this position */
+    private String fType;
+
+    /**
+     * Creates a position along the given specification.
+     *
+     * @param offset the offset of this position
+     * @param length the length of this position
+     * @param type the content type of this position
+     */
+    public this(int offset, int length, String type) {
+        super(offset, length);
+        fType= type;
+    }
+
+    /**
+     * Creates a position based on the typed region.
+     *
+     * @param region the typed region
+     */
+    public this(ITypedRegion region) {
+        super(region.getOffset(), region.getLength());
+        fType= region.getType();
+    }
+
+    /**
+     * Returns the content type of the region.
+     *
+     * @return the content type of the region
+     */
+    public String getType() {
+        return fType;
+    }
+
+    /*
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public override int opEquals(Object o) {
+        if ( cast(TypedPosition)o ) {
+            if (super.opEquals(o)) {
+                TypedPosition p= cast(TypedPosition) o;
+                return (fType is null && p.getType() is null) || fType.equals(p.getType());
+            }
+        }
+        return false;
+    }
+
+     /*
+     * @see java.lang.Object#hashCode()
+     */
+    public override hash_t toHash() {
+        int type= fType is null ? 0 : .toHash(fType);
+        return super.toHash() | type;
+     }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/TypedRegion.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,206 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.TypedRegion;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.WhitespaceCharacterPainter; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Default implementation of {@link dwtx.jface.text.ITypedRegion}. A
+ * <code>TypedRegion</code> is a value object.
+ */
+public class TypedRegion : Region , ITypedRegion {
+
+    /** The region's type */
+    private String fType;
+
+    /**
+     * Creates a typed region based on the given specification.
+     *
+     * @param offset the region's offset
+     * @param length the region's length
+     * @param type the region's type
+     */
+    public this(int offset, int length, String type) {
+        super(offset, length);
+        fType= type;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITypedRegion#getType()
+     */
+    public String getType() {
+        return fType;
+    }
+
+    /*
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public override int opEquals(Object o) {
+        if ( cast(TypedRegion)o ) {
+            TypedRegion r= cast(TypedRegion) o;
+            return super.opEquals(r) && ((fType is null && r.getType() is null) || fType ==/+eq+/r.getType());
+        }
+        return false;
+    }
+
+     /*
+     * @see java.lang.Object#hashCode()
+     */
+    public override hash_t toHash() {
+        int type= fType is null ? 0 : .toHash(fType);
+        return super.toHash() | type;
+     }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/WhitespaceCharacterPainter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,522 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 Wind River Systems, Inc. and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Anton Leherbauer (Wind River Systems) - initial API and implementation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=22712
+ *     Anton Leherbauer (Wind River Systems) - [painting] Long lines take too long to display when "Show Whitespace Characters" is enabled - https://bugs.eclipse.org/bugs/show_bug.cgi?id=196116
+ *     Anton Leherbauer (Wind River Systems) - [painting] Whitespace characters not drawn when scrolling to right slowly - https://bugs.eclipse.org/bugs/show_bug.cgi?id=206633
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.WhitespaceCharacterPainter;
+
+import dwtx.jface.text.IDocumentPartitioningListener; // packageimport
+import dwtx.jface.text.DefaultTextHover; // packageimport
+import dwtx.jface.text.AbstractInformationControl; // packageimport
+import dwtx.jface.text.TextUtilities; // packageimport
+import dwtx.jface.text.IInformationControlCreatorExtension; // packageimport
+import dwtx.jface.text.AbstractInformationControlManager; // packageimport
+import dwtx.jface.text.ITextViewerExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitioner; // packageimport
+import dwtx.jface.text.DefaultIndentLineAutoEditStrategy; // packageimport
+import dwtx.jface.text.ITextSelection; // packageimport
+import dwtx.jface.text.Document; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapterContentProposalProvider; // packageimport
+import dwtx.jface.text.ITextListener; // packageimport
+import dwtx.jface.text.BadPartitioningException; // packageimport
+import dwtx.jface.text.ITextViewerExtension5; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension3; // packageimport
+import dwtx.jface.text.IUndoManager; // packageimport
+import dwtx.jface.text.ITextHoverExtension2; // packageimport
+import dwtx.jface.text.IRepairableDocument; // packageimport
+import dwtx.jface.text.IRewriteTarget; // packageimport
+import dwtx.jface.text.DefaultPositionUpdater; // packageimport
+import dwtx.jface.text.RewriteSessionEditProcessor; // packageimport
+import dwtx.jface.text.TextViewerHoverManager; // packageimport
+import dwtx.jface.text.DocumentRewriteSession; // packageimport
+import dwtx.jface.text.TextViewer; // packageimport
+import dwtx.jface.text.ITextViewerExtension8; // packageimport
+import dwtx.jface.text.RegExMessages; // packageimport
+import dwtx.jface.text.IDelayedInputChangeProvider; // packageimport
+import dwtx.jface.text.ITextOperationTargetExtension; // packageimport
+import dwtx.jface.text.IWidgetTokenOwner; // packageimport
+import dwtx.jface.text.IViewportListener; // packageimport
+import dwtx.jface.text.GapTextStore; // packageimport
+import dwtx.jface.text.MarkSelection; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapterExtension; // packageimport
+import dwtx.jface.text.IInformationControlExtension; // packageimport
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2; // packageimport
+import dwtx.jface.text.DefaultDocumentAdapter; // packageimport
+import dwtx.jface.text.ITextViewerExtension3; // packageimport
+import dwtx.jface.text.IInformationControlCreator; // packageimport
+import dwtx.jface.text.TypedRegion; // packageimport
+import dwtx.jface.text.ISynchronizable; // packageimport
+import dwtx.jface.text.IMarkRegionTarget; // packageimport
+import dwtx.jface.text.TextViewerUndoManager; // packageimport
+import dwtx.jface.text.IRegion; // packageimport
+import dwtx.jface.text.IInformationControlExtension2; // packageimport
+import dwtx.jface.text.IDocumentExtension4; // packageimport
+import dwtx.jface.text.IDocumentExtension2; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension2; // packageimport
+import dwtx.jface.text.Assert; // packageimport
+import dwtx.jface.text.DefaultInformationControl; // packageimport
+import dwtx.jface.text.IWidgetTokenOwnerExtension; // packageimport
+import dwtx.jface.text.DocumentClone; // packageimport
+import dwtx.jface.text.DefaultUndoManager; // packageimport
+import dwtx.jface.text.IFindReplaceTarget; // packageimport
+import dwtx.jface.text.IAutoEditStrategy; // packageimport
+import dwtx.jface.text.ILineTrackerExtension; // packageimport
+import dwtx.jface.text.IUndoManagerExtension; // packageimport
+import dwtx.jface.text.TextSelection; // packageimport
+import dwtx.jface.text.DefaultAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IAutoIndentStrategy; // packageimport
+import dwtx.jface.text.IPainter; // packageimport
+import dwtx.jface.text.IInformationControl; // packageimport
+import dwtx.jface.text.IInformationControlExtension3; // packageimport
+import dwtx.jface.text.ITextViewerExtension6; // packageimport
+import dwtx.jface.text.IInformationControlExtension4; // packageimport
+import dwtx.jface.text.DefaultLineTracker; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension; // packageimport
+import dwtx.jface.text.IRepairableDocumentExtension; // packageimport
+import dwtx.jface.text.ITextHover; // packageimport
+import dwtx.jface.text.FindReplaceDocumentAdapter; // packageimport
+import dwtx.jface.text.ILineTracker; // packageimport
+import dwtx.jface.text.Line; // packageimport
+import dwtx.jface.text.ITextViewerExtension; // packageimport
+import dwtx.jface.text.IDocumentAdapter; // packageimport
+import dwtx.jface.text.TextEvent; // packageimport
+import dwtx.jface.text.BadLocationException; // packageimport
+import dwtx.jface.text.AbstractDocument; // packageimport
+import dwtx.jface.text.AbstractLineTracker; // packageimport
+import dwtx.jface.text.TreeLineTracker; // packageimport
+import dwtx.jface.text.ITextPresentationListener; // packageimport
+import dwtx.jface.text.Region; // packageimport
+import dwtx.jface.text.ITextViewer; // packageimport
+import dwtx.jface.text.IDocumentInformationMapping; // packageimport
+import dwtx.jface.text.MarginPainter; // packageimport
+import dwtx.jface.text.IPaintPositionManager; // packageimport
+import dwtx.jface.text.TextPresentation; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension; // packageimport
+import dwtx.jface.text.ISlaveDocumentManagerExtension; // packageimport
+import dwtx.jface.text.ISelectionValidator; // packageimport
+import dwtx.jface.text.IDocumentExtension; // packageimport
+import dwtx.jface.text.PropagatingFontFieldEditor; // packageimport
+import dwtx.jface.text.ConfigurableLineTracker; // packageimport
+import dwtx.jface.text.SlaveDocumentEvent; // packageimport
+import dwtx.jface.text.IDocumentListener; // packageimport
+import dwtx.jface.text.PaintManager; // packageimport
+import dwtx.jface.text.IFindReplaceTargetExtension3; // packageimport
+import dwtx.jface.text.ITextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.IDocumentExtension3; // packageimport
+import dwtx.jface.text.Position; // packageimport
+import dwtx.jface.text.TextMessages; // packageimport
+import dwtx.jface.text.CopyOnWriteTextStore; // packageimport
+import dwtx.jface.text.IPositionUpdater; // packageimport
+import dwtx.jface.text.DefaultTextDoubleClickStrategy; // packageimport
+import dwtx.jface.text.ListLineTracker; // packageimport
+import dwtx.jface.text.ITextInputListener; // packageimport
+import dwtx.jface.text.BadPositionCategoryException; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeperExtension; // packageimport
+import dwtx.jface.text.IInputChangedListener; // packageimport
+import dwtx.jface.text.ITextOperationTarget; // packageimport
+import dwtx.jface.text.IDocumentInformationMappingExtension2; // packageimport
+import dwtx.jface.text.ITextViewerExtension7; // packageimport
+import dwtx.jface.text.IInformationControlExtension5; // packageimport
+import dwtx.jface.text.IDocumentRewriteSessionListener; // packageimport
+import dwtx.jface.text.JFaceTextUtil; // packageimport
+import dwtx.jface.text.AbstractReusableInformationControlCreator; // packageimport
+import dwtx.jface.text.TabsToSpacesConverter; // packageimport
+import dwtx.jface.text.CursorLinePainter; // packageimport
+import dwtx.jface.text.ITextHoverExtension; // packageimport
+import dwtx.jface.text.IEventConsumer; // packageimport
+import dwtx.jface.text.IDocument; // packageimport
+import dwtx.jface.text.IWidgetTokenKeeper; // packageimport
+import dwtx.jface.text.DocumentCommand; // packageimport
+import dwtx.jface.text.TypedPosition; // packageimport
+import dwtx.jface.text.IEditingSupportRegistry; // packageimport
+import dwtx.jface.text.IDocumentPartitionerExtension; // packageimport
+import dwtx.jface.text.AbstractHoverInformationControlManager; // packageimport
+import dwtx.jface.text.IEditingSupport; // packageimport
+import dwtx.jface.text.IMarkSelection; // packageimport
+import dwtx.jface.text.ISlaveDocumentManager; // packageimport
+import dwtx.jface.text.DocumentEvent; // packageimport
+import dwtx.jface.text.DocumentPartitioningChangedEvent; // packageimport
+import dwtx.jface.text.ITextStore; // packageimport
+import dwtx.jface.text.JFaceTextMessages; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionEvent; // packageimport
+import dwtx.jface.text.SequentialRewriteTextStore; // packageimport
+import dwtx.jface.text.DocumentRewriteSessionType; // packageimport
+import dwtx.jface.text.TextAttribute; // packageimport
+import dwtx.jface.text.ITextViewerExtension4; // packageimport
+import dwtx.jface.text.ITypedRegion; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.custom.StyleRange;
+import dwt.custom.StyledText;
+import dwt.custom.StyledTextContent;
+import dwt.events.PaintEvent;
+import dwt.events.PaintListener;
+import dwt.graphics.Color;
+import dwt.graphics.FontMetrics;
+import dwt.graphics.GC;
+import dwt.graphics.Point;
+
+
+/**
+ * A painter for drawing visible characters for (invisible) whitespace
+ * characters.
+ *
+ * @since 3.3
+ */
+public class WhitespaceCharacterPainter : IPainter, PaintListener {
+
+    private static const char SPACE_SIGN= '\u00b7';
+    private static const char IDEOGRAPHIC_SPACE_SIGN= '\u00b0';
+    private static const char TAB_SIGN= '\u00bb';
+    private static const char CARRIAGE_RETURN_SIGN= '\u00a4';
+    private static const char LINE_FEED_SIGN= '\u00b6';
+
+    /** Indicates whether this painter is active. */
+    private bool fIsActive= false;
+    /** The source viewer this painter is attached to. */
+    private ITextViewer fTextViewer;
+    /** The viewer's widget. */
+    private StyledText fTextWidget;
+    /** Tells whether the advanced graphics sub system is available. */
+    private bool fIsAdvancedGraphicsPresent;
+
+    /**
+     * Creates a new painter for the given text viewer.
+     *
+     * @param textViewer  the text viewer the painter should be attached to
+     */
+    public this(ITextViewer textViewer) {
+//         super();
+        fTextViewer= textViewer;
+        fTextWidget= textViewer.getTextWidget();
+        GC gc= new GC(fTextWidget);
+        gc.setAdvanced(true);
+        fIsAdvancedGraphicsPresent= gc.getAdvanced();
+        gc.dispose();
+    }
+
+    /*
+     * @see dwtx.jface.text.IPainter#dispose()
+     */
+    public void dispose() {
+        fTextViewer= null;
+        fTextWidget= null;
+    }
+
+    /*
+     * @see dwtx.jface.text.IPainter#paint(int)
+     */
+    public void paint(int reason) {
+        IDocument document= fTextViewer.getDocument();
+        if (document is null) {
+            deactivate(false);
+            return;
+        }
+        if (!fIsActive) {
+            fIsActive= true;
+            fTextWidget.addPaintListener(this);
+            redrawAll();
+        } else if (reason is CONFIGURATION || reason is INTERNAL) {
+            redrawAll();
+        } else if (reason is TEXT_CHANGE) {
+            // redraw current line only
+            try {
+                IRegion lineRegion =
+                    document.getLineInformationOfOffset(getDocumentOffset(fTextWidget.getCaretOffset()));
+                int widgetOffset= getWidgetOffset(lineRegion.getOffset());
+                int charCount= fTextWidget.getCharCount();
+                int redrawLength= Math.min(lineRegion.getLength(), charCount - widgetOffset);
+                if (widgetOffset >= 0 && redrawLength > 0) {
+                    fTextWidget.redrawRange(widgetOffset, redrawLength, true);
+                }
+            } catch (BadLocationException e) {
+                // ignore
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IPainter#deactivate(bool)
+     */
+    public void deactivate(bool redraw) {
+        if (fIsActive) {
+            fIsActive= false;
+            fTextWidget.removePaintListener(this);
+            if (redraw) {
+                redrawAll();
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IPainter#setPositionManager(dwtx.jface.text.IPaintPositionManager)
+     */
+    public void setPositionManager(IPaintPositionManager manager) {
+        // no need for a position manager
+    }
+
+    /*
+     * @see dwt.events.PaintListener#paintControl(dwt.events.PaintEvent)
+     */
+    public void paintControl(PaintEvent event) {
+        if (fTextWidget !is null) {
+            handleDrawRequest(event.gc, event.x, event.y, event.width, event.height);
+        }
+    }
+
+    /**
+     * Draw characters in view range.
+     *
+     * @param gc
+     * @param x
+     * @param y
+     * @param w
+     * @param h
+     */
+    private void handleDrawRequest(GC gc, int x, int y, int w, int h) {
+        int startLine= fTextWidget.getLineIndex(y);
+        int endLine= fTextWidget.getLineIndex(y + h - 1);
+        if (startLine <= endLine && startLine < fTextWidget.getLineCount()) {
+            if (fIsAdvancedGraphicsPresent) {
+                int alpha= gc.getAlpha();
+                gc.setAlpha(100);
+                drawLineRange(gc, startLine, endLine, x, w);
+                gc.setAlpha(alpha);
+            } else
+                drawLineRange(gc, startLine, endLine, x, w);
+        }
+    }
+
+    /**
+     * Draw the given line range.
+     *
+     * @param gc
+     * @param startLine  first line number
+     * @param endLine  last line number (inclusive)
+     * @param x  the X-coordinate of the drawing range
+     * @param w  the width of the drawing range
+     */
+    private void drawLineRange(GC gc, int startLine, int endLine, int x, int w) {
+        final int viewPortWidth= fTextWidget.getClientArea().width;
+        for (int line= startLine; line <= endLine; line++) {
+            int lineOffset= fTextWidget.getOffsetAtLine(line);
+            // line end offset including line delimiter
+            int lineEndOffset;
+            if (line < fTextWidget.getLineCount() - 1) {
+                lineEndOffset= fTextWidget.getOffsetAtLine(line + 1);
+            } else {
+                lineEndOffset= fTextWidget.getCharCount();
+            }
+            // line length excluding line delimiter
+            int lineLength= lineEndOffset - lineOffset;
+            while (lineLength > 0) {
+                char c= fTextWidget.getTextRange(lineOffset + lineLength - 1, 1).charAt(0);
+                if (c !is '\r' && c !is '\n') {
+                    break;
+                }
+                --lineLength;
+            }
+            // compute coordinates of last character on line
+            Point endOfLine= fTextWidget.getLocationAtOffset(lineOffset + lineLength);
+            if (x - endOfLine.x > viewPortWidth) {
+                // line is not visible
+                continue;
+            }
+            // Y-coordinate of line
+            int y= fTextWidget.getLinePixel(line);
+            // compute first visible char offset
+            int startOffset;
+            try {
+                startOffset= fTextWidget.getOffsetAtLocation(new Point(x, y)) - 1;
+                if (startOffset - 2 <= lineOffset) {
+                    startOffset= lineOffset;
+                }
+            } catch (IllegalArgumentException iae) {
+                startOffset= lineOffset;
+            }
+            // compute last visible char offset
+            int endOffset;
+            if (x + w >= endOfLine.x) {
+                // line end is visible
+                endOffset= lineEndOffset;
+            } else {
+                try {
+                    endOffset= fTextWidget.getOffsetAtLocation(new Point(x + w - 1, y)) + 1;
+                    if (endOffset + 2 >= lineEndOffset) {
+                        endOffset= lineEndOffset;
+                    }
+                } catch (IllegalArgumentException iae) {
+                    endOffset= lineEndOffset;
+                }
+            }
+            // draw character range
+            if (endOffset > startOffset) {
+                drawCharRange(gc, startOffset, endOffset);
+            }
+        }
+    }
+
+    /**
+     * Draw characters of content range.
+     *
+     * @param gc the GC
+     * @param startOffset inclusive start index
+     * @param endOffset exclusive end index
+     */
+    private void drawCharRange(GC gc, int startOffset, int endOffset) {
+        StyledTextContent content= fTextWidget.getContent();
+        int length= endOffset - startOffset;
+        String text= content.getTextRange(startOffset, length);
+        StyleRange styleRange= null;
+        Color fg= null;
+        Point selection= fTextWidget.getSelection();
+        StringBuffer visibleChar= new StringBuffer(10);
+        for (int textOffset= 0; textOffset <= length; ++textOffset) {
+            int delta= 0;
+            bool eol= false;
+            if (textOffset < length) {
+                delta= 1;
+                char c= text.charAt(textOffset);
+                switch (c) {
+                case ' ' :
+                    visibleChar.append(SPACE_SIGN);
+                    // 'continue' would improve performance but may produce drawing errors
+                    // for long runs of space if width of space and dot differ
+                    break;
+                case '\u3000' : // ideographic whitespace
+                    visibleChar.append(IDEOGRAPHIC_SPACE_SIGN);
+                    // 'continue' would improve performance but may produce drawing errors
+                    // for long runs of space if width of space and dot differ
+                    break;
+                case '\t' :
+                    visibleChar.append(TAB_SIGN);
+                    break;
+                case '\r' :
+                    visibleChar.append(CARRIAGE_RETURN_SIGN);
+                    if (textOffset >= length - 1 || text.charAt(textOffset + 1) !is '\n') {
+                        eol= true;
+                        break;
+                    }
+                    continue;
+                case '\n' :
+                    visibleChar.append(LINE_FEED_SIGN);
+                    eol= true;
+                    break;
+                default :
+                    delta= 0;
+                    break;
+                }
+            }
+            if (visibleChar.length() > 0) {
+                int widgetOffset= startOffset + textOffset - visibleChar.length() + delta;
+                if (!eol || !isFoldedLine(content.getLineAtOffset(widgetOffset))) {
+                    if (widgetOffset >= selection.x && widgetOffset < selection.y) {
+                        fg= fTextWidget.getSelectionForeground();
+                    } else if (styleRange is null || styleRange.start + styleRange.length <= widgetOffset) {
+                        styleRange= fTextWidget.getStyleRangeAtOffset(widgetOffset);
+                        if (styleRange is null || styleRange.foreground is null) {
+                            fg= fTextWidget.getForeground();
+                        } else {
+                            fg= styleRange.foreground;
+                        }
+                    }
+                    draw(gc, widgetOffset, visibleChar.toString(), fg);
+                }
+                visibleChar.truncate(0);
+            }
+        }
+    }
+
+    /**
+     * Check if the given widget line is a folded line.
+     *
+     * @param widgetLine  the widget line number
+     * @return <code>true</code> if the line is folded
+     */
+    private bool isFoldedLine(int widgetLine) {
+        if ( cast(ITextViewerExtension5)fTextViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5)fTextViewer;
+            int modelLine= extension.widgetLine2ModelLine(widgetLine);
+            int widgetLine2= extension.modelLine2WidgetLine(modelLine + 1);
+            return widgetLine2 is -1;
+        }
+        return false;
+    }
+
+    /**
+     * Redraw all of the text widgets visible content.
+     */
+    private void redrawAll() {
+        fTextWidget.redraw();
+    }
+
+    /**
+     * Draw string at widget offset.
+     *
+     * @param gc
+     * @param offset the widget offset
+     * @param s the string to be drawn
+     * @param fg the foreground color
+     */
+    private void draw(GC gc, int offset, String s, Color fg) {
+        // Compute baseline delta (see https://bugs.eclipse.org/bugs/show_bug.cgi?id=165640)
+        int baseline= fTextWidget.getBaseline(offset);
+        FontMetrics fontMetrics= gc.getFontMetrics();
+        int fontBaseline= fontMetrics.getAscent() + fontMetrics.getLeading();
+        int baslineDelta= baseline - fontBaseline;
+
+        Point pos= fTextWidget.getLocationAtOffset(offset);
+        gc.setForeground(fg);
+        gc.drawString(s, pos.x, pos.y + baslineDelta, true);
+    }
+
+    /**
+     * Convert a document offset to the corresponding widget offset.
+     *
+     * @param documentOffset
+     * @return widget offset
+     */
+    private int getWidgetOffset(int documentOffset) {
+        if ( cast(ITextViewerExtension5)fTextViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5)fTextViewer;
+            return extension.modelOffset2WidgetOffset(documentOffset);
+        }
+        IRegion visible= fTextViewer.getVisibleRegion();
+        int widgetOffset= documentOffset - visible.getOffset();
+        if (widgetOffset > visible.getLength()) {
+            return -1;
+        }
+        return widgetOffset;
+    }
+
+    /**
+     * Convert a widget offset to the corresponding document offset.
+     *
+     * @param widgetOffset
+     * @return document offset
+     */
+    private int getDocumentOffset(int widgetOffset) {
+        if ( cast(ITextViewerExtension5)fTextViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5)fTextViewer;
+            return extension.widgetOffset2ModelOffset(widgetOffset);
+        }
+        IRegion visible= fTextViewer.getVisibleRegion();
+        if (widgetOffset > visible.getLength()) {
+            return -1;
+        }
+        return widgetOffset + visible.getOffset();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/AdditionalInfoController.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,658 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.AdditionalInfoController;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+import dwt.dwthelper.utils;
+import tango.core.Thread;
+
+import dwt.events.SelectionEvent;
+import dwt.events.SelectionListener;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Shell;
+import dwt.widgets.Table;
+import dwt.widgets.TableItem;
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.IProgressMonitor;
+import dwtx.core.runtime.IStatus;
+import dwtx.core.runtime.Status;
+import dwtx.core.runtime.jobs.Job;
+import dwtx.jface.internal.text.InformationControlReplacer;
+import dwtx.jface.text.AbstractInformationControlManager;
+import dwtx.jface.text.AbstractReusableInformationControlCreator;
+import dwtx.jface.text.DefaultInformationControl;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.IInformationControlExtension3;
+
+
+/**
+ * Displays the additional information available for a completion proposal.
+ *
+ * @since 2.0
+ */
+class AdditionalInfoController : AbstractInformationControlManager {
+
+    /**
+     * A timer thread.
+     *
+     * @since 3.2
+     */
+    private static abstract class Timer {
+        private static const int DELAY_UNTIL_JOB_IS_SCHEDULED= 50;
+
+        /**
+         * A <code>Task</code> is {@link Task#run() run} when {@link #delay()} milliseconds have
+         * elapsed after it was scheduled without a {@link #reset(ICompletionProposal) reset}
+         * to occur.
+         */
+        private static abstract class Task : Runnable {
+            /**
+             * @return the delay in milliseconds before this task should be run
+             */
+            public abstract long delay();
+            /**
+             * Runs this task.
+             */
+            public abstract void run();
+            /**
+             * @return the task to be scheduled after this task has been run
+             */
+            public abstract Task nextTask();
+        }
+
+        /**
+         * IDLE: the initial task, and active whenever the info has been shown. It cannot be run,
+         * but specifies an infinite delay.
+         */
+        private Task IDLE;
+        private void IDLE_init(){
+            IDLE = new class() Task {
+                public void run() {
+                    Assert.isTrue(false);
+                }
+
+                public Task nextTask() {
+                    Assert.isTrue(false);
+                    return null;
+                }
+
+                public long delay() {
+                    return Long.MAX_VALUE;
+                }
+
+                public override String toString() {
+                    return "IDLE"; //$NON-NLS-1$
+                }
+            };
+        }
+        /**
+         * FIRST_WAIT: Schedules a platform {@link Job} to fetch additional info from an {@link ICompletionProposalExtension5}.
+         */
+        private Task FIRST_WAIT;
+        private void FIRST_WAIT_init() {
+            FIRST_WAIT = new class() Task {
+                public void run() {
+                    final ICompletionProposalExtension5 proposal= getCurrentProposalEx();
+                    Job job= new class(JFaceTextMessages.getString("AdditionalInfoController.job_name")) Job { //$NON-NLS-1$
+                        this( String txt ){
+                            super( txt );
+                        }
+                        protected IStatus run(IProgressMonitor monitor) {
+                            Object info;
+                            try {
+                                info= proposal.getAdditionalProposalInfo(monitor);
+                            } catch (RuntimeException x) {
+                                /*
+                                * XXX: This is the safest fix at this point so close to end of 3.2.
+                                *      Will be revisited when fixing https://bugs.eclipse.org/bugs/show_bug.cgi?id=101033
+                                */
+                                return new Status(IStatus.WARNING, "dwtx.jface.text", IStatus.OK, "", x); //$NON-NLS-1$ //$NON-NLS-2$
+                            }
+                            setInfo(cast(ICompletionProposal) proposal, info);
+                            return new Status(IStatus.OK, "dwtx.jface.text", IStatus.OK, "", null); //$NON-NLS-1$ //$NON-NLS-2$
+                        }
+                    };
+                    job.schedule();
+                }
+
+                public Task nextTask() {
+                    return SECOND_WAIT;
+                }
+
+                public long delay() {
+                    return DELAY_UNTIL_JOB_IS_SCHEDULED;
+                }
+
+                public override String toString() {
+                    return "FIRST_WAIT"; //$NON-NLS-1$
+                }
+            };
+        }
+        /**
+         * SECOND_WAIT: Allows display of additional info obtained from an
+         * {@link ICompletionProposalExtension5}.
+         */
+        private Task SECOND_WAIT;
+        private void SECOND_WAIT_init() {
+            SECOND_WAIT = new class() Task {
+                public void run() {
+                    // show the info
+                    allowShowing();
+                }
+
+                public Task nextTask() {
+                    return IDLE;
+                }
+
+                public long delay() {
+                    return fDelay - DELAY_UNTIL_JOB_IS_SCHEDULED;
+                }
+
+                public override String toString() {
+                    return "SECOND_WAIT"; //$NON-NLS-1$
+                }
+            };
+        }
+        /**
+         * LEGACY_WAIT: Posts a runnable into the display thread to fetch additional info from non-{@link ICompletionProposalExtension5}s.
+         */
+        private Task LEGACY_WAIT;
+        private void LEGACY_WAIT_init() {
+            LEGACY_WAIT = new class()  Task {
+                public void run() {
+                    final ICompletionProposal proposal= getCurrentProposal();
+                    if (!fDisplay.isDisposed()) {
+                        fDisplay.asyncExec(new class()  Runnable {
+                            public void run() {
+                                synchronized (this.outer) {
+                                    if (proposal is getCurrentProposal()) {
+                                        Object info= stringcast(proposal.getAdditionalProposalInfo());
+                                        showInformation(proposal, info);
+                                    }
+                                }
+                            }
+                        });
+                    }
+                }
+
+                public Task nextTask() {
+                    return IDLE;
+                }
+
+                public long delay() {
+                    return fDelay;
+                }
+
+                public override String toString() {
+                    return "LEGACY_WAIT"; //$NON-NLS-1$
+                }
+            };
+        }
+        /**
+         * EXIT: The task that triggers termination of the timer thread.
+         */
+        private Task EXIT;
+        private void EXIT_init() {
+            EXIT = new class()  Task {
+                public long delay() {
+                    return 1;
+                }
+
+                public Task nextTask() {
+                    Assert.isTrue(false);
+                    return EXIT;
+                }
+
+                public void run() {
+                    Assert.isTrue(false);
+                }
+
+                public override String toString() {
+                    return "EXIT"; //$NON-NLS-1$
+                }
+            };
+        }
+
+        /** The timer thread. */
+        private const Thread fThread;
+
+        /** The currently waiting / active task. */
+        private Task fTask;
+        /** The next wake up time. */
+        private long fNextWakeup;
+
+        private ICompletionProposal fCurrentProposal= null;
+        private Object fCurrentInfo= null;
+        private bool fAllowShowing= false;
+
+        private const Display fDisplay;
+        private const int fDelay;
+
+        /**
+         * Creates a new timer.
+         *
+         * @param display the display to use for display thread posting.
+         * @param delay the delay until to show additional info
+         */
+        public this(Display display, int delay) {
+            // DWT instance init
+            IDLE_init();
+            FIRST_WAIT_init();
+            SECOND_WAIT_init();
+            LEGACY_WAIT_init();
+            EXIT_init();
+
+            fDisplay= display;
+            fDelay= delay;
+            long current= System.currentTimeMillis();
+            schedule(IDLE, current);
+
+            void threadrun() {
+                try {
+                    loop();
+                } catch (InterruptedException x) {
+                }
+            }
+            fThread= new Thread( &threadrun );
+            fThread.name = JFaceTextMessages.getString("InfoPopup.info_delay_timer_name"); //$NON-NLS-1$
+            fThread.start();
+        }
+
+        /**
+         * Terminates the timer thread.
+         */
+        public synchronized final void terminate() {
+            schedule(EXIT, System.currentTimeMillis());
+            notifyAll();
+        }
+
+        /**
+         * Resets the timer thread as the selection has changed to a new proposal.
+         *
+         * @param p the new proposal
+         */
+        public final synchronized void reset(ICompletionProposal p) {
+            if (fCurrentProposal !is p) {
+                fCurrentProposal= p;
+                fCurrentInfo= null;
+                fAllowShowing= false;
+
+                long oldWakeup= fNextWakeup;
+                Task task= taskOnReset(p);
+                schedule(task, System.currentTimeMillis());
+                if (fNextWakeup < oldWakeup)
+                    notifyAll();
+            }
+        }
+
+        private Task taskOnReset(ICompletionProposal p) {
+            if (p is null)
+                return IDLE;
+            if (isExt5(p))
+                return FIRST_WAIT;
+            return LEGACY_WAIT;
+        }
+
+        private synchronized void loop()  {
+            long current= System.currentTimeMillis();
+            Task task= currentTask();
+
+            while (task !is EXIT) {
+                long delay= fNextWakeup - current;
+                if (delay <= 0) {
+                    task.run();
+                    task= task.nextTask();
+                    schedule(task, current);
+                } else {
+                    wait(delay);
+                    current= System.currentTimeMillis();
+                    task= currentTask();
+                }
+            }
+        }
+
+        private Task currentTask() {
+            return fTask;
+        }
+
+        private void schedule(Task task, long current) {
+            fTask= task;
+            long nextWakeup= current + task.delay();
+            if (nextWakeup <= current)
+                fNextWakeup= Long.MAX_VALUE;
+            else
+                fNextWakeup= nextWakeup;
+        }
+
+        private bool isExt5(ICompletionProposal p) {
+            return cast(ICompletionProposalExtension5)p;
+        }
+
+        ICompletionProposal getCurrentProposal() {
+            return fCurrentProposal;
+        }
+
+        ICompletionProposalExtension5 getCurrentProposalEx() {
+            Assert.isTrue( cast(ICompletionProposalExtension5)fCurrentProposal );
+            return cast(ICompletionProposalExtension5) fCurrentProposal;
+        }
+
+        synchronized void setInfo(ICompletionProposal proposal, Object info) {
+            if (proposal is fCurrentProposal) {
+                fCurrentInfo= info;
+                if (fAllowShowing) {
+                    triggerShowing();
+                }
+            }
+        }
+
+        private void triggerShowing() {
+            final Object info= fCurrentInfo;
+            if (!fDisplay.isDisposed()) {
+                fDisplay.asyncExec(new class()  Runnable {
+                    public void run() {
+                        synchronized (this.outer) {
+                            if (info is fCurrentInfo) {
+                                showInformation(fCurrentProposal, info);
+                            }
+                        }
+                    }
+                });
+            }
+        }
+
+        /**
+         * Called in the display thread to show additional info.
+         *
+         * @param proposal the proposal to show information about
+         * @param info the information about <code>proposal</code>
+         */
+        protected abstract void showInformation(ICompletionProposal proposal, Object info);
+
+        void allowShowing() {
+            fAllowShowing= true;
+            triggerShowing();
+        }
+    }
+    /**
+     * Internal table selection listener.
+     */
+    private class TableSelectionListener : SelectionListener {
+
+        /*
+         * @see SelectionListener#widgetSelected(SelectionEvent)
+         */
+        public void widgetSelected(SelectionEvent e) {
+            handleTableSelectionChanged();
+        }
+
+        /*
+         * @see SelectionListener#widgetDefaultSelected(SelectionEvent)
+         */
+        public void widgetDefaultSelected(SelectionEvent e) {
+        }
+    }
+
+    /**
+     * Default control creator for the information control replacer.
+     * @since 3.4
+     */
+    private static class DefaultPresenterControlCreator : AbstractReusableInformationControlCreator {
+        public IInformationControl doCreateInformationControl(Shell shell) {
+            return new DefaultInformationControl(shell, true);
+        }
+    }
+
+    /** The proposal table. */
+    private Table fProposalTable;
+    /** The table selection listener */
+    private SelectionListener fSelectionListener;
+    /** The delay after which additional information is displayed */
+    private const int fDelay;
+    /**
+     * The timer thread.
+     * @since 3.2
+     */
+    private Timer fTimer;
+    /**
+     * The proposal most recently set by {@link #showInformation(ICompletionProposal, Object)},
+     * possibly <code>null</code>.
+     * @since 3.2
+     */
+    private ICompletionProposal fProposal;
+    /**
+     * The information most recently set by {@link #showInformation(ICompletionProposal, Object)},
+     * possibly <code>null</code>.
+     * @since 3.2
+     */
+    private Object fInformation;
+
+    /**
+     * Creates a new additional information controller.
+     *
+     * @param creator the information control creator to be used by this controller
+     * @param delay time in milliseconds after which additional info should be displayed
+     */
+    this(IInformationControlCreator creator, int delay) {
+
+        fSelectionListener= new TableSelectionListener();
+
+        super(creator);
+        fDelay= delay;
+        setAnchor(ANCHOR_RIGHT);
+        setFallbackAnchors([ ANCHOR_RIGHT, ANCHOR_LEFT, ANCHOR_BOTTOM ]);
+
+        /*
+         * Adjust the location by one pixel towards the proposal popup, so that the single pixel
+         * border of the additional info popup overlays with the border of the popup. This avoids
+         * having a double black line.
+         */
+        int spacing= -1;
+        setMargins(spacing, spacing); // see also adjustment in #computeLocation
+
+        InformationControlReplacer replacer= new InformationControlReplacer(new DefaultPresenterControlCreator());
+        getInternalAccessor().setInformationControlReplacer(replacer);
+    }
+
+    /*
+     * @see AbstractInformationControlManager#install(Control)
+     */
+    public void install(Control control) {
+
+        if (fProposalTable is control) {
+            // already installed
+            return;
+        }
+
+        super.install(control.getShell());
+
+        Assert.isTrue( cast(Table)control );
+        fProposalTable= cast(Table) control;
+        fProposalTable.addSelectionListener(fSelectionListener);
+        getInternalAccessor().getInformationControlReplacer().install(fProposalTable);
+
+        fTimer= new class(fProposalTable.getDisplay(), fDelay)  Timer {
+            protected void showInformation(ICompletionProposal proposal, Object info) {
+                InformationControlReplacer replacer= getInternalAccessor().getInformationControlReplacer();
+                if (replacer !is null)
+                    replacer.hideInformationControl();
+                this.outer.showInformation(proposal, info);
+            }
+        };
+    }
+
+    /*
+     * @see AbstractInformationControlManager#disposeInformationControl()
+     */
+    public void disposeInformationControl() {
+
+        if (fTimer !is null) {
+            fTimer.terminate();
+            fTimer= null;
+        }
+
+        fProposal= null;
+        fInformation= null;
+
+        if (fProposalTable !is null && !fProposalTable.isDisposed()) {
+            fProposalTable.removeSelectionListener(fSelectionListener);
+            fProposalTable= null;
+        }
+
+        super.disposeInformationControl();
+    }
+
+    /**
+     *Handles a change of the line selected in the associated selector.
+     */
+    public void handleTableSelectionChanged() {
+
+        if (fProposalTable !is null && !fProposalTable.isDisposed() && fProposalTable.isVisible()) {
+            TableItem[] selection= fProposalTable.getSelection();
+            if (selection !is null && selection.length > 0) {
+
+                TableItem item= selection[0];
+
+                Object d= item.getData();
+                if ( cast(ICompletionProposal)d ) {
+                    ICompletionProposal p= cast(ICompletionProposal) d;
+                    fTimer.reset(p);
+                }
+            }
+        }
+    }
+
+    void showInformation(ICompletionProposal proposal, Object info) {
+        if (fProposalTable is null || fProposalTable.isDisposed())
+            return;
+
+        if (fProposal is proposal && ((info is null && fInformation is null) || (info !is null && info.equals(fInformation))))
+            return;
+
+        fInformation= info;
+        fProposal= proposal;
+        showInformation();
+    }
+
+    /*
+     * @see AbstractInformationControlManager#computeInformation()
+     */
+    protected void computeInformation() {
+        if ( cast(ICompletionProposalExtension3)fProposal )
+            setCustomInformationControlCreator((cast(ICompletionProposalExtension3) fProposal).getInformationControlCreator());
+        else
+            setCustomInformationControlCreator(null);
+
+        // compute subject area
+        Point size= fProposalTable.getShell().getSize();
+
+        // set information & subject area
+        setInformation(fInformation, new Rectangle(0, 0, size.x, size.y));
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#computeLocation(dwt.graphics.Rectangle, dwt.graphics.Point, dwtx.jface.text.AbstractInformationControlManager.Anchor)
+     */
+    protected Point computeLocation(Rectangle subjectArea, Point controlSize, Anchor anchor) {
+        Point location= super.computeLocation(subjectArea, controlSize, anchor);
+
+        /*
+         * The location is computed using subjectControl.toDisplay(), which does not include the
+         * trim of the subject control. As we want the additional info popup aligned with the outer
+         * coordinates of the proposal popup, adjust this here
+         */
+        Rectangle trim= fProposalTable.getShell().computeTrim(0, 0, 0, 0);
+        location.x += trim.x;
+        location.y += trim.y;
+
+        return location;
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#computeSizeConstraints(Control, IInformationControl)
+     */
+    protected Point computeSizeConstraints(Control subjectControl, IInformationControl informationControl) {
+        // at least as big as the proposal table
+        Point sizeConstraint= super.computeSizeConstraints(subjectControl, informationControl);
+        Point size= subjectControl.getShell().getSize();
+
+        // AbstractInformationControlManager#internalShowInformationControl(Rectangle, Object) adds trims
+        // to the computed constraints. Need to remove them here, to make the outer bounds of the additional
+        // info shell fit the bounds of the proposal shell:
+        if ( cast(IInformationControlExtension3)fInformationControl ) {
+            Rectangle shellTrim= (cast(IInformationControlExtension3) fInformationControl).computeTrim();
+            size.x -= shellTrim.width;
+            size.y -= shellTrim.height;
+        }
+
+        if (sizeConstraint.x < size.x)
+            sizeConstraint.x= size.x;
+        if (sizeConstraint.y < size.y)
+            sizeConstraint.y= size.y;
+        return sizeConstraint;
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl()
+     */
+    protected void hideInformationControl() {
+        super.hideInformationControl();
+    }
+    package void hideInformationControl_package() {
+        this.hideInformationControl();
+    }
+
+    /**
+     * @return the current information control, or <code>null</code> if none available
+     */
+    public IInformationControl getCurrentInformationControl2() {
+        return getInternalAccessor().getCurrentInformationControl();
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/CompletionProposal.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.CompletionProposal;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+import dwt.graphics.Image;
+import dwt.graphics.Point;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+
+
+/**
+ * The standard implementation of the <code>ICompletionProposal</code> interface.
+ */
+public final class CompletionProposal : ICompletionProposal {
+
+    /** The string to be displayed in the completion proposal popup. */
+    private String fDisplayString;
+    /** The replacement string. */
+    private String fReplacementString;
+    /** The replacement offset. */
+    private int fReplacementOffset;
+    /** The replacement length. */
+    private int fReplacementLength;
+    /** The cursor position after this proposal has been applied. */
+    private int fCursorPosition;
+    /** The image to be displayed in the completion proposal popup. */
+    private Image fImage;
+    /** The context information of this proposal. */
+    private IContextInformation fContextInformation;
+    /** The additional info of this proposal. */
+    private String fAdditionalProposalInfo;
+
+    /**
+     * Creates a new completion proposal based on the provided information. The replacement string is
+     * considered being the display string too. All remaining fields are set to <code>null</code>.
+     *
+     * @param replacementString the actual string to be inserted into the document
+     * @param replacementOffset the offset of the text to be replaced
+     * @param replacementLength the length of the text to be replaced
+     * @param cursorPosition the position of the cursor following the insert relative to replacementOffset
+     */
+    public this(String replacementString, int replacementOffset, int replacementLength, int cursorPosition) {
+        this(replacementString, replacementOffset, replacementLength, cursorPosition, null, null, null, null);
+    }
+
+    /**
+     * Creates a new completion proposal. All fields are initialized based on the provided information.
+     *
+     * @param replacementString the actual string to be inserted into the document
+     * @param replacementOffset the offset of the text to be replaced
+     * @param replacementLength the length of the text to be replaced
+     * @param cursorPosition the position of the cursor following the insert relative to replacementOffset
+     * @param image the image to display for this proposal
+     * @param displayString the string to be displayed for the proposal
+     * @param contextInformation the context information associated with this proposal
+     * @param additionalProposalInfo the additional information associated with this proposal
+     */
+    public this(String replacementString, int replacementOffset, int replacementLength, int cursorPosition, Image image, String displayString, IContextInformation contextInformation, String additionalProposalInfo) {
+        Assert.isNotNull(replacementString);
+        Assert.isTrue(replacementOffset >= 0);
+        Assert.isTrue(replacementLength >= 0);
+        Assert.isTrue(cursorPosition >= 0);
+
+        fReplacementString= replacementString;
+        fReplacementOffset= replacementOffset;
+        fReplacementLength= replacementLength;
+        fCursorPosition= cursorPosition;
+        fImage= image;
+        fDisplayString= displayString;
+        fContextInformation= contextInformation;
+        fAdditionalProposalInfo= additionalProposalInfo;
+    }
+
+    /*
+     * @see ICompletionProposal#apply(IDocument)
+     */
+    public void apply(IDocument document) {
+        try {
+            document.replace(fReplacementOffset, fReplacementLength, fReplacementString);
+        } catch (BadLocationException x) {
+            // ignore
+        }
+    }
+
+    /*
+     * @see ICompletionProposal#getSelection(IDocument)
+     */
+    public Point getSelection(IDocument document) {
+        return new Point(fReplacementOffset + fCursorPosition, 0);
+    }
+
+    /*
+     * @see ICompletionProposal#getContextInformation()
+     */
+    public IContextInformation getContextInformation() {
+        return fContextInformation;
+    }
+
+    /*
+     * @see ICompletionProposal#getImage()
+     */
+    public Image getImage() {
+        return fImage;
+    }
+
+    /*
+     * @see ICompletionProposal#getDisplayString()
+     */
+    public String getDisplayString() {
+        if (fDisplayString !is null)
+            return fDisplayString;
+        return fReplacementString;
+    }
+
+    /*
+     * @see ICompletionProposal#getAdditionalProposalInfo()
+     */
+    public String getAdditionalProposalInfo() {
+        return fAdditionalProposalInfo;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/CompletionProposalPopup.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1884 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Sean Montgomery, sean_montgomery@comcast.net - https://bugs.eclipse.org/bugs/show_bug.cgi?id=116454
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.CompletionProposalPopup;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwt.DWT;
+import dwt.custom.BusyIndicator;
+import dwt.custom.StyleRange;
+import dwt.events.ControlEvent;
+import dwt.events.ControlListener;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.FocusEvent;
+import dwt.events.FocusListener;
+import dwt.events.KeyAdapter;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.events.MouseAdapter;
+import dwt.events.MouseEvent;
+import dwt.events.SelectionEvent;
+import dwt.events.SelectionListener;
+import dwt.events.TraverseEvent;
+import dwt.events.TraverseListener;
+import dwt.events.VerifyEvent;
+import dwt.graphics.Color;
+import dwt.graphics.Font;
+import dwt.graphics.FontData;
+import dwt.graphics.Image;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.layout.GridData;
+import dwt.layout.GridLayout;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Label;
+import dwt.widgets.Listener;
+import dwt.widgets.Shell;
+import dwt.widgets.Table;
+import dwt.widgets.TableItem;
+import dwtx.core.commands.AbstractHandler;
+import dwtx.core.commands.ExecutionEvent;
+import dwtx.core.commands.ExecutionException;
+import dwtx.core.commands.IHandler;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.bindings.keys.KeySequence;
+import dwtx.jface.bindings.keys.SWTKeySupport;
+import dwtx.jface.contentassist.IContentAssistSubjectControl;
+import dwtx.jface.internal.text.InformationControlReplacer;
+import dwtx.jface.internal.text.TableOwnerDrawSupport;
+import dwtx.jface.preference.JFacePreferences;
+import dwtx.jface.resource.JFaceResources;
+import dwtx.jface.text.AbstractInformationControlManager;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentListener;
+import dwtx.jface.text.IEditingSupport;
+import dwtx.jface.text.IEditingSupportRegistry;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.IRewriteTarget;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension;
+import dwtx.jface.text.TextUtilities;
+import dwtx.jface.text.AbstractInformationControlManager;
+import dwtx.jface.util.Geometry;
+import dwtx.jface.viewers.StyledString;
+
+
+/**
+ * This class is used to present proposals to the user. If additional
+ * information exists for a proposal, then selecting that proposal
+ * will result in the information being displayed in a secondary
+ * window.
+ *
+ * @see dwtx.jface.text.contentassist.ICompletionProposal
+ * @see dwtx.jface.text.contentassist.AdditionalInfoController
+ */
+class CompletionProposalPopup : IContentAssistListener {
+    /**
+     * Set to <code>true</code> to use a Table with DWT.VIRTUAL.
+     * XXX: This is a workaround for: https://bugs.eclipse.org/bugs/show_bug.cgi?id=90321
+     *      More details see also: https://bugs.eclipse.org/bugs/show_bug.cgi?id=98585#c36
+     * @since 3.1
+     */
+    private static bool USE_VIRTUAL_;
+    private static bool USE_VIRTUAL_init = false;;
+    private static bool USE_VIRTUAL(){
+        if( !USE_VIRTUAL_init ){
+            USE_VIRTUAL_init = true;
+            USE_VIRTUAL_ = !"motif".equals(DWT.getPlatform()); //$NON-NLS-1$
+        }
+        return USE_VIRTUAL_;
+    }
+
+    /**
+     * Completion proposal selection handler.
+     *
+     * @since 3.4
+     */
+    final class ProposalSelectionHandler : AbstractHandler {
+
+        /**
+         * Selection operation codes.
+         */
+        static const int SELECT_NEXT= 1;
+        static const int SELECT_PREVIOUS= 2;
+
+
+        private int fOperationCode;
+
+        /**
+         * Creates a new selection handler.
+         *
+         * @param operationCode the operation code
+         * @since 3.4
+         */
+        public this(int operationCode) {
+            Assert.isLegal(operationCode is SELECT_NEXT || operationCode is SELECT_PREVIOUS);
+            fOperationCode= operationCode;
+        }
+
+        /*
+         * @see dwtx.core.commands.AbstractHandler#execute(dwtx.core.commands.ExecutionEvent)
+         * @since 3.4
+         */
+        public Object execute(ExecutionEvent event)  {
+            int itemCount= fProposalTable.getItemCount();
+            int selectionIndex= fProposalTable.getSelectionIndex();
+            switch (fOperationCode) {
+            case SELECT_NEXT:
+                selectionIndex+= 1;
+                if (selectionIndex > itemCount - 1)
+                    selectionIndex= 0;
+                break;
+            case SELECT_PREVIOUS:
+                selectionIndex-= 1;
+                if (selectionIndex < 0)
+                    selectionIndex= itemCount - 1;
+                break;
+            }
+            selectProposal(selectionIndex, false);
+            return null;
+        }
+
+    }
+
+
+    /**
+     * The empty proposal displayed if there is nothing else to show.
+     *
+     * @since 3.2
+     */
+    private static final class EmptyProposal : ICompletionProposal, ICompletionProposalExtension {
+
+        String fDisplayString;
+        int fOffset;
+        /*
+         * @see ICompletionProposal#apply(IDocument)
+         */
+        public void apply(IDocument document) {
+        }
+
+        /*
+         * @see ICompletionProposal#getSelection(IDocument)
+         */
+        public Point getSelection(IDocument document) {
+            return new Point(fOffset, 0);
+        }
+
+        /*
+         * @see ICompletionProposal#getContextInformation()
+         */
+        public IContextInformation getContextInformation() {
+            return null;
+        }
+
+        /*
+         * @see ICompletionProposal#getImage()
+         */
+        public Image getImage() {
+            return null;
+        }
+
+        /*
+         * @see ICompletionProposal#getDisplayString()
+         */
+        public String getDisplayString() {
+            return fDisplayString;
+        }
+
+        /*
+         * @see ICompletionProposal#getAdditionalProposalInfo()
+         */
+        public String getAdditionalProposalInfo() {
+            return null;
+        }
+
+        /*
+         * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#apply(dwtx.jface.text.IDocument, char, int)
+         */
+        public void apply(IDocument document, char trigger, int offset) {
+        }
+
+        /*
+         * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#isValidFor(dwtx.jface.text.IDocument, int)
+         */
+        public bool isValidFor(IDocument document, int offset) {
+            return false;
+        }
+
+        /*
+         * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#getTriggerCharacters()
+         */
+        public char[] getTriggerCharacters() {
+            return null;
+        }
+
+        /*
+         * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#getContextInformationPosition()
+         */
+        public int getContextInformationPosition() {
+            return -1;
+        }
+    }
+
+    private final class ProposalSelectionListener : KeyListener {
+        public void keyPressed(KeyEvent e) {
+            if (!Helper.okToUse(fProposalShell))
+                return;
+
+            if (e.character is 0 && e.keyCode is DWT.CTRL) {
+                // http://dev.eclipse.org/bugs/show_bug.cgi?id=34754
+                int index= fProposalTable.getSelectionIndex();
+                if (index >= 0)
+                    selectProposal(index, true);
+            }
+        }
+
+        public void keyReleased(KeyEvent e) {
+            if (!Helper.okToUse(fProposalShell))
+                return;
+
+            if (e.character is 0 && e.keyCode is DWT.CTRL) {
+                // http://dev.eclipse.org/bugs/show_bug.cgi?id=34754
+                int index= fProposalTable.getSelectionIndex();
+                if (index >= 0)
+                    selectProposal(index, false);
+            }
+        }
+    }
+
+    private final class CommandKeyListener : KeyAdapter {
+        private KeySequence fCommandSequence;
+
+        private this(KeySequence keySequence) {
+            fCommandSequence= keySequence;
+        }
+
+        public void keyPressed(KeyEvent e) {
+            if (!Helper.okToUse(fProposalShell))
+                return;
+
+            int accelerator= SWTKeySupport.convertEventToUnmodifiedAccelerator(e);
+            KeySequence sequence= KeySequence.getInstance(SWTKeySupport.convertAcceleratorToKeyStroke(accelerator));
+            if (sequence==/++/fCommandSequence)
+                if (fContentAssistant.isPrefixCompletionEnabled())
+                    incrementalComplete();
+                else
+                    showProposals(false);
+
+        }
+    }
+
+
+    /** The associated text viewer. */
+    private ITextViewer fViewer;
+    /** The associated content assistant. */
+    private ContentAssistant fContentAssistant;
+    /** The used additional info controller. */
+    private AdditionalInfoController fAdditionalInfoController;
+    /** The closing strategy for this completion proposal popup. */
+    private PopupCloser fPopupCloser;
+    /** The popup shell. */
+    private Shell fProposalShell;
+    /** The proposal table. */
+    private Table fProposalTable;
+    /** Indicates whether a completion proposal is being inserted. */
+    private bool fInserting= false;
+    /** The key listener to control navigation. */
+    private ProposalSelectionListener fKeyListener;
+    /** List of document events used for filtering proposals. */
+    private List fDocumentEvents;
+    /** Listener filling the document event queue. */
+    private IDocumentListener fDocumentListener;
+    /** The filter list of proposals. */
+    private ICompletionProposal[] fFilteredProposals;
+    /** The computed list of proposals. */
+    private ICompletionProposal[] fComputedProposals;
+    /** The offset for which the proposals have been computed. */
+    private int fInvocationOffset;
+    /** The offset for which the computed proposals have been filtered. */
+    private int fFilterOffset;
+    /**
+     * The most recently selected proposal.
+     * @since 3.0
+     */
+    private ICompletionProposal fLastProposal;
+    /**
+     * The content assist subject control.
+     * This replaces <code>fViewer</code>
+     *
+     * @since 3.0
+     */
+    private IContentAssistSubjectControl fContentAssistSubjectControl;
+    /**
+     * The content assist subject control adapter.
+     * This replaces <code>fViewer</code>
+     *
+     * @since 3.0
+     */
+    private ContentAssistSubjectControlAdapter fContentAssistSubjectControlAdapter;
+    /**
+     * Remembers the size for this completion proposal popup.
+     * @since 3.0
+     */
+    private Point fSize;
+    /**
+     * Editor helper that communicates that the completion proposal popup may
+     * have focus while the 'logical focus' is still with the editor.
+     * @since 3.1
+     */
+    private IEditingSupport fFocusHelper;
+    /**
+     * Set to true by {@link #computeFilteredProposals(int, DocumentEvent)} if
+     * the returned proposals are a subset of {@link #fFilteredProposals},
+     * <code>false</code> if not.
+     * @since 3.1
+     */
+    private bool fIsFilteredSubset;
+    /**
+     * The filter runnable.
+     *
+     * @since 3.1.1
+     */
+    private Runnable fFilterRunnable;
+    private void fFilterRunnableInit(){
+        fFilterRunnable = dgRunnable( {
+            if (!fIsFilterPending)
+                return;
+
+            fIsFilterPending= false;
+
+            if (!Helper.okToUse(fContentAssistSubjectControlAdapter.getControl()))
+                return;
+
+            int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
+            ICompletionProposal[] proposals= null;
+            try  {
+                if (offset > -1) {
+                    DocumentEvent event= TextUtilities.mergeProcessedDocumentEvents(fDocumentEvents);
+                    proposals= computeFilteredProposals(offset, event);
+                }
+            } catch (BadLocationException x)  {
+            } finally  {
+                fDocumentEvents.clear();
+            }
+            fFilterOffset= offset;
+
+            if (proposals !is null && proposals.length > 0)
+                setProposals(proposals, fIsFilteredSubset);
+            else
+                hide();
+        });
+    }
+
+    /**
+     * <code>true</code> if <code>fFilterRunnable</code> has been
+     * posted, <code>false</code> if not.
+     *
+     * @since 3.1.1
+     */
+    private bool fIsFilterPending= false;
+    /**
+     * The info message at the bottom of the popup, or <code>null</code> for no popup (if
+     * ContentAssistant does not provide one).
+     *
+     * @since 3.2
+     */
+    private Label fMessageText;
+    /**
+     * The font used for <code>fMessageText</code> or null; dispose when done.
+     *
+     * @since 3.2
+     */
+    private Font fMessageTextFont;
+    /**
+     * The most recent completion offset (used to determine repeated invocation)
+     *
+     * @since 3.2
+     */
+    private int fLastCompletionOffset;
+    /**
+     * The (reusable) empty proposal.
+     *
+     * @since 3.2
+     */
+    private EmptyProposal fEmptyProposal;
+    /**
+     * The text for the empty proposal, or <code>null</code> to use the default text.
+     *
+     * @since 3.2
+     */
+    private String fEmptyMessage= null;
+    /**
+     * Tells whether colored labels support is enabled.
+     * Only valid while the popup is active.
+     *
+     * @since 3.4
+     */
+    private bool fIsColoredLabelsSupportEnabled= false;
+
+
+    /**
+     * Creates a new completion proposal popup for the given elements.
+     *
+     * @param contentAssistant the content assistant feeding this popup
+     * @param viewer the viewer on top of which this popup appears
+     * @param infoController the information control collaborating with this popup
+     * @since 2.0
+     */
+    public this(ContentAssistant contentAssistant, ITextViewer viewer, AdditionalInfoController infoController) {
+        // DWT instance init
+        fDocumentEvents= new ArrayList();
+        fPopupCloser= new PopupCloser();
+        if( fEmptyProposal is null ) fEmptyProposal= new EmptyProposal();
+        fFilterRunnableInit();
+
+        fContentAssistant= contentAssistant;
+        fViewer= viewer;
+        fAdditionalInfoController= infoController;
+        fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fViewer);
+    }
+
+    /**
+     * Creates a new completion proposal popup for the given elements.
+     *
+     * @param contentAssistant the content assistant feeding this popup
+     * @param contentAssistSubjectControl the content assist subject control on top of which this popup appears
+     * @param infoController the information control collaborating with this popup
+     * @since 3.0
+     */
+    public this(ContentAssistant contentAssistant, IContentAssistSubjectControl contentAssistSubjectControl, AdditionalInfoController infoController) {
+        // DWT instance init
+        fDocumentEvents= new ArrayList();
+        fPopupCloser= new PopupCloser();
+        if( fEmptyProposal is null ) fEmptyProposal= new EmptyProposal();
+        fFilterRunnableInit();
+
+        fContentAssistant= contentAssistant;
+        fContentAssistSubjectControl= contentAssistSubjectControl;
+        fAdditionalInfoController= infoController;
+        fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fContentAssistSubjectControl);
+    }
+
+    /**
+     * Computes and presents completion proposals. The flag indicates whether this call has
+     * be made out of an auto activation context.
+     *
+     * @param autoActivated <code>true</code> if auto activation context
+     * @return an error message or <code>null</code> in case of no error
+     */
+    public String showProposals(bool autoActivated) {
+
+        if (fKeyListener is null)
+            fKeyListener= new ProposalSelectionListener();
+
+        final Control control= fContentAssistSubjectControlAdapter.getControl();
+
+        if (!Helper.okToUse(fProposalShell) && control !is null && !control.isDisposed()) {
+            // add the listener before computing the proposals so we don't move the caret
+            // when the user types fast.
+            fContentAssistSubjectControlAdapter.addKeyListener(fKeyListener);
+
+            BusyIndicator.showWhile(control.getDisplay(), dgRunnable((bool autoActivated_) {
+
+                fInvocationOffset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
+                fFilterOffset= fInvocationOffset;
+                fLastCompletionOffset= fFilterOffset;
+                fComputedProposals= computeProposals(fInvocationOffset);
+
+                int count= (fComputedProposals is null ? 0 : fComputedProposals.length);
+                if (count is 0 && hideWhenNoProposals(autoActivated_))
+                    return;
+
+                if (count is 1 && !autoActivated_ && canAutoInsert(fComputedProposals[0])) {
+                    insertProposal(fComputedProposals[0], cast(wchar) 0, 0, fInvocationOffset);
+                    hide();
+                } else {
+                    createProposalSelector();
+                    setProposals(fComputedProposals, false);
+                    displayProposals();
+                }
+            }, autoActivated ));
+        } else {
+            fLastCompletionOffset= fFilterOffset;
+            handleRepeatedInvocation();
+        }
+
+        return getErrorMessage();
+    }
+
+    /**
+     * Hides the popup and returns <code>true</code> if the popup is configured
+     * to never display an empty list. Returns <code>false</code> otherwise.
+     *
+     * @param autoActivated whether the invocation was auto-activated
+     * @return <code>false</code> if an empty list should be displayed, <code>true</code> otherwise
+     * @since 3.2
+     */
+    private bool hideWhenNoProposals(bool autoActivated) {
+        if (autoActivated || !fContentAssistant.isShowEmptyList()) {
+            if (!autoActivated) {
+                Control control= fContentAssistSubjectControlAdapter.getControl();
+                if (control !is null && !control.isDisposed())
+                    control.getDisplay().beep();
+            }
+            hide();
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * If content assist is set up to handle cycling, then the proposals are recomputed. Otherwise,
+     * nothing happens.
+     *
+     * @since 3.2
+     */
+    private void handleRepeatedInvocation() {
+        if (fContentAssistant.isRepeatedInvocationMode()) {
+            fComputedProposals= computeProposals(fFilterOffset);
+            setProposals(fComputedProposals, false);
+        }
+    }
+
+    /**
+     * Returns the completion proposal available at the given offset of the
+     * viewer's document. Delegates the work to the content assistant.
+     *
+     * @param offset the offset
+     * @return the completion proposals available at this offset
+     */
+    private ICompletionProposal[] computeProposals(int offset) {
+        if (fContentAssistSubjectControl !is null)
+            return fContentAssistant.computeCompletionProposals(fContentAssistSubjectControl, offset);
+        return fContentAssistant.computeCompletionProposals(fViewer, offset);
+    }
+
+    /**
+     * Returns the error message.
+     *
+     * @return the error message
+     */
+    private String getErrorMessage() {
+        return fContentAssistant.getErrorMessage();
+    }
+
+    /**
+     * Creates the proposal selector.
+     */
+    private void createProposalSelector() {
+        if (Helper.okToUse(fProposalShell))
+            return;
+
+        Control control= fContentAssistSubjectControlAdapter.getControl();
+        fProposalShell= new Shell(control.getShell(), DWT.ON_TOP | DWT.RESIZE );
+        fProposalShell.setFont(JFaceResources.getDefaultFont());
+        if (USE_VIRTUAL) {
+            fProposalTable= new Table(fProposalShell, DWT.H_SCROLL | DWT.V_SCROLL | DWT.VIRTUAL);
+
+            Listener listener= new class()  Listener {
+                public void handleEvent(Event event) {
+                    handleSetData(event);
+                }
+            };
+            fProposalTable.addListener(DWT.SetData, listener);
+        } else {
+            fProposalTable= new Table(fProposalShell, DWT.H_SCROLL | DWT.V_SCROLL);
+        }
+
+        fIsColoredLabelsSupportEnabled= fContentAssistant.isColoredLabelsSupportEnabled();
+        if (fIsColoredLabelsSupportEnabled)
+            TableOwnerDrawSupport.install(fProposalTable);
+
+        fProposalTable.setLocation(0, 0);
+        if (fAdditionalInfoController !is null)
+            fAdditionalInfoController.setSizeConstraints(50, 10, true, true);
+
+        GridLayout layout= new GridLayout();
+        layout.marginWidth= 0;
+        layout.marginHeight= 0;
+        layout.verticalSpacing= 1;
+        fProposalShell.setLayout(layout);
+
+        if (fContentAssistant.isStatusLineVisible()) {
+            createMessageText();
+        }
+
+        GridData data= new GridData(GridData.FILL_BOTH);
+
+        Point size= fContentAssistant.restoreCompletionProposalPopupSize_package();
+        if (size !is null) {
+            fProposalTable.setLayoutData(data);
+            fProposalShell.setSize(size);
+        } else {
+            int height= fProposalTable.getItemHeight() * 10;
+            // use golden ratio as default aspect ratio
+            double aspectRatio= (1 + Math.sqrt(5.0f)) / 2;
+            int width= cast(int) (height * aspectRatio);
+            Rectangle trim= fProposalTable.computeTrim(0, 0, width, height);
+            data.heightHint= trim.height;
+            data.widthHint= trim.width;
+            fProposalTable.setLayoutData(data);
+            fProposalShell.pack();
+        }
+        fContentAssistant.addToLayout(this, fProposalShell, ContentAssistant.LayoutManager.LAYOUT_PROPOSAL_SELECTOR, fContentAssistant.getSelectionOffset());
+
+        fProposalShell.addControlListener(new class()  ControlListener {
+
+            public void controlMoved(ControlEvent e) {}
+
+            public void controlResized(ControlEvent e) {
+                if (fAdditionalInfoController !is null) {
+                    // reset the cached resize constraints
+                    fAdditionalInfoController.setSizeConstraints(50, 10, true, false);
+                }
+
+                fSize= fProposalShell.getSize();
+            }
+        });
+
+        fProposalShell.setBackground(control.getDisplay().getSystemColor(DWT.COLOR_GRAY));
+
+        Color c= getBackgroundColor(control);
+        fProposalTable.setBackground(c);
+
+        c= getForegroundColor(control);
+        fProposalTable.setForeground(c);
+
+        fProposalTable.addSelectionListener(new class()  SelectionListener {
+
+            public void widgetSelected(SelectionEvent e) {}
+
+            public void widgetDefaultSelected(SelectionEvent e) {
+                insertSelectedProposalWithMask(e.stateMask);
+            }
+        });
+
+        fPopupCloser.install(fContentAssistant, fProposalTable, fAdditionalInfoController);
+
+        fProposalShell.addDisposeListener(new class()  DisposeListener {
+            public void widgetDisposed(DisposeEvent e) {
+                unregister(); // but don't dispose the shell, since we're being called from its disposal event!
+            }
+        });
+
+        fProposalTable.setHeaderVisible(false);
+
+        addCommandSupport(fProposalTable);
+    }
+
+    /**
+     * Returns the minimal required height for the proposal, may return 0 if the popup has not been
+     * created yet.
+     *
+     * @return the minimal height
+     * @since 3.3
+     */
+    int getMinimalHeight() {
+        int height= 0;
+        if (Helper.okToUse(fProposalTable)) {
+            int items= fProposalTable.getItemHeight() * 10;
+            Rectangle trim= fProposalTable.computeTrim(0, 0, DWT.DEFAULT, items);
+            height= trim.height;
+        }
+        if (Helper.okToUse(fMessageText))
+            height+= fMessageText.getSize().y + 1;
+        return height;
+    }
+
+    /**
+     * Adds command support to the given control.
+     *
+     * @param control the control to watch for focus
+     * @since 3.2
+     */
+    private void addCommandSupport(Control control) {
+        final KeySequence commandSequence= fContentAssistant.getRepeatedInvocationKeySequence();
+        if (commandSequence !is null && !commandSequence.isEmpty() && fContentAssistant.isRepeatedInvocationMode()) {
+            control.addFocusListener(new class(control,commandSequence)  FocusListener {
+                Control control_;
+                KeySequence commandSequence_;
+                this(Control a, KeySequence b){
+                    control_=a;
+                    commandSequence_=b;
+                }
+                private CommandKeyListener fCommandKeyListener;
+                public void focusGained(FocusEvent e) {
+                    if (Helper.okToUse(control_)) {
+                        if (fCommandKeyListener is null) {
+                            fCommandKeyListener= new CommandKeyListener(commandSequence_);
+                            fProposalTable.addKeyListener(fCommandKeyListener);
+                        }
+                    }
+                }
+                public void focusLost(FocusEvent e) {
+                    if (fCommandKeyListener !is null) {
+                        control_.removeKeyListener(fCommandKeyListener);
+                        fCommandKeyListener= null;
+                    }
+                }
+            });
+        }
+        control.addFocusListener(new class(control)  FocusListener {
+            Control control_;
+            private TraverseListener fTraverseListener;
+            this(Control a){
+                control_=a;
+            }
+            public void focusGained(FocusEvent e) {
+                if (Helper.okToUse(control_)) {
+                    if (fTraverseListener is null) {
+                        fTraverseListener= new class()  TraverseListener {
+                            public void keyTraversed(TraverseEvent event) {
+                                if (event.detail is DWT.TRAVERSE_TAB_NEXT) {
+                                    IInformationControl iControl= fAdditionalInfoController.getCurrentInformationControl2();
+                                    if (fAdditionalInfoController.getInternalAccessor().canReplace(iControl)) {
+                                        fAdditionalInfoController.getInternalAccessor().replaceInformationControl(true);
+                                        event.doit= false;
+                                    }
+                                }
+                            }
+                        };
+                        fProposalTable.addTraverseListener(fTraverseListener);
+                    }
+                }
+            }
+            public void focusLost(FocusEvent e) {
+                if (fTraverseListener !is null) {
+                    control_.removeTraverseListener(fTraverseListener);
+                    fTraverseListener= null;
+                }
+            }
+        });
+    }
+
+    /**
+     * Returns the background color to use.
+     *
+     * @param control the control to get the display from
+     * @return the background color
+     * @since 3.2
+     */
+    private Color getBackgroundColor(Control control) {
+        Color c= fContentAssistant.getProposalSelectorBackground();
+        if (c is null)
+            c= JFaceResources.getColorRegistry().get(JFacePreferences.CONTENT_ASSIST_BACKGROUND_COLOR);
+        return c;
+    }
+
+    /**
+     * Returns the foreground color to use.
+     *
+     * @param control the control to get the display from
+     * @return the foreground color
+     * @since 3.2
+     */
+    private Color getForegroundColor(Control control) {
+        Color c= fContentAssistant.getProposalSelectorForeground();
+        if (c is null)
+            c= JFaceResources.getColorRegistry().get(JFacePreferences.CONTENT_ASSIST_FOREGROUND_COLOR);
+        return c;
+    }
+
+    /**
+     * Creates the caption line under the proposal table.
+     *
+     * @since 3.2
+     */
+    private void createMessageText() {
+        if (fMessageText is null) {
+            fMessageText= new Label(fProposalShell, DWT.RIGHT);
+            GridData textData= new GridData(DWT.FILL, DWT.BOTTOM, true, false);
+            fMessageText.setLayoutData(textData);
+            fMessageText.setText(fContentAssistant.getStatusMessage() ~ " "); //$NON-NLS-1$
+            if (fMessageTextFont is null) {
+                Font font= fMessageText.getFont();
+                Display display= fProposalShell.getDisplay();
+                FontData[] fontDatas= font.getFontData();
+                for (int i= 0; i < fontDatas.length; i++)
+                    fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10);
+                fMessageTextFont= new Font(display, fontDatas);
+            }
+            fMessageText.setFont(fMessageTextFont);
+            fMessageText.setBackground(getBackgroundColor(fProposalShell));
+            fMessageText.setForeground(getForegroundColor(fProposalShell));
+
+            if (fContentAssistant.isRepeatedInvocationMode()) {
+                fMessageText.setCursor(fProposalShell.getDisplay().getSystemCursor(DWT.CURSOR_HAND));
+                fMessageText.addMouseListener(new class()  MouseAdapter {
+                    public void mouseUp(MouseEvent e) {
+                        fLastCompletionOffset= fFilterOffset;
+                        fProposalTable.setFocus();
+                        handleRepeatedInvocation();
+                    }
+
+                    public void mouseDown(MouseEvent e) {
+                    }
+                });
+            }
+        }
+    }
+
+    /*
+     * @since 3.1
+     */
+    private void handleSetData(Event event) {
+        TableItem item= cast(TableItem) event.item;
+        int index= fProposalTable.indexOf(item);
+
+        if (0 <= index && index < fFilteredProposals.length) {
+            ICompletionProposal current= fFilteredProposals[index];
+
+            String displayString;
+            StyleRange[] styleRanges= null;
+            if (fIsColoredLabelsSupportEnabled && cast(ICompletionProposalExtension6)current ) {
+                StyledString styledString= (cast(ICompletionProposalExtension6)current).getStyledDisplayString();
+                displayString= styledString.getString();
+                styleRanges= styledString.getStyleRanges();
+            } else
+                displayString= current.getDisplayString();
+
+            item.setText(displayString);
+            if (fIsColoredLabelsSupportEnabled)
+                TableOwnerDrawSupport.storeStyleRanges(item, 0, styleRanges);
+
+            item.setImage(current.getImage());
+            item.setData(cast(Object)current);
+        } else {
+            // this should not happen, but does on win32
+        }
+    }
+
+    /**
+     * Returns the proposal selected in the proposal selector.
+     *
+     * @return the selected proposal
+     * @since 2.0
+     */
+    private ICompletionProposal getSelectedProposal() {
+        /* Make sure that there is no filter runnable pending.
+         * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=31427
+         */
+        if (fIsFilterPending)
+            fFilterRunnable.run();
+
+        // filter runnable may have hidden the proposals
+        if (!Helper.okToUse(fProposalTable))
+            return null;
+
+        int i= fProposalTable.getSelectionIndex();
+        if (fFilteredProposals is null || i < 0 || i >= fFilteredProposals.length)
+            return null;
+        return fFilteredProposals[i];
+    }
+
+    /**
+     * Takes the selected proposal and applies it.
+     *
+     * @param stateMask the state mask
+     * @since 3.2
+     */
+    private void insertSelectedProposalWithMask(int stateMask) {
+        ICompletionProposal p= getSelectedProposal();
+        hide();
+        if (p !is null)
+            insertProposal(p, cast(wchar) 0, stateMask, fContentAssistSubjectControlAdapter.getSelectedRange().x);
+    }
+
+    /**
+     * Applies the given proposal at the given offset. The given character is the
+     * one that triggered the insertion of this proposal.
+     *
+     * @param p the completion proposal
+     * @param trigger the trigger character
+     * @param stateMask the state mask
+     * @param offset the offset
+     * @since 2.1
+     */
+    private void insertProposal(ICompletionProposal p, char trigger, int stateMask, int offset) {
+
+        fInserting= true;
+        IRewriteTarget target= null;
+        IEditingSupport helper= new class(offset)  IEditingSupport {
+            int offset_;
+            this(int a){
+                offset_=a;
+            }
+            public bool isOriginator(DocumentEvent event, IRegion focus) {
+                return focus.getOffset() <= offset_ && focus.getOffset() + focus.getLength() >= offset_;
+            }
+
+            public bool ownsFocusShell() {
+                return false;
+            }
+
+        };
+
+        try {
+
+            IDocument document= fContentAssistSubjectControlAdapter.getDocument();
+
+            if ( cast(ITextViewerExtension)fViewer ) {
+                ITextViewerExtension extension= cast(ITextViewerExtension) fViewer;
+                target= extension.getRewriteTarget();
+            }
+
+            if (target !is null)
+                target.beginCompoundChange();
+
+            if ( cast(IEditingSupportRegistry)fViewer ) {
+                IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer;
+                registry.register(helper);
+            }
+
+
+            if (cast(ICompletionProposalExtension2)p && fViewer !is null) {
+                ICompletionProposalExtension2 e= cast(ICompletionProposalExtension2) p;
+                e.apply(fViewer, trigger, stateMask, offset);
+            } else if ( cast(ICompletionProposalExtension)p ) {
+                ICompletionProposalExtension e= cast(ICompletionProposalExtension) p;
+                e.apply(document, trigger, offset);
+            } else {
+                p.apply(document);
+            }
+
+            Point selection= p.getSelection(document);
+            if (selection !is null) {
+                fContentAssistSubjectControlAdapter.setSelectedRange(selection.x, selection.y);
+                fContentAssistSubjectControlAdapter.revealRange(selection.x, selection.y);
+            }
+
+            IContextInformation info= p.getContextInformation();
+            if (info !is null) {
+
+                int contextInformationOffset;
+                if ( cast(ICompletionProposalExtension)p ) {
+                    ICompletionProposalExtension e= cast(ICompletionProposalExtension) p;
+                    contextInformationOffset= e.getContextInformationPosition();
+                } else {
+                    if (selection is null)
+                        selection= fContentAssistSubjectControlAdapter.getSelectedRange();
+                    contextInformationOffset= selection.x + selection.y;
+                }
+
+                fContentAssistant.showContextInformation(info, contextInformationOffset);
+            } else
+                fContentAssistant.showContextInformation(null, -1);
+
+
+        } finally {
+            if (target !is null)
+                target.endCompoundChange();
+
+            if ( cast(IEditingSupportRegistry)fViewer ) {
+                IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer;
+                registry.unregister(helper);
+            }
+            fInserting= false;
+        }
+    }
+
+    /**
+     * Returns whether this popup has the focus.
+     *
+     * @return <code>true</code> if the popup has the focus
+     */
+    public bool hasFocus() {
+        if (Helper.okToUse(fProposalShell)) {
+            if ((fProposalShell.isFocusControl() || fProposalTable.isFocusControl()))
+                return true;
+            /*
+             * We have to delegate this query to the additional info controller
+             * as well, since the content assistant is the widget token owner
+             * and its closer does not know that the additional info control can
+             * now also take focus.
+             */
+            if (fAdditionalInfoController !is null) {
+                IInformationControl informationControl= fAdditionalInfoController.getCurrentInformationControl2();
+                if (informationControl !is null && informationControl.isFocusControl())
+                    return true;
+                InformationControlReplacer replacer= fAdditionalInfoController.getInternalAccessor().getInformationControlReplacer();
+                if (replacer !is null) {
+                    informationControl= replacer.getCurrentInformationControl2();
+                    if (informationControl !is null && informationControl.isFocusControl())
+                        return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Hides this popup.
+     */
+    public void hide() {
+
+        unregister();
+
+        if ( cast(IEditingSupportRegistry)fViewer ) {
+            IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer;
+            registry.unregister(fFocusHelper);
+        }
+
+        if (Helper.okToUse(fProposalShell)) {
+
+            fContentAssistant.removeContentAssistListener(this, ContentAssistant.PROPOSAL_SELECTOR);
+
+            fPopupCloser.uninstall();
+            fProposalShell.setVisible(false);
+            fProposalShell.dispose();
+            fProposalShell= null;
+        }
+
+        if (fMessageTextFont !is null) {
+            fMessageTextFont.dispose();
+            fMessageTextFont= null;
+        }
+
+        if (fMessageText !is null) {
+            fMessageText= null;
+        }
+
+        fEmptyMessage= null;
+
+        fLastCompletionOffset= -1;
+
+        fContentAssistant.fireSessionEndEvent();
+    }
+
+    /**
+     * Unregister this completion proposal popup.
+     *
+     * @since 3.0
+     */
+    private void unregister() {
+        if (fDocumentListener !is null) {
+            IDocument document= fContentAssistSubjectControlAdapter.getDocument();
+            if (document !is null)
+                document.removeDocumentListener(fDocumentListener);
+            fDocumentListener= null;
+        }
+        fDocumentEvents.clear();
+
+        if (fKeyListener !is null && fContentAssistSubjectControlAdapter.getControl() !is null && !fContentAssistSubjectControlAdapter.getControl().isDisposed()) {
+            fContentAssistSubjectControlAdapter.removeKeyListener(fKeyListener);
+            fKeyListener= null;
+        }
+
+        if (fLastProposal !is null) {
+            if (cast(ICompletionProposalExtension2)fLastProposal  && fViewer !is null) {
+                ICompletionProposalExtension2 extension= cast(ICompletionProposalExtension2) fLastProposal;
+                extension.unselected(fViewer);
+            }
+            fLastProposal= null;
+        }
+
+        fFilteredProposals= null;
+        fComputedProposals= null;
+
+        fContentAssistant.possibleCompletionsClosed_package();
+    }
+
+    /**
+     *Returns whether this popup is active. It is active if the proposal selector is visible.
+     *
+     * @return <code>true</code> if this popup is active
+     */
+    public bool isActive() {
+        return fProposalShell !is null && !fProposalShell.isDisposed();
+    }
+
+    /**
+     * Initializes the proposal selector with these given proposals.
+     * @param proposals the proposals
+     * @param isFilteredSubset if <code>true</code>, the proposal table is
+     *        not cleared, but the proposals that are not in the passed array
+     *        are removed from the displayed set
+     */
+    private void setProposals(ICompletionProposal[] proposals, bool isFilteredSubset) {
+        ICompletionProposal[] oldProposals= fFilteredProposals;
+        ICompletionProposal oldProposal= getSelectedProposal(); // may trigger filtering and a reentrant call to setProposals()
+        if (oldProposals !is fFilteredProposals) // reentrant call was first - abort
+            return;
+
+        if (Helper.okToUse(fProposalTable)) {
+            if (cast(ICompletionProposalExtension2)oldProposal  && fViewer !is null)
+                (cast(ICompletionProposalExtension2) oldProposal).unselected(fViewer);
+
+            if (proposals is null || proposals.length is 0) {
+                fEmptyProposal.fOffset= fFilterOffset;
+                fEmptyProposal.fDisplayString= fEmptyMessage !is null ? fEmptyMessage : JFaceTextMessages.getString("CompletionProposalPopup.no_proposals"); //$NON-NLS-1$
+                proposals= [ fEmptyProposal ];
+            }
+
+            fFilteredProposals= proposals;
+            final int newLen= proposals.length;
+            if (USE_VIRTUAL) {
+                fProposalTable.setItemCount(newLen);
+                fProposalTable.clearAll();
+            } else {
+                fProposalTable.setRedraw(false);
+                fProposalTable.setItemCount(newLen);
+                TableItem[] items= fProposalTable.getItems();
+                for (int i= 0; i < items.length; i++) {
+                    TableItem item= items[i];
+                    ICompletionProposal proposal= proposals[i];
+                    item.setText(proposal.getDisplayString());
+                    item.setImage(proposal.getImage());
+                    item.setData(cast(Object)proposal);
+                }
+                fProposalTable.setRedraw(true);
+            }
+
+            Point currentLocation= fProposalShell.getLocation();
+            Point newLocation= getLocation();
+            if ((newLocation.x < currentLocation.x && newLocation.y is currentLocation.y) || newLocation.y < currentLocation.y)
+                fProposalShell.setLocation(newLocation);
+
+            selectProposal(0, false);
+        }
+    }
+
+    /**
+     * Returns the graphical location at which this popup should be made visible.
+     *
+     * @return the location of this popup
+     */
+    private Point getLocation() {
+        int caret= fContentAssistSubjectControlAdapter.getCaretOffset();
+        Rectangle location= fContentAssistant.getLayoutManager().computeBoundsBelowAbove_package(fProposalShell, fSize is null ? fProposalShell.getSize() : fSize, caret, this);
+        return Geometry.getLocation(location);
+    }
+
+    /**
+     * Returns the size of this completion proposal popup.
+     *
+     * @return a Point containing the size
+     * @since 3.0
+     */
+    Point getSize() {
+        return fSize;
+    }
+
+    /**
+     * Displays this popup and install the additional info controller, so that additional info
+     * is displayed when a proposal is selected and additional info is available.
+     */
+    private void displayProposals() {
+
+        if (!Helper.okToUse(fProposalShell) ||  !Helper.okToUse(fProposalTable))
+            return;
+
+        if (fContentAssistant.addContentAssistListener(this, ContentAssistant.PROPOSAL_SELECTOR)) {
+
+            ensureDocumentListenerInstalled();
+
+            if (fFocusHelper is null) {
+                fFocusHelper= new class()  IEditingSupport {
+
+                    public bool isOriginator(DocumentEvent event, IRegion focus) {
+                        return false; // this helper just covers the focus change to the proposal shell, no remote editions
+                    }
+
+                    public bool ownsFocusShell() {
+                        return true;
+                    }
+
+                };
+            }
+            if ( cast(IEditingSupportRegistry)fViewer ) {
+                IEditingSupportRegistry registry= cast(IEditingSupportRegistry) fViewer;
+                registry.register(fFocusHelper);
+            }
+
+
+            /* https://bugs.eclipse.org/bugs/show_bug.cgi?id=52646
+             * on GTK, setVisible and such may run the event loop
+             * (see also https://bugs.eclipse.org/bugs/show_bug.cgi?id=47511)
+             * Since the user may have already canceled the popup or selected
+             * an entry (ESC or RETURN), we have to double check whether
+             * the table is still okToUse. See comments below
+             */
+            fProposalShell.setVisible(true); // may run event loop on GTK
+            // transfer focus since no verify key listener can be attached
+            if (!fContentAssistSubjectControlAdapter.supportsVerifyKeyListener() && Helper.okToUse(fProposalShell))
+                fProposalShell.setFocus(); // may run event loop on GTK ??
+
+            if (fAdditionalInfoController !is null && Helper.okToUse(fProposalTable)) {
+                fAdditionalInfoController.install(fProposalTable);
+                fAdditionalInfoController.handleTableSelectionChanged();
+            }
+        } else
+            hide();
+    }
+
+    /**
+     * Installs the document listener if not already done.
+     *
+     * @since 3.2
+     */
+    private void ensureDocumentListenerInstalled() {
+        if (fDocumentListener is null) {
+            fDocumentListener=  new class()   IDocumentListener {
+                public void documentAboutToBeChanged(DocumentEvent event) {
+                    if (!fInserting)
+                        fDocumentEvents.add(event);
+                }
+
+                public void documentChanged(DocumentEvent event) {
+                    if (!fInserting)
+                        filterProposals();
+                }
+            };
+            IDocument document= fContentAssistSubjectControlAdapter.getDocument();
+            if (document !is null)
+                document.addDocumentListener(fDocumentListener);
+        }
+    }
+
+    /*
+     * @see IContentAssistListener#verifyKey(VerifyEvent)
+     */
+    public bool verifyKey(VerifyEvent e) {
+        if (!Helper.okToUse(fProposalShell))
+            return true;
+
+        char key= e.character;
+        if (key is 0) {
+            int newSelection= fProposalTable.getSelectionIndex();
+            int visibleRows= (fProposalTable.getSize().y / fProposalTable.getItemHeight()) - 1;
+            int itemCount= fProposalTable.getItemCount();
+            bool smartToggle= false;
+            switch (e.keyCode) {
+
+                case DWT.ARROW_LEFT :
+                case DWT.ARROW_RIGHT :
+                    filterProposals();
+                    return true;
+
+                case DWT.ARROW_UP :
+                    newSelection -= 1;
+                    if (newSelection < 0)
+                        newSelection= itemCount - 1;
+                    break;
+
+                case DWT.ARROW_DOWN :
+                    newSelection += 1;
+                    if (newSelection > itemCount - 1)
+                        newSelection= 0;
+                    break;
+
+                case DWT.PAGE_DOWN :
+                    newSelection += visibleRows;
+                    if (newSelection >= itemCount)
+                        newSelection= itemCount - 1;
+                    break;
+
+                case DWT.PAGE_UP :
+                    newSelection -= visibleRows;
+                    if (newSelection < 0)
+                        newSelection= 0;
+                    break;
+
+                case DWT.HOME :
+                    newSelection= 0;
+                    break;
+
+                case DWT.END :
+                    newSelection= itemCount - 1;
+                    break;
+
+                default :
+                    if (e.keyCode !is DWT.CAPS_LOCK && e.keyCode !is DWT.MOD1 && e.keyCode !is DWT.MOD2 && e.keyCode !is DWT.MOD3 && e.keyCode !is DWT.MOD4)
+                        hide();
+                    return true;
+            }
+
+            selectProposal(newSelection, smartToggle);
+
+            e.doit= false;
+            return false;
+
+        }
+
+        // key !is 0
+        switch (key) {
+            case 0x1B: // Esc
+                e.doit= false;
+                hide();
+                break;
+
+            case '\n': // Ctrl-Enter on w2k
+            case '\r': // Enter
+                e.doit= false;
+                insertSelectedProposalWithMask(e.stateMask);
+                break;
+
+            case '\t':
+                e.doit= false;
+                fProposalShell.setFocus();
+                return false;
+
+            default:
+                ICompletionProposal p= getSelectedProposal();
+                if ( cast(ICompletionProposalExtension)p ) {
+                    ICompletionProposalExtension t= cast(ICompletionProposalExtension) p;
+                    char[] triggers= t.getTriggerCharacters();
+                    if (contains(triggers, key)) {
+                        e.doit= false;
+                        hide();
+                        insertProposal(p, key, e.stateMask, fContentAssistSubjectControlAdapter.getSelectedRange().x);
+                    }
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Selects the entry with the given index in the proposal selector and feeds
+     * the selection to the additional info controller.
+     *
+     * @param index the index in the list
+     * @param smartToggle <code>true</code> if the smart toggle key has been pressed
+     * @since 2.1
+     */
+    private void selectProposal(int index, bool smartToggle) {
+
+        ICompletionProposal oldProposal= getSelectedProposal();
+        if (cast(ICompletionProposalExtension2)oldProposal  && fViewer !is null)
+            (cast(ICompletionProposalExtension2) oldProposal).unselected(fViewer);
+
+        if (fFilteredProposals is null) {
+            fireSelectionEvent(null, smartToggle);
+            return;
+        }
+
+        ICompletionProposal proposal= fFilteredProposals[index];
+        if (cast(ICompletionProposalExtension2)proposal && fViewer !is null)
+            (cast(ICompletionProposalExtension2) proposal).selected(fViewer, smartToggle);
+
+        fireSelectionEvent(proposal, smartToggle);
+
+        fLastProposal= proposal;
+
+        fProposalTable.setSelection(index);
+        fProposalTable.showSelection();
+        if (fAdditionalInfoController !is null)
+            fAdditionalInfoController.handleTableSelectionChanged();
+    }
+
+    /**
+     * Fires a selection event, see {@link ICompletionListener}.
+     *
+     * @param proposal the selected proposal, possibly <code>null</code>
+     * @param smartToggle true if the smart toggle is on
+     * @since 3.2
+     */
+    private void fireSelectionEvent(ICompletionProposal proposal, bool smartToggle) {
+        fContentAssistant.fireSelectionEvent(proposal, smartToggle);
+    }
+
+    /**
+     * Returns whether the given character is contained in the given array of
+     * characters.
+     *
+     * @param characters the list of characters
+     * @param c the character to look for in the list
+     * @return <code>true</code> if character belongs to the list
+     * @since 2.0
+     */
+    private bool contains(char[] characters, char c) {
+
+        if (characters is null)
+            return false;
+
+        for (int i= 0; i < characters.length; i++) {
+            if (c is characters[i])
+                return true;
+        }
+
+        return false;
+    }
+
+    /*
+     * @see IEventConsumer#processEvent(VerifyEvent)
+     */
+    public void processEvent(VerifyEvent e) {
+    }
+
+    /**
+     * Filters the displayed proposal based on the given cursor position and the
+     * offset of the original invocation of the content assistant.
+     */
+    private void filterProposals() {
+        if (!fIsFilterPending) {
+            fIsFilterPending= true;
+            Control control= fContentAssistSubjectControlAdapter.getControl();
+            control.getDisplay().asyncExec(fFilterRunnable);
+        }
+    }
+
+    /**
+     * Computes the subset of already computed proposals that are still valid for
+     * the given offset.
+     *
+     * @param offset the offset
+     * @param event the merged document event
+     * @return the set of filtered proposals
+     * @since 3.0
+     */
+    private ICompletionProposal[] computeFilteredProposals(int offset, DocumentEvent event) {
+
+        if (offset is fInvocationOffset && event is null) {
+            fIsFilteredSubset= false;
+            return fComputedProposals;
+        }
+
+        if (offset < fInvocationOffset) {
+            fIsFilteredSubset= false;
+            fInvocationOffset= offset;
+            fContentAssistant.fireSessionRestartEvent();
+            fComputedProposals= computeProposals(fInvocationOffset);
+            return fComputedProposals;
+        }
+
+        ICompletionProposal[] proposals;
+        if (offset < fFilterOffset) {
+            proposals= fComputedProposals;
+            fIsFilteredSubset= false;
+        } else {
+            proposals= fFilteredProposals;
+            fIsFilteredSubset= true;
+        }
+
+        if (proposals is null) {
+            fIsFilteredSubset= false;
+            return null;
+        }
+
+        IDocument document= fContentAssistSubjectControlAdapter.getDocument();
+        int length= proposals.length;
+        List filtered= new ArrayList(length);
+        for (int i= 0; i < length; i++) {
+
+            if (cast(ICompletionProposalExtension2)proposals[i] ) {
+
+                ICompletionProposalExtension2 p= cast(ICompletionProposalExtension2) proposals[i];
+                if (p.validate(document, offset, event))
+                    filtered.add(cast(Object)p);
+
+            } else if (cast(ICompletionProposalExtension)proposals[i] ) {
+
+                ICompletionProposalExtension p= cast(ICompletionProposalExtension) proposals[i];
+                if (p.isValidFor(document, offset))
+                    filtered.add(cast(Object)p);
+
+            } else {
+                // restore original behavior
+                fIsFilteredSubset= false;
+                fInvocationOffset= offset;
+                fContentAssistant.fireSessionRestartEvent();
+                fComputedProposals= computeProposals(fInvocationOffset);
+                return fComputedProposals;
+            }
+        }
+
+        return arraycast!(ICompletionProposal)( filtered.toArray());
+    }
+
+    /**
+     * Requests the proposal shell to take focus.
+     *
+     * @since 3.0
+     */
+    public void setFocus() {
+        if (Helper.okToUse(fProposalShell)) {
+            fProposalShell.setFocus();
+        }
+    }
+
+    /**
+     * Returns <code>true</code> if <code>proposal</code> should be auto-inserted,
+     * <code>false</code> otherwise.
+     *
+     * @param proposal the single proposal that might be automatically inserted
+     * @return <code>true</code> if <code>proposal</code> can be inserted automatically,
+     *         <code>false</code> otherwise
+     * @since 3.1
+     */
+    private bool canAutoInsert(ICompletionProposal proposal) {
+        if (fContentAssistant.isAutoInserting()) {
+            if ( cast(ICompletionProposalExtension4)proposal ) {
+                ICompletionProposalExtension4 ext= cast(ICompletionProposalExtension4) proposal;
+                return ext.isAutoInsertable();
+            }
+            return true; // default behavior before ICompletionProposalExtension4 was introduced
+        }
+        return false;
+    }
+
+    /**
+     * Completes the common prefix of all proposals directly in the code. If no
+     * common prefix can be found, the proposal popup is shown.
+     *
+     * @return an error message if completion failed.
+     * @since 3.0
+     */
+    public String incrementalComplete() {
+        if (Helper.okToUse(fProposalShell) && fFilteredProposals !is null) {
+            if (fLastCompletionOffset is fFilterOffset) {
+                handleRepeatedInvocation();
+            } else {
+                fLastCompletionOffset= fFilterOffset;
+                completeCommonPrefix();
+            }
+        } else {
+            final Control control= fContentAssistSubjectControlAdapter.getControl();
+
+            if (fKeyListener is null)
+                fKeyListener= new ProposalSelectionListener();
+
+            if (!Helper.okToUse(fProposalShell) && !control.isDisposed())
+                fContentAssistSubjectControlAdapter.addKeyListener(fKeyListener);
+
+            BusyIndicator.showWhile(control.getDisplay(), new class()  Runnable {
+                public void run() {
+
+                    fInvocationOffset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
+                    fFilterOffset= fInvocationOffset;
+                    fLastCompletionOffset= fFilterOffset;
+                    fFilteredProposals= computeProposals(fInvocationOffset);
+
+                    int count= (fFilteredProposals is null ? 0 : fFilteredProposals.length);
+                    if (count is 0 && hideWhenNoProposals(false))
+                        return;
+
+                    if (count is 1 && canAutoInsert(fFilteredProposals[0])) {
+                        insertProposal(fFilteredProposals[0], cast(wchar) 0, 0, fInvocationOffset);
+                        hide();
+                    } else {
+                        ensureDocumentListenerInstalled();
+                        if (count > 0 && completeCommonPrefix())
+                            hide();
+                        else {
+                            fComputedProposals= fFilteredProposals;
+                            createProposalSelector();
+                            setProposals(fComputedProposals, false);
+                            displayProposals();
+                        }
+                    }
+                }
+            });
+        }
+        return getErrorMessage();
+    }
+
+    /**
+     * Acts upon <code>fFilteredProposals</code>: if there is just one valid
+     * proposal, it is inserted, otherwise, the common prefix of all proposals
+     * is inserted into the document. If there is no common prefix, nothing
+     * happens and <code>false</code> is returned.
+     *
+     * @return <code>true</code> if a single proposal was inserted and the
+     *         selector can be closed, <code>false</code> otherwise
+     * @since 3.0
+     */
+    private bool completeCommonPrefix() {
+
+        // 0: insert single proposals
+        if (fFilteredProposals.length is 1) {
+            if (canAutoInsert(fFilteredProposals[0])) {
+                insertProposal(fFilteredProposals[0], cast(wchar) 0, 0, fFilterOffset);
+                hide();
+                return true;
+            }
+            return false;
+        }
+
+        // 1: extract pre- and postfix from all remaining proposals
+        IDocument document= fContentAssistSubjectControlAdapter.getDocument();
+
+        // contains the common postfix in the case that there are any proposals matching our LHS
+        StringBuffer rightCasePostfix;
+        List rightCase= new ArrayList();
+
+        bool isWrongCaseMatch= false;
+
+        // the prefix of all case insensitive matches. This differs from the document
+        // contents and will be replaced.
+        CharSequence wrongCasePrefix= null;
+        int wrongCasePrefixStart= 0;
+        // contains the common postfix of all case-insensitive matches
+        StringBuffer wrongCasePostfix;
+        List wrongCase= new ArrayList();
+
+        for (int i= 0; i < fFilteredProposals.length; i++) {
+            ICompletionProposal proposal= fFilteredProposals[i];
+
+            if (!( cast(ICompletionProposalExtension3)proposal ))
+                return false;
+
+            int start= (cast(ICompletionProposalExtension3)proposal).getPrefixCompletionStart(fContentAssistSubjectControlAdapter.getDocument(), fFilterOffset);
+            CharSequence insertion= (cast(ICompletionProposalExtension3)proposal).getPrefixCompletionText(fContentAssistSubjectControlAdapter.getDocument(), fFilterOffset);
+            if (insertion is null)
+                insertion= new StringCharSequence(proposal.getDisplayString());
+            try {
+                int prefixLength= fFilterOffset - start;
+                int relativeCompletionOffset= Math.min(insertion.length(), prefixLength);
+                String prefix= document.get(start, prefixLength);
+                if (!isWrongCaseMatch && insertion.toString().startsWith(prefix)) {
+                    isWrongCaseMatch= false;
+                    rightCase.add(cast(Object)proposal);
+                    CharSequence newPostfix= insertion.subSequence(relativeCompletionOffset, insertion.length());
+                    if (rightCasePostfix is null)
+                        rightCasePostfix= new StringBuffer(newPostfix.toString());
+                    else
+                        truncatePostfix(rightCasePostfix, newPostfix);
+                } else if (i is 0 || isWrongCaseMatch) {
+                    CharSequence newPrefix= insertion.subSequence(0, relativeCompletionOffset);
+                    if (isPrefixCompatible(wrongCasePrefix, wrongCasePrefixStart, newPrefix, start, document)) {
+                        isWrongCaseMatch= true;
+                        wrongCasePrefix= newPrefix;
+                        wrongCasePrefixStart= start;
+                        CharSequence newPostfix= insertion.subSequence(relativeCompletionOffset, insertion.length());
+                        if (wrongCasePostfix is null)
+                            wrongCasePostfix= new StringBuffer(newPostfix.toString());
+                        else
+                            truncatePostfix(wrongCasePostfix, newPostfix);
+                        wrongCase.add(cast(Object)proposal);
+                    } else {
+                        return false;
+                    }
+                } else
+                    return false;
+            } catch (BadLocationException e2) {
+                // bail out silently
+                return false;
+            }
+
+            if (rightCasePostfix !is null && rightCasePostfix.length() is 0 && rightCase.size() > 1)
+                return false;
+        }
+
+        // 2: replace single proposals
+
+        if (rightCase.size() is 1) {
+            ICompletionProposal proposal= cast(ICompletionProposal) rightCase.get(0);
+            if (canAutoInsert(proposal) && rightCasePostfix.length() > 0) {
+                insertProposal(proposal, cast(wchar) 0, 0, fInvocationOffset);
+                hide();
+                return true;
+            }
+            return false;
+        } else if (isWrongCaseMatch && wrongCase.size() is 1) {
+            ICompletionProposal proposal= cast(ICompletionProposal) wrongCase.get(0);
+            if (canAutoInsert(proposal)) {
+                insertProposal(proposal, cast(wchar) 0, 0, fInvocationOffset);
+                hide();
+            return true;
+            }
+            return false;
+        }
+
+        // 3: replace post- / prefixes
+
+        CharSequence prefix;
+        if (isWrongCaseMatch)
+            prefix= wrongCasePrefix;
+        else
+            prefix= new StringCharSequence("");  //$NON-NLS-1$
+
+        CharSequence postfix;
+        if (isWrongCaseMatch)
+            postfix= new StringCharSequence(wrongCasePostfix.toString);
+        else
+            postfix= new StringCharSequence(rightCasePostfix.toString);
+
+        if (prefix is null || postfix is null)
+            return false;
+
+        try {
+            // 4: check if parts of the postfix are already in the document
+            int to= Math.min(document.getLength(), fFilterOffset + postfix.length());
+            StringBuffer inDocument= new StringBuffer(document.get(fFilterOffset, to - fFilterOffset));
+            truncatePostfix(inDocument, postfix);
+
+            // 5: replace and reveal
+            document.replace(fFilterOffset - prefix.length(), prefix.length() + inDocument.length(), prefix.toString() ~ postfix.toString());
+
+            fContentAssistSubjectControlAdapter.setSelectedRange(fFilterOffset + postfix.length(), 0);
+            fContentAssistSubjectControlAdapter.revealRange(fFilterOffset + postfix.length(), 0);
+            fFilterOffset+= postfix.length();
+            fLastCompletionOffset= fFilterOffset;
+
+            return false;
+        } catch (BadLocationException e) {
+            // ignore and return false
+            return false;
+        }
+    }
+
+    /*
+     * @since 3.1
+     */
+    private bool isPrefixCompatible(CharSequence oneSequence, int oneOffset, CharSequence twoSequence, int twoOffset, IDocument document)  {
+        if (oneSequence is null || twoSequence is null)
+            return true;
+
+        int min= Math.min(oneOffset, twoOffset);
+        int oneEnd= oneOffset + oneSequence.length();
+        int twoEnd= twoOffset + twoSequence.length();
+
+        String one= document.get(oneOffset, min - oneOffset) ~ oneSequence.toString ~ document.get(oneEnd, Math.min(fFilterOffset, fFilterOffset - oneEnd));
+        String two= document.get(twoOffset, min - twoOffset) ~ twoSequence.toString ~ document.get(twoEnd, Math.min(fFilterOffset, fFilterOffset - twoEnd));
+
+        return one.equals(two);
+    }
+
+    /**
+     * Truncates <code>buffer</code> to the common prefix of <code>buffer</code>
+     * and <code>sequence</code>.
+     *
+     * @param buffer the common postfix to truncate
+     * @param sequence the characters to truncate with
+     */
+    private void truncatePostfix(StringBuffer buffer, CharSequence sequence) {
+        // find common prefix
+        int min= Math.min(buffer.length(), sequence.length());
+        for (int c= 0; c < min; c++) {
+            if (sequence.charAt(c) !is buffer.slice()[c]) {
+                buffer.truncate(c);
+                return;
+            }
+        }
+
+        // all equal up to minimum
+        buffer.truncate(min);
+    }
+
+    /**
+     * Sets the message for the repetition affordance text at the bottom of the proposal. Only has
+     * an effect if {@link ContentAssistant#isRepeatedInvocationMode()} returns <code>true</code>.
+     *
+     * @param message the new caption
+     * @since 3.2
+     */
+    void setMessage(String message) {
+        Assert.isNotNull(message);
+        if (isActive() && fMessageText !is null)
+            fMessageText.setText(message ~ " "); //$NON-NLS-1$
+    }
+
+    /**
+     * Sets the text to be displayed if no proposals are available. Only has an effect if
+     * {@link ContentAssistant#isShowEmptyList()} returns <code>true</code>.
+     *
+     * @param message the empty message
+     * @since 3.2
+     */
+    void setEmptyMessage(String message) {
+        Assert.isNotNull(message);
+        fEmptyMessage= message;
+    }
+
+    /**
+     * Enables or disables showing of the caption line. See also {@link #setMessage(String)}.
+     *
+     * @param show
+     * @since 3.2
+     */
+    public void setStatusLineVisible(bool show) {
+        if (!isActive() || show is (fMessageText !is null))
+            return; // nothing to do
+
+        if (show) {
+            createMessageText();
+        } else {
+            fMessageText.dispose();
+            fMessageText= null;
+        }
+        fProposalShell.layout();
+    }
+
+    /**
+     * Informs the popup that it is being placed above the caret line instead of below.
+     *
+     * @param above <code>true</code> if the location of the popup is above the caret line, <code>false</code> if it is below
+     * @since 3.3
+     */
+    void switchedPositionToAbove(bool above) {
+        if (fAdditionalInfoController !is null) {
+            fAdditionalInfoController.setFallbackAnchors([
+                    AbstractInformationControlManager.ANCHOR_RIGHT,
+                    AbstractInformationControlManager.ANCHOR_LEFT,
+                    above ? AbstractInformationControlManager.ANCHOR_TOP : AbstractInformationControlManager.ANCHOR_BOTTOM
+            ]);
+        }
+    }
+
+    /**
+     * Returns a new proposal selection handler.
+     *
+     * @param operationCode the operation code
+     * @return the handler
+     * @since 3.4
+     */
+    IHandler createProposalSelectionHandler(int operationCode) {
+        return new ProposalSelectionHandler(operationCode);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ContentAssistEvent.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Anton Leherbauer (Wind River Systems) - [content assist][api] ContentAssistEvent should contain information about auto activation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=193728
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ContentAssistEvent;
+
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Describes the state that the content assistant is in when completing proposals.
+ * <p>
+ * Clients may use this class.
+ * </p>
+ * 
+ * @since 3.2
+ * @see ICompletionListener
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class ContentAssistEvent {
+    /**
+     * Creates a new event.
+     * 
+     * @param ca the assistant
+     * @param proc the processor
+     * @param isAutoActivated whether content assist was triggered by auto activation
+     * @since 3.4
+     */
+    this(IContentAssistant ca, IContentAssistProcessor proc, bool isAutoActivated) {
+        assistant= ca;
+        processor= proc;
+        this.isAutoActivated= isAutoActivated;
+    }
+
+    /**
+     * Creates a new event.
+     * 
+     * @param ca the assistant
+     * @param proc the processor
+     */
+    this(ContentAssistant ca, IContentAssistProcessor proc) {
+        this(ca, proc, false);
+    }
+
+    /**
+     * The content assistant computing proposals.
+     */
+    public const IContentAssistant assistant;
+    /**
+     * The processor for the current partition.
+     */
+    public const IContentAssistProcessor processor;
+    /**
+     * Tells, whether content assist was triggered by auto activation.
+     * <p>
+     * <strong>Note:</strong> This flag is only valid in {@link ICompletionListener#assistSessionStarted(ContentAssistEvent)}.
+     * </p>
+     * 
+     * @since 3.4
+     */
+    public const bool isAutoActivated;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ContentAssistSubjectControlAdapter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,450 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+
+import dwt.custom.StyledText;
+import dwt.custom.VerifyKeyListener;
+import dwt.events.KeyListener;
+import dwt.events.SelectionListener;
+import dwt.graphics.Point;
+import dwt.widgets.Control;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.contentassist.IContentAssistSubjectControl;
+import dwtx.jface.contentassist.ISubjectControlContextInformationPresenter;
+import dwtx.jface.contentassist.ISubjectControlContextInformationValidator;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IEventConsumer;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension;
+import dwtx.jface.text.contentassist.ContextInformationPopup;
+
+
+/**
+ * This content assist adapter delegates the calls either to
+ * a text viewer or to a content assist subject control.
+ *
+ * @since 3.0
+ */
+final class ContentAssistSubjectControlAdapter : IContentAssistSubjectControl {
+
+    /**
+     * The text viewer which is used as content assist subject control.
+     */
+    private ITextViewer fViewer;
+
+    /**
+     * The content assist subject control.
+     */
+    private IContentAssistSubjectControl fContentAssistSubjectControl;
+
+
+    /**
+     * Creates an adapter for the given content assist subject control.
+     *
+     * @param contentAssistSubjectControl the content assist subject control
+     */
+    this(IContentAssistSubjectControl contentAssistSubjectControl) {
+        Assert.isNotNull(cast(Object)contentAssistSubjectControl);
+        fContentAssistSubjectControl= contentAssistSubjectControl;
+    }
+
+    /**
+     * Creates an adapter for the given text viewer.
+     *
+     * @param viewer the text viewer
+     */
+    public this(ITextViewer viewer) {
+        Assert.isNotNull(cast(Object)viewer);
+        fViewer= viewer;
+    }
+
+    /*
+     * @see IContentAssistSubjectControl#getLineHeight()
+     */
+    public int getLineHeight() {
+        if (fContentAssistSubjectControl !is null)
+            return fContentAssistSubjectControl.getLineHeight();
+
+        return fViewer.getTextWidget().getLineHeight(getCaretOffset());
+    }
+
+    /*
+     * @see IContentAssistSubjectControl#getControl()
+     */
+    public Control getControl() {
+        if (fContentAssistSubjectControl !is null)
+            return fContentAssistSubjectControl.getControl();
+        return fViewer.getTextWidget();
+    }
+
+    /*
+     * @see IContentAssistSubjectControl#getLocationAtOffset(int)
+     */
+    public Point getLocationAtOffset(int offset) {
+        if (fContentAssistSubjectControl !is null)
+            return fContentAssistSubjectControl.getLocationAtOffset(offset);
+        return fViewer.getTextWidget().getLocationAtOffset(offset);
+    }
+
+    /*
+     * @see IContentAssistSubjectControl#getWidgetSelectionRange()
+     */
+    public Point getWidgetSelectionRange() {
+        if (fContentAssistSubjectControl !is null)
+            return fContentAssistSubjectControl.getWidgetSelectionRange();
+        return fViewer.getTextWidget().getSelectionRange();
+    }
+
+    /*
+     * @see IContentAssistSubjectControl#getSelectedRange()
+     */
+    public Point getSelectedRange() {
+        if (fContentAssistSubjectControl !is null)
+            return fContentAssistSubjectControl.getSelectedRange();
+        return fViewer.getSelectedRange();
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#getCaretOffset()
+     */
+    public int getCaretOffset() {
+        if (fContentAssistSubjectControl !is null)
+            return fContentAssistSubjectControl.getCaretOffset();
+        return fViewer.getTextWidget().getCaretOffset();
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#getLineDelimiter()
+     */
+    public String getLineDelimiter() {
+        if (fContentAssistSubjectControl !is null)
+            return fContentAssistSubjectControl.getLineDelimiter();
+        return fViewer.getTextWidget().getLineDelimiter();
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#addKeyListener(dwt.events.KeyListener)
+     */
+    public void addKeyListener(KeyListener keyListener) {
+        if (fContentAssistSubjectControl !is null)
+            fContentAssistSubjectControl.addKeyListener(keyListener);
+        else
+            fViewer.getTextWidget().addKeyListener(keyListener);
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#removeKeyListener(dwt.events.KeyListener)
+     */
+    public void removeKeyListener(KeyListener keyListener) {
+        if (fContentAssistSubjectControl !is null)
+            fContentAssistSubjectControl.removeKeyListener(keyListener);
+        else
+            fViewer.getTextWidget().removeKeyListener(keyListener);
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#getDocument()
+     */
+    public IDocument getDocument() {
+        if (fContentAssistSubjectControl !is null)
+            return fContentAssistSubjectControl.getDocument();
+        return fViewer.getDocument();
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#prependVerifyKeyListener(VerifyKeyListener)
+     */
+    public bool prependVerifyKeyListener(VerifyKeyListener verifyKeyListener) {
+        if (fContentAssistSubjectControl !is null) {
+            return fContentAssistSubjectControl.prependVerifyKeyListener(verifyKeyListener);
+        } else if ( cast(ITextViewerExtension)fViewer ) {
+            ITextViewerExtension e= cast(ITextViewerExtension) fViewer;
+            e.prependVerifyKeyListener(verifyKeyListener);
+            return true;
+        } else {
+
+            StyledText textWidget= fViewer.getTextWidget();
+            if (Helper.okToUse(textWidget)) {
+                textWidget.addVerifyKeyListener(verifyKeyListener);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#appendVerifyKeyListener(dwt.custom.VerifyKeyListener)
+     */
+    public bool appendVerifyKeyListener(VerifyKeyListener verifyKeyListener) {
+        if (fContentAssistSubjectControl !is null)
+            return fContentAssistSubjectControl.appendVerifyKeyListener(verifyKeyListener);
+        else if ( cast(ITextViewerExtension)fViewer ) {
+            ITextViewerExtension extension= cast(ITextViewerExtension)fViewer;
+            extension.appendVerifyKeyListener(verifyKeyListener);
+            return true;
+        } else {
+            StyledText textWidget= fViewer.getTextWidget();
+            if (Helper.okToUse(textWidget)) {
+                textWidget.addVerifyKeyListener(verifyKeyListener);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#removeVerifyKeyListener(dwt.custom.VerifyKeyListener)
+     */
+    public void removeVerifyKeyListener(VerifyKeyListener verifyKeyListener) {
+        if (fContentAssistSubjectControl !is null) {
+            fContentAssistSubjectControl.removeVerifyKeyListener(verifyKeyListener);
+        } else if ( cast(ITextViewerExtension)fViewer ) {
+            ITextViewerExtension extension= cast(ITextViewerExtension) fViewer;
+            extension.removeVerifyKeyListener(verifyKeyListener);
+        } else {
+            StyledText textWidget= fViewer.getTextWidget();
+            if (Helper.okToUse(textWidget))
+                textWidget.removeVerifyKeyListener(verifyKeyListener);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#setEventConsumer(dwtx.jface.text.contentassist.ContentAssistant.InternalListener)
+     */
+    public void setEventConsumer(IEventConsumer eventConsumer) {
+        if (fContentAssistSubjectControl !is null)
+            fContentAssistSubjectControl.setEventConsumer(eventConsumer);
+        else
+            fViewer.setEventConsumer(eventConsumer);
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#setSelectedRange(int, int)
+     */
+    public void setSelectedRange(int i, int j) {
+        if (fContentAssistSubjectControl !is null)
+            fContentAssistSubjectControl.setSelectedRange(i, j);
+        else
+            fViewer.setSelectedRange(i, j);
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#revealRange(int, int)
+     */
+    public void revealRange(int i, int j) {
+        if (fContentAssistSubjectControl !is null)
+            fContentAssistSubjectControl.revealRange(i, j);
+        else
+            fViewer.revealRange(i, j);
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistSubjectControl#canAddVerifyKeyListener()
+     */
+    public bool supportsVerifyKeyListener() {
+        if (fContentAssistSubjectControl !is null)
+            return fContentAssistSubjectControl.supportsVerifyKeyListener();
+        return true;
+    }
+    /**
+     * Returns the characters which when typed by the user should automatically
+     * initiate proposing completions. The position is used to determine the
+     * appropriate content assist processor to invoke.
+     *
+     * @param contentAssistant the content assistant
+     * @param offset a document offset
+     * @return the auto activation characters
+     * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+     */
+    public char[] getCompletionProposalAutoActivationCharacters(ContentAssistant contentAssistant, int offset) {
+        if (fContentAssistSubjectControl !is null)
+            return contentAssistant.getCompletionProposalAutoActivationCharacters(fContentAssistSubjectControl, offset);
+        return contentAssistant.getCompletionProposalAutoActivationCharacters(fViewer, offset);
+    }
+
+    /**
+     * Returns the characters which when typed by the user should automatically
+     * initiate the presentation of context information. The position is used
+     * to determine the appropriate content assist processor to invoke.
+     *
+     * @param contentAssistant the content assistant
+     * @param offset a document offset
+     * @return the auto activation characters
+     *
+     * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters()
+     */
+    char[] getContextInformationAutoActivationCharacters(ContentAssistant contentAssistant, int offset) {
+        if (fContentAssistSubjectControl !is null)
+            return contentAssistant.getContextInformationAutoActivationCharacters(fContentAssistSubjectControl, offset);
+        return contentAssistant.getContextInformationAutoActivationCharacters(fViewer, offset);
+    }
+
+    /**
+    * Creates and returns a completion proposal popup for the given content assistant.
+    *
+    * @param contentAssistant the content assistant
+    * @param controller the additional info controller
+    * @return the completion proposal popup
+    */
+    CompletionProposalPopup createCompletionProposalPopup(ContentAssistant contentAssistant, AdditionalInfoController controller) {
+        if (fContentAssistSubjectControl !is null)
+            return new CompletionProposalPopup(contentAssistant, fContentAssistSubjectControl, controller);
+        return new CompletionProposalPopup(contentAssistant, fViewer, controller);
+
+    }
+
+    /**
+     * Creates and returns a context info popup for the given content assistant.
+     *
+     * @param contentAssistant the content assistant
+     * @return the context info popup or <code>null</code>
+     */
+    ContextInformationPopup createContextInfoPopup(ContentAssistant contentAssistant) {
+        if (fContentAssistSubjectControl !is null)
+            return new ContextInformationPopup(contentAssistant, fContentAssistSubjectControl);
+        return new ContextInformationPopup(contentAssistant, fViewer);
+
+    }
+
+    /**
+     * Returns the context information validator that should be used to
+     * determine when the currently displayed context information should
+     * be dismissed. The position is used to determine the appropriate
+     * content assist processor to invoke.
+     *
+     * @param contentAssistant the content assistant
+     * @param offset a document offset
+     * @return an validator
+     */
+    public IContextInformationValidator getContextInformationValidator(ContentAssistant contentAssistant, int offset) {
+        if (fContentAssistSubjectControl !is null)
+            return contentAssistant.getContextInformationValidator(fContentAssistSubjectControl, offset);
+        return contentAssistant.getContextInformationValidator(fViewer, offset);
+    }
+
+    /**
+     * Returns the context information presenter that should be used to
+     * display context information. The position is used to determine the
+     * appropriate content assist processor to invoke.
+     *
+     * @param contentAssistant the content assistant
+     * @param offset a document offset
+     * @return a presenter
+     */
+    public IContextInformationPresenter getContextInformationPresenter(ContentAssistant contentAssistant, int offset) {
+        if (fContentAssistSubjectControl !is null)
+            return contentAssistant.getContextInformationPresenter(fContentAssistSubjectControl, offset);
+        return contentAssistant.getContextInformationPresenter(fViewer, offset);
+    }
+
+    /**
+     * Installs this adapter's information validator on the given context frame.
+     *
+     * @param frame the context frame
+     */
+    public void installValidator(ContextInformationPopup_ContextFrame frame) {
+        if (fContentAssistSubjectControl !is null) {
+            if (cast(ISubjectControlContextInformationValidator)frame.fValidator )
+                (cast(ISubjectControlContextInformationValidator)frame.fValidator).install(frame.fInformation, fContentAssistSubjectControl, frame.fOffset);
+        } else
+            frame.fValidator.install(frame.fInformation, fViewer, frame.fOffset);
+    }
+
+    /**
+     * Installs this adapter's information presenter on the given context frame.
+     *
+     * @param frame the context frame
+     */
+    public void installContextInformationPresenter(ContextInformationPopup_ContextFrame frame) {
+        if (fContentAssistSubjectControl !is null) {
+            if (cast(ISubjectControlContextInformationPresenter)frame.fPresenter )
+                (cast(ISubjectControlContextInformationPresenter)frame.fValidator).install(frame.fInformation, fContentAssistSubjectControl, frame.fBeginOffset);
+        } else
+            frame.fPresenter.install(frame.fInformation, fViewer, frame.fBeginOffset);
+    }
+
+    /**
+     * Returns an array of context information objects computed based
+     * on the specified document position. The position is used to determine
+     * the appropriate content assist processor to invoke.
+     *
+     * @param contentAssistant the content assistant
+     * @param offset a document offset
+     * @return an array of context information objects
+     * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
+     */
+    public IContextInformation[] computeContextInformation(ContentAssistant contentAssistant, int offset) {
+        if (fContentAssistSubjectControl !is null)
+            return contentAssistant.computeContextInformation(fContentAssistSubjectControl, offset);
+        return contentAssistant.computeContextInformation(fViewer, offset);
+    }
+
+    /*
+     * @see IContentAssistSubjectControl#addSelectionListener(SelectionListener)
+     */
+    public bool addSelectionListener(SelectionListener selectionListener) {
+        if (fContentAssistSubjectControl !is null)
+            return fContentAssistSubjectControl.addSelectionListener(selectionListener);
+        fViewer.getTextWidget().addSelectionListener(selectionListener);
+        return true;
+    }
+
+    /*
+     * @see IContentAssistSubjectControl#removeSelectionListener(SelectionListener)
+     */
+    public void removeSelectionListener(SelectionListener selectionListener) {
+        if (fContentAssistSubjectControl !is null)
+            fContentAssistSubjectControl.removeSelectionListener(selectionListener);
+        else
+            fViewer.getTextWidget().removeSelectionListener(selectionListener);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ContentAssistant.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,2506 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Guy Gurfinkel, guy.g@zend.com - [content assist][api] provide better access to ContentAssistant - https://bugs.eclipse.org/bugs/show_bug.cgi?id=169954
+ *     Anton Leherbauer (Wind River Systems) - [content assist][api] ContentAssistEvent should contain information about auto activation - https://bugs.eclipse.org/bugs/show_bug.cgi?id=193728
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ContentAssistant;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.core.Thread;
+
+import dwt.DWT;
+import dwt.DWTError;
+import dwt.custom.VerifyKeyListener;
+import dwt.events.ControlEvent;
+import dwt.events.ControlListener;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.FocusEvent;
+import dwt.events.FocusListener;
+import dwt.events.KeyAdapter;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.events.TraverseEvent;
+import dwt.events.TraverseListener;
+import dwt.events.VerifyEvent;
+import dwt.graphics.Color;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwt.widgets.Monitor;
+import dwt.widgets.Shell;
+import dwt.widgets.Widget;
+import dwtx.core.commands.IHandler;
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.ListenerList;
+import dwtx.jface.bindings.keys.KeySequence;
+import dwtx.jface.contentassist.IContentAssistSubjectControl;
+import dwtx.jface.contentassist.ISubjectControlContentAssistProcessor;
+import dwtx.jface.dialogs.IDialogSettings;
+import dwtx.jface.preference.JFacePreferences;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentExtension3;
+import dwtx.jface.text.IEventConsumer;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.IViewportListener;
+import dwtx.jface.text.IWidgetTokenKeeper;
+import dwtx.jface.text.IWidgetTokenKeeperExtension;
+import dwtx.jface.text.IWidgetTokenOwner;
+import dwtx.jface.text.IWidgetTokenOwnerExtension;
+import dwtx.jface.text.TextUtilities;
+import dwtx.jface.util.Geometry;
+
+
+/**
+ * The standard implementation of the <code>IContentAssistant</code> interface. Usually, clients
+ * instantiate this class and configure it before using it.
+ */
+public class ContentAssistant : IContentAssistant, IContentAssistantExtension, IContentAssistantExtension2, IContentAssistantExtension3, IContentAssistantExtension4, IWidgetTokenKeeper, IWidgetTokenKeeperExtension {
+
+
+
+    /**
+     * Content assist command identifier for 'select next proposal'.
+     *
+     * @since 3.4
+     */
+    public static const String SELECT_NEXT_PROPOSAL_COMMAND_ID= "dwtx.ui.edit.text.contentAssist.selectNextProposal"; //$NON-NLS-1$
+    /**
+     * Content assist command identifier for 'select previous proposal'.
+     *
+     * @since 3.4
+     */
+    public static const String SELECT_PREVIOUS_PROPOSAL_COMMAND_ID= "dwtx.ui.edit.text.contentAssist.selectPreviousProposal"; //$NON-NLS-1$
+
+
+    /**
+     * A generic closer class used to monitor various interface events in order to determine whether
+     * content-assist should be terminated and all associated windows closed.
+     */
+    class Closer : ControlListener, MouseListener, FocusListener, DisposeListener, IViewportListener {
+
+        /** The shell that a <code>ControlListener</code> is registered with. */
+        private Shell fShell;
+        /**
+         * The control that a <code>MouseListener</code>, a<code>FocusListener</code> and a
+         * <code>DisposeListener</code> are registered with.
+         */
+        private Control fControl;
+
+        /**
+         * Installs this closer on it's viewer's text widget.
+         */
+        protected void install() {
+            Control control= fContentAssistSubjectControlAdapter.getControl();
+            fControl= control;
+            if (Helper.okToUse(control)) {
+
+                Shell shell= control.getShell();
+                fShell= shell;
+                shell.addControlListener(this);
+
+                control.addMouseListener(this);
+                control.addFocusListener(this);
+
+                /*
+                 * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of
+                 * Internal Errors
+                 */
+                control.addDisposeListener(this);
+            }
+            if (fViewer !is null)
+                fViewer.addViewportListener(this);
+        }
+
+        /**
+         * Uninstalls this closer from the viewer's text widget.
+         */
+        protected void uninstall() {
+            Control shell= fShell;
+            fShell= null;
+            if (Helper.okToUse(shell))
+                shell.removeControlListener(this);
+
+            Control control= fControl;
+            fControl= null;
+            if (Helper.okToUse(control)) {
+
+                control.removeMouseListener(this);
+                control.removeFocusListener(this);
+
+                /*
+                 * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of
+                 * Internal Errors
+                 */
+                control.removeDisposeListener(this);
+            }
+
+            if (fViewer !is null)
+                fViewer.removeViewportListener(this);
+        }
+
+        /*
+         * @see ControlListener#controlResized(ControlEvent)
+         */
+        public void controlResized(ControlEvent e) {
+            hide();
+        }
+
+        /*
+         * @see ControlListener#controlMoved(ControlEvent)
+         */
+        public void controlMoved(ControlEvent e) {
+            hide();
+        }
+
+        /*
+         * @see MouseListener#mouseDown(MouseEvent)
+         */
+        public void mouseDown(MouseEvent e) {
+            hide();
+        }
+
+        /*
+         * @see MouseListener#mouseUp(MouseEvent)
+         */
+        public void mouseUp(MouseEvent e) {
+        }
+
+        /*
+         * @see MouseListener#mouseDoubleClick(MouseEvent)
+         */
+        public void mouseDoubleClick(MouseEvent e) {
+            hide();
+        }
+
+        /*
+         * @see FocusListener#focusGained(FocusEvent)
+         */
+        public void focusGained(FocusEvent e) {
+        }
+
+        /*
+         * @see FocusListener#focusLost(FocusEvent)
+         */
+        public void focusLost(FocusEvent e) {
+            Control control= fControl;
+            if (Helper.okToUse(control)) {
+                Display d= control.getDisplay();
+                if (d !is null) {
+                    d.asyncExec(new class()  Runnable {
+                        public void run() {
+                            if (!fProposalPopup.hasFocus() && (fContextInfoPopup is null || !fContextInfoPopup.hasFocus()))
+                                hide();
+                        }
+                    });
+                }
+            }
+        }
+
+        /*
+         * @seeDisposeListener#widgetDisposed(DisposeEvent)
+         */
+        public void widgetDisposed(DisposeEvent e) {
+            /*
+             * 1GGYYWK: ITPJUI:ALL - Dismissing editor with code assist up causes lots of Internal
+             * Errors
+             */
+            hide();
+        }
+
+        /*
+         * @see IViewportListener#viewportChanged(int)
+         */
+        public void viewportChanged(int topIndex) {
+            hide();
+        }
+    }
+
+    /**
+     * An implementation of <code>IContentAssistListener</code>, this class is used to monitor
+     * key events in support of automatic activation of the content assistant. If enabled, the
+     * implementation utilizes a thread to watch for input characters matching the activation
+     * characters specified by the content assist processor, and if detected, will wait the
+     * indicated delay interval before activating the content assistant.
+     *
+     * @since 3.4 protected, was added in 2.1 as private class
+     */
+    protected class AutoAssistListener : KeyAdapter , KeyListener, Runnable, VerifyKeyListener {
+
+        private Thread fThread;
+        private bool fIsReset= false;
+        private Object fMutex= new Object();
+        private int fShowStyle;
+
+        private const static int SHOW_PROPOSALS= 1;
+        private const static int SHOW_CONTEXT_INFO= 2;
+
+        protected this() {
+        }
+
+        protected void start(int showStyle) {
+            fShowStyle= showStyle;
+            fThread= new Thread(&run);
+            fThread.name = JFaceTextMessages.getString("ContentAssistant.assist_delay_timer_name"); //$NON-NLS-1$
+            fThread.start();
+        }
+
+        public void run() {
+            try {
+                while (true) {
+                    synchronized (fMutex) {
+                        if (fAutoActivationDelay !is 0)
+                            fMutex.wait(fAutoActivationDelay);
+                        if (fIsReset) {
+                            fIsReset= false;
+                            continue;
+                        }
+                    }
+                    showAssist(fShowStyle);
+                    break;
+                }
+            } catch (InterruptedException e) {
+            }
+            fThread= null;
+        }
+
+        protected void reset(int showStyle) {
+            synchronized (fMutex) {
+                fShowStyle= showStyle;
+                fIsReset= true;
+                fMutex.notifyAll();
+            }
+        }
+
+        protected void stop() {
+            Thread threadToStop= fThread;
+            if (threadToStop !is null && threadToStop.isAlive())
+                threadToStop.interrupt();
+        }
+
+        private bool contains(char[] characters, char character) {
+            if (characters !is null) {
+                for (int i= 0; i < characters.length; i++) {
+                    if (character is characters[i])
+                        return true;
+                }
+            }
+            return false;
+        }
+
+        public void keyPressed(KeyEvent e) {
+            // Only act on typed characters and ignore modifier-only events
+            if (e.character is 0 && (e.keyCode & DWT.KEYCODE_BIT) is 0)
+                return;
+
+            if (e.character !is 0 && (e.stateMask is DWT.ALT))
+                return;
+
+            // Only act on characters that are trigger candidates. This
+            // avoids computing the model selection on every keystroke
+            if (computeAllAutoActivationTriggers().indexOf(e.character) < 0) {
+                stop();
+                return;
+            }
+
+            int showStyle;
+            int pos= fContentAssistSubjectControlAdapter.getSelectedRange().x;
+            char[] activation;
+
+            activation= fContentAssistSubjectControlAdapter.getCompletionProposalAutoActivationCharacters(this.outer, pos);
+
+            if (contains(activation, e.character) && !isProposalPopupActive())
+                showStyle= SHOW_PROPOSALS;
+            else {
+                activation= fContentAssistSubjectControlAdapter.getContextInformationAutoActivationCharacters(this.outer, pos);
+                if (contains(activation, e.character) && !isContextInfoPopupActive())
+                    showStyle= SHOW_CONTEXT_INFO;
+                else {
+                    stop();
+                    return;
+                }
+            }
+
+            if (fThread !is null && fThread.isAlive())
+                reset(showStyle);
+            else
+                start(showStyle);
+        }
+
+        /*
+         * @see dwt.custom.VerifyKeyListener#verifyKey(dwt.events.VerifyEvent)
+         */
+        public void verifyKey(VerifyEvent event) {
+            keyPressed(event);
+        }
+
+        protected void showAssist(int showStyle) {
+            final Control control= fContentAssistSubjectControlAdapter.getControl();
+            if (control is null)
+                return;
+
+            final Display d= control.getDisplay();
+            if (d is null)
+                return;
+
+            try {
+                d.syncExec(new class()  Runnable {
+                    public void run() {
+                        if (isProposalPopupActive())
+                            return;
+
+                        if (control.isDisposed() || !control.isFocusControl())
+                            return;
+
+                        if (showStyle is SHOW_PROPOSALS) {
+                            if (!prepareToShowCompletions(true))
+                                return;
+                            fProposalPopup.showProposals(true);
+                            fLastAutoActivation= System.currentTimeMillis();
+                        } else if (showStyle is SHOW_CONTEXT_INFO && fContextInfoPopup !is null) {
+                            promoteKeyListener();
+                            fContextInfoPopup.showContextProposals(true);
+                        }
+                    }
+                });
+            } catch (DWTError e) {
+            }
+        }
+    }
+
+    /**
+     * The layout manager layouts the various windows associated with the content assistant based on
+     * the settings of the content assistant.
+     */
+    class LayoutManager : Listener {
+
+        // Presentation types.
+        /** The presentation type for the proposal selection popup. */
+        public const static int LAYOUT_PROPOSAL_SELECTOR= 0;
+        /** The presentation type for the context selection popup. */
+        public const static int LAYOUT_CONTEXT_SELECTOR= 1;
+        /** The presentation type for the context information hover . */
+        public const static int LAYOUT_CONTEXT_INFO_POPUP= 2;
+
+        int fContextType= LAYOUT_CONTEXT_SELECTOR;
+        Shell[] fShells= new Shell[3];
+        Object[] fPopups= new Object[3];
+
+        protected void add(Object popup, Shell shell, int type, int offset) {
+            Assert.isNotNull(popup);
+            Assert.isTrue(shell !is null && !shell.isDisposed());
+            checkType(type);
+
+            if (fShells[type] !is shell) {
+                if (fShells[type] !is null)
+                    fShells[type].removeListener(DWT.Dispose, this);
+                shell.addListener(DWT.Dispose, this);
+                fShells[type]= shell;
+            }
+
+            fPopups[type]= popup;
+            if (type is LAYOUT_CONTEXT_SELECTOR || type is LAYOUT_CONTEXT_INFO_POPUP)
+                fContextType= type;
+
+            layout(type, offset);
+            adjustListeners(type);
+        }
+
+        protected void checkType(int type) {
+            Assert.isTrue(type is LAYOUT_PROPOSAL_SELECTOR ||
+                type is LAYOUT_CONTEXT_SELECTOR || type is LAYOUT_CONTEXT_INFO_POPUP);
+        }
+
+        public void handleEvent(Event event) {
+            Widget source= event.widget;
+            source.removeListener(DWT.Dispose, this);
+
+            int type= getShellType(source);
+            checkType(type);
+            fShells[type]= null;
+
+            switch (type) {
+                case LAYOUT_PROPOSAL_SELECTOR:
+                    if (fContextType is LAYOUT_CONTEXT_SELECTOR &&
+                            Helper.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR])) {
+                        // Restore event notification to the tip popup.
+                        addContentAssistListener(cast(IContentAssistListener) fPopups[LAYOUT_CONTEXT_SELECTOR], CONTEXT_SELECTOR);
+                    }
+                    break;
+
+                case LAYOUT_CONTEXT_SELECTOR:
+                    if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
+                        if (fProposalPopupOrientation is PROPOSAL_STACKED)
+                            layout(LAYOUT_PROPOSAL_SELECTOR, getSelectionOffset());
+                        // Restore event notification to the proposal popup.
+                        addContentAssistListener(cast(IContentAssistListener) fPopups[LAYOUT_PROPOSAL_SELECTOR], PROPOSAL_SELECTOR);
+                    }
+                    fContextType= LAYOUT_CONTEXT_INFO_POPUP;
+                    break;
+
+                case LAYOUT_CONTEXT_INFO_POPUP:
+                    if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
+                        if (fContextInfoPopupOrientation is CONTEXT_INFO_BELOW)
+                            layout(LAYOUT_PROPOSAL_SELECTOR, getSelectionOffset());
+                    }
+                    fContextType= LAYOUT_CONTEXT_SELECTOR;
+                    break;
+            }
+        }
+
+        protected int getShellType(Widget shell) {
+            for (int i= 0; i < fShells.length; i++) {
+                if (fShells[i] is shell)
+                    return i;
+            }
+            return -1;
+        }
+
+        /**
+         * Layouts the popup defined by <code>type</code> at the given widget offset.
+         *
+         * @param type the kind of popup to layout
+         * @param offset the widget offset
+         */
+        protected void layout(int type, int offset) {
+            switch (type) {
+                case LAYOUT_PROPOSAL_SELECTOR:
+                    layoutProposalSelector(offset);
+                    break;
+                case LAYOUT_CONTEXT_SELECTOR:
+                    layoutContextSelector(offset);
+                    break;
+                case LAYOUT_CONTEXT_INFO_POPUP:
+                    layoutContextInfoPopup(offset);
+                    break;
+            }
+        }
+
+        protected void layoutProposalSelector(int offset) {
+            if (fContextType is LAYOUT_CONTEXT_INFO_POPUP &&
+                    fContextInfoPopupOrientation is CONTEXT_INFO_BELOW &&
+                    Helper.okToUse(fShells[LAYOUT_CONTEXT_INFO_POPUP])) {
+                // Stack proposal selector beneath the tip box.
+                Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                Shell parent= fShells[LAYOUT_CONTEXT_INFO_POPUP];
+                shell.setLocation(getStackedLocation(shell, parent));
+            } else if (fContextType !is LAYOUT_CONTEXT_SELECTOR ||
+                        !Helper.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR])) {
+                // There are no other presentations to be concerned with,
+                // so place the proposal selector beneath the cursor line.
+                Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                CompletionProposalPopup popup= cast(CompletionProposalPopup) fPopups[LAYOUT_PROPOSAL_SELECTOR];
+                shell.setBounds(computeBoundsBelowAbove(shell, shell.getSize(), offset, popup));
+            } else {
+                CompletionProposalPopup popup= (cast(CompletionProposalPopup) fPopups[LAYOUT_PROPOSAL_SELECTOR]);
+                switch (fProposalPopupOrientation) {
+                    case PROPOSAL_REMOVE: {
+                        // Remove the tip selector and place the
+                        // proposal selector beneath the cursor line.
+                        fShells[LAYOUT_CONTEXT_SELECTOR].dispose();
+                        Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                        shell.setBounds(computeBoundsBelowAbove(shell, shell.getSize(), offset, popup));
+                        break;
+                    }
+                    case PROPOSAL_OVERLAY: {
+                        // Overlay the tip selector with the proposal selector.
+                        Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                        shell.setBounds(computeBoundsBelowAbove(shell, shell.getSize(), offset, popup));
+                        break;
+                    }
+                    case PROPOSAL_STACKED: {
+                        // Stack the proposal selector beneath the tip selector.
+                        Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                        Shell parent= fShells[LAYOUT_CONTEXT_SELECTOR];
+                        shell.setLocation(getStackedLocation(shell, parent));
+                        break;
+                    }
+                }
+            }
+        }
+
+        protected void layoutContextSelector(int offset) {
+            // Always place the context selector beneath the cursor line.
+            Shell shell= fShells[LAYOUT_CONTEXT_SELECTOR];
+            shell.setBounds(computeBoundsBelowAbove(shell, shell.getSize(), offset, null));
+
+            if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
+                switch (fProposalPopupOrientation) {
+                    case PROPOSAL_REMOVE:
+                        // Remove the proposal selector.
+                        fShells[LAYOUT_PROPOSAL_SELECTOR].dispose();
+                        break;
+
+                    case PROPOSAL_OVERLAY:
+                        // The proposal selector has been overlaid by the tip selector.
+                        break;
+
+                    case PROPOSAL_STACKED: {
+                        // Stack the proposal selector beneath the tip selector.
+                        shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                        Shell parent= fShells[LAYOUT_CONTEXT_SELECTOR];
+                        shell.setLocation(getStackedLocation(shell, parent));
+                        break;
+                    }
+                }
+            }
+        }
+
+        protected void layoutContextInfoPopup(int offset) {
+            switch (fContextInfoPopupOrientation) {
+                case CONTEXT_INFO_ABOVE: {
+                    // Place the popup above the cursor line.
+                    Shell shell= fShells[LAYOUT_CONTEXT_INFO_POPUP];
+                    shell.setBounds(computeBoundsAboveBelow(shell, shell.getSize(), offset));
+                    break;
+                }
+                case CONTEXT_INFO_BELOW: {
+                    // Place the popup beneath the cursor line.
+                    Shell parent= fShells[LAYOUT_CONTEXT_INFO_POPUP];
+                    parent.setBounds(computeBoundsBelowAbove(parent, parent.getSize(), offset, null));
+                    if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR])) {
+                        // Stack the proposal selector beneath the context info popup.
+                        Shell shell= fShells[LAYOUT_PROPOSAL_SELECTOR];
+                        shell.setLocation(getStackedLocation(shell, parent));
+                    }
+                    break;
+                }
+            }
+        }
+
+        /**
+         * Moves <code>point</code> such that <code>rectangle</code> does not bleed outside of
+         * <code>bounds</code>. All coordinates must have the same reference.
+         *
+         * @param point the point to move if needed
+         * @param shellSize the size of the shell that may be moved
+         * @param bounds the bounds
+         * @since 3.3
+         */
+        protected void constrainLocation(Point point, Point shellSize, Rectangle bounds) {
+            if (point.x + shellSize.x > bounds.x + bounds.width)
+                point.x= bounds.x + bounds.width - shellSize.x;
+
+            if (point.x < bounds.x)
+                point.x= bounds.x;
+
+            if (point.y + shellSize.y > bounds.y + bounds.height)
+                point.y= bounds.y + bounds.height - shellSize.y;
+
+            if (point.y < bounds.y)
+                point.y= bounds.y;
+        }
+
+        protected Rectangle constrainHorizontally(Rectangle rect, Rectangle bounds) {
+            // clip width
+            if (rect.width > bounds.width)
+                rect.width= bounds.width;
+
+            if (rect.x + rect.width > bounds.x + bounds.width)
+                rect.x= bounds.x + bounds.width - rect.width;
+            if (rect.x < bounds.x)
+                rect.x= bounds.x;
+
+            return rect;
+        }
+
+        /**
+         * Returns the display bounds for <code>shell</code> such that it appears right above
+         * <code>offset</code>, or below it if above is not suitable. The returned bounds lie
+         * within the monitor at the caret location and never overlap with the caret line.
+         *
+         * @param shell the shell to compute the placement for
+         * @param preferred the preferred size for <code>shell</code>
+         * @param offset the caret offset in the subject control
+         * @return the point right above <code>offset</code> in display coordinates
+         * @since 3.3
+         */
+        protected Rectangle computeBoundsAboveBelow(Shell shell, Point preferred, int offset) {
+            Control subjectControl= fContentAssistSubjectControlAdapter.getControl();
+            Display display= subjectControl.getDisplay();
+            Rectangle caret= getCaretRectangle(offset);
+            Monitor monitor= getClosestMonitor(display, caret);
+            Rectangle bounds= monitor.getClientArea();
+            Geometry.moveInside(caret, bounds);
+
+            int spaceAbove= caret.y - bounds.y;
+            int caretLowerY= caret.y + caret.height;
+            int spaceBelow= bounds.y + bounds.height - caretLowerY;
+            Rectangle rect;
+            if (spaceAbove >= preferred.y)
+                rect= new Rectangle(caret.x, caret.y - preferred.y, preferred.x, preferred.y);
+            else if (spaceBelow >= preferred.y)
+                rect= new Rectangle(caret.x, caretLowerY, preferred.x, preferred.y);
+            // we can't fit in the preferred size - squeeze into larger area
+            else if (spaceBelow <= spaceAbove)
+                rect= new Rectangle(caret.x, bounds.y, preferred.x, spaceAbove);
+            else
+                rect= new Rectangle(caret.x, caretLowerY, preferred.x, spaceBelow);
+
+            return constrainHorizontally(rect, bounds);
+        }
+        package Rectangle computeBoundsAboveBelow_package(Shell shell, Point preferred, int offset) {
+            return computeBoundsAboveBelow(shell, preferred, offset);
+        }
+
+        /**
+         * Returns the display bounds for <code>shell</code> such that it appears right below
+         * <code>offset</code>, or above it if below is not suitable. The returned bounds lie
+         * within the monitor at the caret location and never overlap with the caret line.
+         *
+         * @param shell the shell to compute the placement for
+         * @param preferred the preferred size for <code>shell</code>
+         * @param offset the caret offset in the subject control
+         * @param popup a popup to inform if the location was switched to above, <code>null</code> to do nothing
+         * @return the point right below <code>offset</code> in display coordinates
+         * @since 3.3
+         */
+        protected Rectangle computeBoundsBelowAbove(Shell shell, Point preferred, int offset, CompletionProposalPopup popup) {
+            Control subjectControl= fContentAssistSubjectControlAdapter.getControl();
+            Display display= subjectControl.getDisplay();
+            Rectangle caret= getCaretRectangle(offset);
+            Monitor monitor= getClosestMonitor(display, caret);
+            Rectangle bounds= monitor.getClientArea();
+            Geometry.moveInside(caret, bounds);
+
+            int threshold= popup is null ? Integer.MAX_VALUE : popup.getMinimalHeight();
+            int spaceAbove= caret.y - bounds.y;
+            int spaceBelow= bounds.y + bounds.height - (caret.y + caret.height);
+            Rectangle rect;
+            bool switched= false;
+            if (spaceBelow >= preferred.y)
+                rect= new Rectangle(caret.x, caret.y + caret.height, preferred.x, preferred.y);
+            // squeeze in below if we have at least threshold space
+            else if (spaceBelow >= threshold)
+                rect= new Rectangle(caret.x, caret.y + caret.height, preferred.x, spaceBelow);
+            else if (spaceAbove >= preferred.y) {
+                rect= new Rectangle(caret.x, caret.y - preferred.y, preferred.x, preferred.y);
+                switched= true;
+            } else if (spaceBelow >= spaceAbove) {
+                // we can't fit in the preferred size - squeeze into larger area
+                rect= new Rectangle(caret.x, caret.y + caret.height, preferred.x, spaceBelow);
+            } else {
+                rect= new Rectangle(caret.x, bounds.y, preferred.x, spaceAbove);
+                switched= true;
+            }
+
+            if (popup !is null)
+                popup.switchedPositionToAbove(switched);
+
+            return constrainHorizontally(rect, bounds);
+        }
+        package Rectangle computeBoundsBelowAbove_package(Shell shell, Point preferred, int offset, CompletionProposalPopup popup) {
+            return computeBoundsBelowAbove(shell, preferred, offset, popup );
+        }
+
+        private Rectangle getCaretRectangle(int offset) {
+            Point location= fContentAssistSubjectControlAdapter.getLocationAtOffset(offset);
+            Control subjectControl= fContentAssistSubjectControlAdapter.getControl();
+            Point controlSize= subjectControl.getSize();
+            constrainLocation(location, new Point(0, 0), new Rectangle(0, 0, controlSize.x, controlSize.y));
+            location= subjectControl.toDisplay(location);
+            Rectangle subjectRectangle= new Rectangle(location.x, location.y, 1, fContentAssistSubjectControlAdapter.getLineHeight());
+            return subjectRectangle;
+        }
+
+        protected Point getStackedLocation(Shell shell, Shell parent) {
+            Point p= parent.getLocation();
+            Point size= parent.getSize();
+            p.x += size.x / 4;
+            p.y += size.y;
+
+            p= parent.toDisplay(p);
+
+            Point shellSize= shell.getSize();
+            Monitor monitor= getClosestMonitor(parent.getDisplay(), new Rectangle(p.x, p.y, 0, 0));
+            Rectangle displayBounds= monitor.getClientArea();
+            constrainLocation(p, shellSize, displayBounds);
+
+            return p;
+        }
+
+        protected void adjustListeners(int type) {
+            switch (type) {
+                case LAYOUT_PROPOSAL_SELECTOR:
+                    if (fContextType is LAYOUT_CONTEXT_SELECTOR &&
+                            Helper.okToUse(fShells[LAYOUT_CONTEXT_SELECTOR]))
+                        // Disable event notification to the tip selector.
+                        removeContentAssistListener(cast(IContentAssistListener) fPopups[LAYOUT_CONTEXT_SELECTOR], CONTEXT_SELECTOR);
+                    break;
+                case LAYOUT_CONTEXT_SELECTOR:
+                    if (Helper.okToUse(fShells[LAYOUT_PROPOSAL_SELECTOR]))
+                        // Disable event notification to the proposal selector.
+                        removeContentAssistListener(cast(IContentAssistListener) fPopups[LAYOUT_PROPOSAL_SELECTOR], PROPOSAL_SELECTOR);
+                    break;
+                case LAYOUT_CONTEXT_INFO_POPUP:
+                    break;
+            }
+        }
+
+        /**
+         * Copied from dwtx.jface.window.Window.
+         * Returns the monitor whose client area contains the given point. If no
+         * monitor contains the point, returns the monitor that is closest to the
+         * point. If this is ever made public, it should be moved into a separate
+         * utility class.
+         *
+         * @param toSearch
+         *            point to find (display coordinates)
+         * @param rectangle
+         *            rectangle to find (display coordinates)
+         * @return the monitor closest to the given point
+         * @since 3.3
+         */
+        private Monitor getClosestMonitor(Display toSearch, Rectangle rectangle) {
+            int closest = Integer.MAX_VALUE;
+
+            Point toFind= Geometry.centerPoint(rectangle);
+            Monitor[] monitors = toSearch.getMonitors();
+            Monitor result = monitors[0];
+
+            for (int idx = 0; idx < monitors.length; idx++) {
+                Monitor current = monitors[idx];
+
+                Rectangle clientArea = current.getClientArea();
+
+                if (clientArea.contains(toFind)) {
+                    return current;
+                }
+
+                int distance = Geometry.distanceSquared(Geometry.centerPoint(clientArea), toFind);
+                if (distance < closest) {
+                    closest = distance;
+                    result = current;
+                }
+            }
+
+            return result;
+        }
+    }
+
+    /**
+     * Internal key listener and event consumer.
+     */
+    class InternalListener : VerifyKeyListener, IEventConsumer {
+
+        /**
+         * Verifies key events by notifying the registered listeners. Each listener is allowed to
+         * indicate that the event has been handled and should not be further processed.
+         *
+         * @param e the verify event
+         * @see VerifyKeyListener#verifyKey(dwt.events.VerifyEvent)
+         */
+        public void verifyKey(VerifyEvent e) {
+            IContentAssistListener[] listeners= arraycast!(IContentAssistListener)( fListeners.clone() );
+            for (int i= 0; i < listeners.length; i++) {
+                if (listeners[i] !is null) {
+                    if (!listeners[i].verifyKey(e) || !e.doit)
+                        break;
+                }
+            }
+            if (fAutoAssistListener !is null)
+                fAutoAssistListener.keyPressed(e);
+        }
+
+        /*
+         * @see IEventConsumer#processEvent
+         */
+        public void processEvent(VerifyEvent event) {
+
+            installKeyListener();
+
+            IContentAssistListener[] listeners= arraycast!(IContentAssistListener)( fListeners.clone() );
+            for (int i= 0; i < listeners.length; i++) {
+                if (listeners[i] !is null) {
+                    listeners[i].processEvent(event);
+                    if (!event.doit)
+                        return;
+                }
+            }
+        }
+    }
+
+    /**
+     * Dialog store constants.
+     *
+     * @since 3.0
+     */
+    public static const String STORE_SIZE_X= "size.x"; //$NON-NLS-1$
+    public static const String STORE_SIZE_Y= "size.y"; //$NON-NLS-1$
+
+    // Content-Assist Listener types
+    final static int CONTEXT_SELECTOR= 0;
+    final static int PROPOSAL_SELECTOR= 1;
+    final static int CONTEXT_INFO_POPUP= 2;
+
+    /**
+     * The popup priority: &gt; linked position proposals and hover pop-ups. Default value:
+     * <code>20</code>;
+     *
+     * @since 3.0
+     */
+    public static const int WIDGET_PRIORITY= 20;
+
+    private static const int DEFAULT_AUTO_ACTIVATION_DELAY= 500;
+
+    private IInformationControlCreator fInformationControlCreator;
+    private int fAutoActivationDelay= DEFAULT_AUTO_ACTIVATION_DELAY;
+    private bool fIsAutoActivated= false;
+    private bool fIsAutoInserting= false;
+    private int fProposalPopupOrientation= PROPOSAL_OVERLAY;
+    private int fContextInfoPopupOrientation= CONTEXT_INFO_ABOVE;
+    private Map fProcessors;
+
+    /**
+     * The partitioning.
+     *
+     * @since 3.0
+     */
+    private String fPartitioning;
+
+    private Color fContextInfoPopupBackground;
+    private Color fContextInfoPopupForeground;
+    private Color fContextSelectorBackground;
+    private Color fContextSelectorForeground;
+    private Color fProposalSelectorBackground;
+    private Color fProposalSelectorForeground;
+
+    private ITextViewer fViewer;
+    private String fLastErrorMessage;
+
+    private Closer fCloser;
+    LayoutManager fLayoutManager;
+    private AutoAssistListener fAutoAssistListener;
+    private InternalListener fInternalListener;
+    private CompletionProposalPopup fProposalPopup;
+    private ContextInformationPopup fContextInfoPopup;
+
+    /**
+     * Flag which tells whether a verify key listener is hooked.
+     *
+     * @since 3.0
+     */
+    private bool fVerifyKeyListenerHooked= false;
+    private IContentAssistListener[] fListeners;
+    /**
+     * The content assist subject control.
+     *
+     * @since 3.0
+     */
+    private IContentAssistSubjectControl fContentAssistSubjectControl;
+    /**
+     * The content assist subject control's shell.
+     *
+     * @since 3.2
+     */
+    private Shell fContentAssistSubjectControlShell;
+    /**
+     * The content assist subject control's shell traverse listener.
+     *
+     * @since 3.2
+     */
+    private TraverseListener fCASCSTraverseListener;
+    /**
+     * The content assist subject control adapter.
+     *
+     * @since 3.0
+     */
+    private ContentAssistSubjectControlAdapter fContentAssistSubjectControlAdapter;
+    /**
+     * The dialog settings for the control's bounds.
+     *
+     * @since 3.0
+     */
+    private IDialogSettings fDialogSettings;
+    /**
+     * Prefix completion setting.
+     *
+     * @since 3.0
+     */
+    private bool fIsPrefixCompletionEnabled= false;
+    /**
+     * The list of completion listeners.
+     *
+     * @since 3.2
+     */
+    private ListenerList fCompletionListeners;
+    /**
+     * The message to display at the bottom of the proposal popup.
+     *
+     * @since 3.2
+     */
+    private String fMessage= ""; //$NON-NLS-1$
+    /**
+     * The cycling mode property.
+     *
+     * @since 3.2
+     */
+    private bool fIsRepetitionMode= false;
+    /**
+     * The show empty property.
+     *
+     * @since 3.2
+     */
+    private bool fShowEmptyList= false;
+    /**
+     * The message line property.
+     *
+     * @since 3.2
+     */
+    private bool fIsStatusLineVisible;
+    /**
+     * The last system time when auto activation performed.
+     *
+     * @since 3.2
+     */
+    private long fLastAutoActivation= Long.MIN_VALUE;
+    /**
+     * The iteration key sequence to listen for, or <code>null</code>.
+     *
+     * @since 3.2
+     */
+    private KeySequence fRepeatedInvocationKeySequence;
+
+    /**
+     * Maps handler to command identifiers.
+     *
+     * @since 3.4
+     */
+    private Map fHandlers;
+
+    /**
+     * Tells whether colored labels support is enabled.
+     *
+     * @since 3.4
+     */
+    private bool fIsColoredLabelsSupportEnabled= false;
+
+
+    /**
+     * Creates a new content assistant. The content assistant is not automatically activated,
+     * overlays the completion proposals with context information list if necessary, and shows the
+     * context information above the location at which it was activated. If auto activation will be
+     * enabled, without further configuration steps, this content assistant is activated after a 500
+     * milliseconds delay. It uses the default partitioning.
+     */
+    public this() {
+        fListeners= new IContentAssistListener[4];
+        fCompletionListeners= new ListenerList(ListenerList.IDENTITY);
+        fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING;
+    }
+
+    /**
+     * Sets the document partitioning this content assistant is using.
+     *
+     * @param partitioning the document partitioning for this content assistant
+     * @since 3.0
+     */
+    public void setDocumentPartitioning(String partitioning) {
+        Assert.isNotNull(partitioning);
+        fPartitioning= partitioning;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistantExtension#getDocumentPartitioning()
+     * @since 3.0
+     */
+    public String getDocumentPartitioning() {
+        return fPartitioning;
+    }
+
+    /**
+     * Registers a given content assist processor for a particular content type. If there is already
+     * a processor registered for this type, the new processor is registered instead of the old one.
+     *
+     * @param processor the content assist processor to register, or <code>null</code> to remove
+     *        an existing one
+     * @param contentType the content type under which to register
+     */
+    public void setContentAssistProcessor(IContentAssistProcessor processor, String contentType) {
+
+        Assert.isNotNull(contentType);
+
+        if (fProcessors is null)
+            fProcessors= new HashMap();
+
+        if (processor is null)
+            fProcessors.remove(contentType);
+        else
+            fProcessors.put(contentType, processor);
+    }
+
+    /*
+     * @see IContentAssistant#getContentAssistProcessor
+     */
+    public IContentAssistProcessor getContentAssistProcessor(String contentType) {
+        if (fProcessors is null)
+            return null;
+
+        return cast(IContentAssistProcessor) fProcessors.get(contentType);
+    }
+
+    /**
+     * Computes the sorted set of all auto activation trigger characters.
+     *
+     * @return the sorted set of all auto activation trigger characters
+     * @since 3.1
+     */
+    private String computeAllAutoActivationTriggers() {
+        if (fProcessors is null)
+            return ""; //$NON-NLS-1$
+
+        StringBuffer buf= new StringBuffer(5);
+        Iterator iter= fProcessors.entrySet().iterator();
+        while (iter.hasNext()) {
+            Entry entry= cast(Entry) iter.next();
+            IContentAssistProcessor processor= cast(IContentAssistProcessor) entry.getValue();
+            char[] triggers= processor.getCompletionProposalAutoActivationCharacters();
+            if (triggers !is null)
+                buf.append(triggers);
+            triggers= processor.getContextInformationAutoActivationCharacters();
+            if (triggers !is null)
+                buf.append(triggers);
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Enables the content assistant's auto activation mode.
+     *
+     * @param enabled indicates whether auto activation is enabled or not
+     */
+    public void enableAutoActivation(bool enabled) {
+        fIsAutoActivated= enabled;
+        manageAutoActivation(fIsAutoActivated);
+    }
+
+    /**
+     * Enables the content assistant's auto insertion mode. If enabled, the content assistant
+     * inserts a proposal automatically if it is the only proposal. In the case of ambiguities, the
+     * user must make the choice.
+     *
+     * @param enabled indicates whether auto insertion is enabled or not
+     * @since 2.0
+     */
+    public void enableAutoInsert(bool enabled) {
+        fIsAutoInserting= enabled;
+    }
+
+    /**
+     * Returns whether this content assistant is in the auto insertion mode or not.
+     *
+     * @return <code>true</code> if in auto insertion mode
+     * @since 2.0
+     */
+    bool isAutoInserting() {
+        return fIsAutoInserting;
+    }
+
+    /**
+     * Installs and uninstall the listeners needed for auto activation.
+     *
+     * @param start <code>true</code> if listeners must be installed, <code>false</code> if they
+     *        must be removed
+     * @since 2.0
+     */
+    private void manageAutoActivation(bool start) {
+        if (start) {
+
+            if ((fContentAssistSubjectControlAdapter !is null) && fAutoAssistListener is null) {
+                fAutoAssistListener= createAutoAssistListener();
+                // For details see https://bugs.eclipse.org/bugs/show_bug.cgi?id=49212
+                if (fContentAssistSubjectControlAdapter.supportsVerifyKeyListener())
+                    fContentAssistSubjectControlAdapter.appendVerifyKeyListener(fAutoAssistListener);
+                else
+                    fContentAssistSubjectControlAdapter.addKeyListener(fAutoAssistListener);
+            }
+
+        } else if (fAutoAssistListener !is null) {
+            // For details see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=49212
+            if (fContentAssistSubjectControlAdapter.supportsVerifyKeyListener())
+                fContentAssistSubjectControlAdapter.removeVerifyKeyListener(fAutoAssistListener);
+            else
+                fContentAssistSubjectControlAdapter.removeKeyListener(fAutoAssistListener);
+            fAutoAssistListener= null;
+        }
+    }
+
+    /**
+     * This method allows subclasses to provide their own {@link AutoAssistListener}.
+     *
+     * @return a new auto assist listener
+     * @since 3.4
+     */
+    protected AutoAssistListener createAutoAssistListener() {
+        return new AutoAssistListener();
+    }
+
+    /**
+     * Sets the delay after which the content assistant is automatically invoked if the cursor is
+     * behind an auto activation character.
+     *
+     * @param delay the auto activation delay
+     */
+    public void setAutoActivationDelay(int delay) {
+        fAutoActivationDelay= delay;
+    }
+
+    /**
+     * Gets the delay after which the content assistant is automatically invoked if the cursor is
+     * behind an auto activation character.
+     *
+     * @return the auto activation delay
+     * @since 3.4
+     */
+    public int getAutoActivationDelay() {
+        return fAutoActivationDelay;
+    }
+
+    /**
+     * Sets the proposal pop-ups' orientation. The following values may be used:
+     * <ul>
+     *   <li>PROPOSAL_OVERLAY<p>
+     *     proposal popup windows should overlay each other
+     *   </li>
+     *   <li>PROPOSAL_REMOVE<p>
+     *     any currently shown proposal popup should be closed
+     *   </li>
+     *   <li>PROPOSAL_STACKED<p>
+     *     proposal popup windows should be vertical stacked, with no overlap,
+     *     beneath the line containing the current cursor location
+     *   </li>
+     * </ul>
+     *
+     * @param orientation the popup's orientation
+     */
+    public void setProposalPopupOrientation(int orientation) {
+        fProposalPopupOrientation= orientation;
+    }
+
+    /**
+     * Sets the context information popup's orientation.
+     * The following values may be used:
+     * <ul>
+     *   <li>CONTEXT_ABOVE<p>
+     *     context information popup should always appear above the line containing
+     *     the current cursor location
+     *   </li>
+     *   <li>CONTEXT_BELOW<p>
+     *     context information popup should always appear below the line containing
+     *     the current cursor location
+     *   </li>
+     * </ul>
+     *
+     * @param orientation the popup's orientation
+     */
+    public void setContextInformationPopupOrientation(int orientation) {
+        fContextInfoPopupOrientation= orientation;
+    }
+
+    /**
+     * Sets the context information popup's background color.
+     *
+     * @param background the background color
+     */
+    public void setContextInformationPopupBackground(Color background) {
+        fContextInfoPopupBackground= background;
+    }
+
+    /**
+     * Returns the background of the context information popup.
+     *
+     * @return the background of the context information popup
+     * @since 2.0
+     */
+    Color getContextInformationPopupBackground() {
+        return fContextInfoPopupBackground;
+    }
+
+    /**
+     * Sets the context information popup's foreground color.
+     *
+     * @param foreground the foreground color
+     * @since 2.0
+     */
+    public void setContextInformationPopupForeground(Color foreground) {
+        fContextInfoPopupForeground= foreground;
+    }
+
+    /**
+     * Returns the foreground of the context information popup.
+     *
+     *
+     * @return the foreground of the context information popup
+     * @since 2.0
+     */
+    Color getContextInformationPopupForeground() {
+        return fContextInfoPopupForeground;
+    }
+
+    /**
+     * Sets the proposal selector's background color.
+     * <p>
+     * <strong>Note:</strong> As of 3.4, you should only call this
+     * method if you want to override the {@link JFacePreferences#CONTENT_ASSIST_BACKGROUND_COLOR}.
+     * </p>
+     *
+     * @param background the background color
+     * @since 2.0
+     */
+    public void setProposalSelectorBackground(Color background) {
+        fProposalSelectorBackground= background;
+    }
+
+    /**
+     * Returns the custom background color of the proposal selector.
+     *
+     * @return the background of the proposal selector or <code>null</code> if not set
+     * @since 2.0
+     */
+    Color getProposalSelectorBackground() {
+        return fProposalSelectorBackground;
+    }
+
+    /**
+     * Sets the proposal's foreground color.
+     * <p>
+     * <strong>Note:</strong> As of 3.4, you should only call this
+     * method if you want to override the {@link JFacePreferences#CONTENT_ASSIST_FOREGROUND_COLOR}.
+     * </p>
+     *
+     * @param foreground the foreground color
+     * @since 2.0
+     */
+    public void setProposalSelectorForeground(Color foreground) {
+        fProposalSelectorForeground= foreground;
+    }
+
+    /**
+     * Returns the custom foreground color of the proposal selector.
+     *
+     * @return the foreground of the proposal selector or <code>null</code> if not set
+     * @since 2.0
+     */
+    Color getProposalSelectorForeground() {
+        return fProposalSelectorForeground;
+    }
+
+    /**
+     * Sets the context selector's background color.
+     *
+     * @param background the background color
+     * @since 2.0
+     */
+    public void setContextSelectorBackground(Color background) {
+        fContextSelectorBackground= background;
+    }
+
+    /**
+     * Returns the background of the context selector.
+     *
+     * @return the background of the context selector
+     * @since 2.0
+     */
+    Color getContextSelectorBackground() {
+        return fContextSelectorBackground;
+    }
+
+    /**
+     * Sets the context selector's foreground color.
+     *
+     * @param foreground the foreground color
+     * @since 2.0
+     */
+    public void setContextSelectorForeground(Color foreground) {
+        fContextSelectorForeground= foreground;
+    }
+
+    /**
+     * Returns the foreground of the context selector.
+     *
+     * @return the foreground of the context selector
+     * @since 2.0
+     */
+    Color getContextSelectorForeground() {
+        return fContextSelectorForeground;
+    }
+
+    /**
+     * Sets the information control creator for the additional information control.
+     *
+     * @param creator the information control creator for the additional information control
+     * @since 2.0
+     */
+    public void setInformationControlCreator(IInformationControlCreator creator) {
+        fInformationControlCreator= creator;
+    }
+
+    /*
+     * @see IControlContentAssistant#install(IContentAssistSubjectControl)
+     * @since 3.0
+     */
+    protected void install(IContentAssistSubjectControl contentAssistSubjectControl) {
+        fContentAssistSubjectControl= contentAssistSubjectControl;
+        fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fContentAssistSubjectControl);
+        install();
+    }
+
+    /*
+     * @see IContentAssist#install
+     * @since 3.0
+     */
+    public void install(ITextViewer textViewer) {
+        fViewer= textViewer;
+        fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fViewer);
+        install();
+    }
+
+    protected void install() {
+
+        fLayoutManager= new LayoutManager();
+        fInternalListener= new InternalListener();
+
+        AdditionalInfoController controller= null;
+        if (fInformationControlCreator !is null) {
+            int delay= fAutoActivationDelay;
+            if (delay is 0)
+                delay= DEFAULT_AUTO_ACTIVATION_DELAY;
+            delay= Math.round(delay * 1.5f);
+            controller= new AdditionalInfoController(fInformationControlCreator, delay);
+        }
+
+        fContextInfoPopup= fContentAssistSubjectControlAdapter.createContextInfoPopup(this);
+        fProposalPopup= fContentAssistSubjectControlAdapter.createCompletionProposalPopup(this, controller);
+
+        registerHandler(SELECT_NEXT_PROPOSAL_COMMAND_ID, fProposalPopup.createProposalSelectionHandler(CompletionProposalPopup.ProposalSelectionHandler.SELECT_NEXT));
+        registerHandler(SELECT_PREVIOUS_PROPOSAL_COMMAND_ID, fProposalPopup.createProposalSelectionHandler(CompletionProposalPopup.ProposalSelectionHandler.SELECT_PREVIOUS));
+
+        if (Helper.okToUse(fContentAssistSubjectControlAdapter.getControl())) {
+            fContentAssistSubjectControlShell= fContentAssistSubjectControlAdapter.getControl().getShell();
+            fCASCSTraverseListener= new class()  TraverseListener {
+                public void keyTraversed(TraverseEvent e) {
+                    if (e.detail is DWT.TRAVERSE_ESCAPE && isProposalPopupActive())
+                        e.doit= false;
+                }
+            };
+            fContentAssistSubjectControlShell.addTraverseListener(fCASCSTraverseListener);
+        }
+
+        manageAutoActivation(fIsAutoActivated);
+    }
+
+    /*
+     * @see IContentAssist#uninstall
+     */
+    public void uninstall() {
+        hide();
+        manageAutoActivation(false);
+
+        if (fHandlers !is null) {
+            fHandlers.clear();
+            fHandlers= null;
+        }
+
+        if (fCloser !is null) {
+            fCloser.uninstall();
+            fCloser= null;
+        }
+
+        if (Helper.okToUse(fContentAssistSubjectControlShell))
+            fContentAssistSubjectControlShell.removeTraverseListener(fCASCSTraverseListener);
+        fCASCSTraverseListener= null;
+        fContentAssistSubjectControlShell= null;
+
+        fViewer= null;
+        fContentAssistSubjectControl= null;
+        fContentAssistSubjectControlAdapter= null;
+    }
+
+    /**
+     * Adds the given shell of the specified type to the layout. Valid types are defined by
+     * <code>LayoutManager</code>.
+     *
+     * @param popup a content assist popup
+     * @param shell the shell of the content-assist popup
+     * @param type the type of popup
+     * @param visibleOffset the offset at which to layout the popup relative to the offset of the
+     *        viewer's visible region
+     * @since 2.0
+     */
+    void addToLayout(Object popup, Shell shell, int type, int visibleOffset) {
+        fLayoutManager.add(popup, shell, type, visibleOffset);
+    }
+
+    /**
+     * Layouts the registered popup of the given type relative to the given offset. The offset is
+     * relative to the offset of the viewer's visible region. Valid types are defined by
+     * <code>LayoutManager</code>.
+     *
+     * @param type the type of popup to layout
+     * @param visibleOffset the offset at which to layout relative to the offset of the viewer's
+     *        visible region
+     * @since 2.0
+     */
+    void layout(int type, int visibleOffset) {
+        fLayoutManager.layout(type, visibleOffset);
+    }
+
+    /**
+     * Returns the layout manager.
+     *
+     * @return the layout manager
+     * @since 3.3
+     */
+    LayoutManager getLayoutManager() {
+        return fLayoutManager;
+    }
+
+    /**
+     * Notifies the controller that a popup has lost focus.
+     *
+     * @param e the focus event
+     */
+    void popupFocusLost(FocusEvent e) {
+        fCloser.focusLost(e);
+    }
+
+    /**
+     * Returns the offset of the selection relative to the offset of the visible region.
+     *
+     * @return the offset of the selection relative to the offset of the visible region
+     * @since 2.0
+     */
+    int getSelectionOffset() {
+        return fContentAssistSubjectControlAdapter.getWidgetSelectionRange().x;
+    }
+
+    /**
+     * Returns whether the widget token could be acquired. The following are valid listener types:
+     * <ul>
+     *   <li>AUTO_ASSIST</li>
+     *   <li>CONTEXT_SELECTOR</li>
+     *   <li>PROPOSAL_SELECTOR</li>
+     *   <li>CONTEXT_INFO_POPUP</li>
+     * </ul>
+     *
+     * @param type the listener type for which to acquire
+     * @return <code>true</code> if the widget token could be acquired
+     * @since 2.0
+     */
+    private bool acquireWidgetToken(int type) {
+        switch (type) {
+            case CONTEXT_SELECTOR:
+            case PROPOSAL_SELECTOR:
+                if ( cast(IWidgetTokenOwnerExtension)fContentAssistSubjectControl ) {
+                    IWidgetTokenOwnerExtension extension= cast(IWidgetTokenOwnerExtension) fContentAssistSubjectControl;
+                    return extension.requestWidgetToken(this, WIDGET_PRIORITY);
+                } else if ( cast(IWidgetTokenOwner)fContentAssistSubjectControl ) {
+                    IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fContentAssistSubjectControl;
+                    return owner.requestWidgetToken(this);
+                } else if ( cast(IWidgetTokenOwnerExtension)fViewer ) {
+                    IWidgetTokenOwnerExtension extension= cast(IWidgetTokenOwnerExtension) fViewer;
+                    return extension.requestWidgetToken(this, WIDGET_PRIORITY);
+                } else if ( cast(IWidgetTokenOwner)fViewer ) {
+                    IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fViewer;
+                    return owner.requestWidgetToken(this);
+                }
+        }
+        return true;
+    }
+
+    /**
+     * Registers a content assist listener. The following are valid listener types:
+     * <ul>
+     *   <li>AUTO_ASSIST</li>
+     *   <li>CONTEXT_SELECTOR</li>
+     *   <li>PROPOSAL_SELECTOR</li>
+     *   <li>CONTEXT_INFO_POPUP</li>
+     * </ul>
+     * Returns whether the listener could be added successfully. A listener can not be added if the
+     * widget token could not be acquired.
+     *
+     * @param listener the listener to register
+     * @param type the type of listener
+     * @return <code>true</code> if the listener could be added
+     */
+    bool addContentAssistListener(IContentAssistListener listener, int type) {
+
+        if (acquireWidgetToken(type)) {
+
+            fListeners[type]= listener;
+
+            if (fCloser is null && getNumberOfListeners() is 1) {
+                fCloser= new Closer();
+                fCloser.install();
+                fContentAssistSubjectControlAdapter.setEventConsumer(fInternalListener);
+                installKeyListener();
+            } else
+                promoteKeyListener();
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Re-promotes the key listener to the first position, using prependVerifyKeyListener. This
+     * ensures no other instance is filtering away the keystrokes underneath, if we've been up for a
+     * while (e.g. when the context info is showing.
+     *
+     * @since 3.0
+     */
+    private void promoteKeyListener() {
+        uninstallVerifyKeyListener();
+        installKeyListener();
+    }
+
+    /**
+     * Installs a key listener on the text viewer's widget.
+     */
+    private void installKeyListener() {
+        if (!fVerifyKeyListenerHooked) {
+            if (Helper.okToUse(fContentAssistSubjectControlAdapter.getControl())) {
+                fVerifyKeyListenerHooked= fContentAssistSubjectControlAdapter.prependVerifyKeyListener(fInternalListener);
+            }
+        }
+    }
+
+    /**
+     * Releases the previously acquired widget token if the token is no longer necessary. The
+     * following are valid listener types:
+     * <ul>
+     *   <li>AUTO_ASSIST</li>
+     *   <li>CONTEXT_SELECTOR</li>
+     *   <li>PROPOSAL_SELECTOR</li>
+     *   <li>CONTEXT_INFO_POPUP</li>
+     * </ul>
+     *
+     * @param type the listener type
+     * @since 2.0
+     */
+    private void releaseWidgetToken(int type) {
+        if (fListeners[CONTEXT_SELECTOR] is null && fListeners[PROPOSAL_SELECTOR] is null) {
+            IWidgetTokenOwner owner= null;
+            if ( cast(IWidgetTokenOwner)fContentAssistSubjectControl )
+                owner= cast(IWidgetTokenOwner) fContentAssistSubjectControl;
+            else if ( cast(IWidgetTokenOwner)fViewer )
+                owner= cast(IWidgetTokenOwner) fViewer;
+            if (owner !is null)
+                owner.releaseWidgetToken(this);
+        }
+    }
+
+    /**
+     * Unregisters a content assist listener.
+     *
+     * @param listener the listener to unregister
+     * @param type the type of listener
+     * @see #addContentAssistListener(IContentAssistListener, int)
+     */
+    void removeContentAssistListener(IContentAssistListener listener, int type) {
+        fListeners[type]= null;
+
+        if (getNumberOfListeners() is 0) {
+
+            if (fCloser !is null) {
+                fCloser.uninstall();
+                fCloser= null;
+            }
+
+            uninstallVerifyKeyListener();
+            fContentAssistSubjectControlAdapter.setEventConsumer(null);
+        }
+
+        releaseWidgetToken(type);
+    }
+
+    /**
+     * Uninstall the key listener from the text viewer's widget.
+     *
+     * @since 3.0
+     */
+    private void uninstallVerifyKeyListener() {
+        if (fVerifyKeyListenerHooked) {
+            if (Helper.okToUse(fContentAssistSubjectControlAdapter.getControl()))
+                fContentAssistSubjectControlAdapter.removeVerifyKeyListener(fInternalListener);
+            fVerifyKeyListenerHooked= false;
+        }
+    }
+
+    /**
+     * Returns the number of listeners.
+     *
+     * @return the number of listeners
+     * @since 2.0
+     */
+    private int getNumberOfListeners() {
+        int count= 0;
+        for (int i= 0; i <= CONTEXT_INFO_POPUP; i++) {
+            if (fListeners[i] !is null)
+                ++count;
+        }
+        return count;
+    }
+
+    /*
+     * @see IContentAssist#showPossibleCompletions
+     */
+    public String showPossibleCompletions() {
+        if (!prepareToShowCompletions(false))
+            return null;
+        if (fIsPrefixCompletionEnabled)
+            return fProposalPopup.incrementalComplete();
+        return fProposalPopup.showProposals(false);
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistantExtension#completePrefix()
+     * @since 3.0
+     */
+    public String completePrefix() {
+        if (!prepareToShowCompletions(false))
+            return null;
+        return fProposalPopup.incrementalComplete();
+    }
+
+    /**
+     * Prepares to show content assist proposals. It returns false if auto activation has kicked in
+     * recently.
+     *
+     * @param isAutoActivated  whether completion was triggered by auto activation
+     * @return <code>true</code> if the caller should continue and show the proposals,
+     *         <code>false</code> otherwise.
+     * @since 3.2
+     */
+    private bool prepareToShowCompletions(bool isAutoActivated) {
+        long current= System.currentTimeMillis();
+        int gracePeriod= Math.max(fAutoActivationDelay, 200);
+        if (current < fLastAutoActivation + gracePeriod)
+            return false;
+
+        promoteKeyListener();
+        fireSessionBeginEvent(isAutoActivated);
+        return true;
+    }
+
+    /**
+     * Callback to signal this content assistant that the presentation of the possible completions
+     * has been stopped.
+     *
+     * @since 2.1
+     */
+    protected void possibleCompletionsClosed() {
+        fLastAutoActivation= Long.MIN_VALUE;
+        storeCompletionProposalPopupSize();
+    }
+    package void possibleCompletionsClosed_package() {
+        possibleCompletionsClosed();
+    }
+
+    /*
+     * @see IContentAssist#showContextInformation
+     */
+    public String showContextInformation() {
+        promoteKeyListener();
+        if (fContextInfoPopup !is null)
+            return fContextInfoPopup.showContextProposals(false);
+        return null;
+    }
+
+    /**
+     * Callback to signal this content assistant that the presentation of the context information
+     * has been stopped.
+     *
+     * @since 2.1
+     */
+    protected void contextInformationClosed() {
+    }
+    package void contextInformationClosed_package() {
+        contextInformationClosed();
+    }
+
+    /**
+     * Requests that the specified context information to be shown.
+     *
+     * @param contextInformation the context information to be shown
+     * @param offset the offset to which the context information refers to
+     * @since 2.0
+     */
+    void showContextInformation(IContextInformation contextInformation, int offset) {
+        if (fContextInfoPopup !is null)
+            fContextInfoPopup.showContextInformation(contextInformation, offset);
+    }
+
+    /**
+     * Returns the current content assist error message.
+     *
+     * @return an error message or <code>null</code> if no error has occurred
+     */
+    String getErrorMessage() {
+        return fLastErrorMessage;
+    }
+
+    /**
+     * Returns the content assist processor for the content type of the specified document position.
+     *
+     * @param viewer the text viewer
+     * @param offset a offset within the document
+     * @return a content-assist processor or <code>null</code> if none exists
+     * @since 3.0
+     */
+    private IContentAssistProcessor getProcessor(ITextViewer viewer, int offset) {
+        try {
+
+            IDocument document= viewer.getDocument();
+            String type= TextUtilities.getContentType(document, getDocumentPartitioning(), offset, true);
+
+            return getContentAssistProcessor(type);
+
+        } catch (BadLocationException x) {
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the content assist processor for the content type of the specified document position.
+     *
+     * @param contentAssistSubjectControl the content assist subject control
+     * @param offset a offset within the document
+     * @return a content-assist processor or <code>null</code> if none exists
+     * @since 3.0
+     */
+    private IContentAssistProcessor getProcessor(IContentAssistSubjectControl contentAssistSubjectControl, int offset) {
+        try {
+
+            IDocument document= contentAssistSubjectControl.getDocument();
+            String type;
+            if (document !is null)
+                type= TextUtilities.getContentType(document, getDocumentPartitioning(), offset, true);
+            else
+                type= IDocument.DEFAULT_CONTENT_TYPE;
+
+            return getContentAssistProcessor(type);
+
+        } catch (BadLocationException x) {
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns an array of completion proposals computed based on the specified document position.
+     * The position is used to determine the appropriate content assist processor to invoke.
+     *
+     * @param contentAssistSubjectControl the content assist subject control
+     * @param offset a document offset
+     * @return an array of completion proposals
+     * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int)
+     * @since 3.0
+     */
+    ICompletionProposal[] computeCompletionProposals(IContentAssistSubjectControl contentAssistSubjectControl, int offset) {
+        fLastErrorMessage= null;
+
+        ICompletionProposal[] result= null;
+
+        IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset);
+        if ( cast(ISubjectControlContentAssistProcessor)p ) {
+            result= (cast(ISubjectControlContentAssistProcessor) p).computeCompletionProposals(contentAssistSubjectControl, offset);
+            fLastErrorMessage= p.getErrorMessage();
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns an array of completion proposals computed based on the specified document position.
+     * The position is used to determine the appropriate content assist processor to invoke.
+     *
+     * @param viewer the viewer for which to compute the proposals
+     * @param offset a document offset
+     * @return an array of completion proposals or <code>null</code> if no proposals are possible
+     * @see IContentAssistProcessor#computeCompletionProposals(ITextViewer, int)
+     */
+    ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+        fLastErrorMessage= null;
+
+        ICompletionProposal[] result= null;
+
+        IContentAssistProcessor p= getProcessor(viewer, offset);
+        if (p !is null) {
+            result= p.computeCompletionProposals(viewer, offset);
+            fLastErrorMessage= p.getErrorMessage();
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns an array of context information objects computed based on the specified document
+     * position. The position is used to determine the appropriate content assist processor to
+     * invoke.
+     *
+     * @param viewer the viewer for which to compute the context information
+     * @param offset a document offset
+     * @return an array of context information objects
+     * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
+     */
+    IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
+        fLastErrorMessage= null;
+
+        IContextInformation[] result= null;
+
+        IContentAssistProcessor p= getProcessor(viewer, offset);
+        if (p !is null) {
+            result= p.computeContextInformation(viewer, offset);
+            fLastErrorMessage= p.getErrorMessage();
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns an array of context information objects computed based on the specified document
+     * position. The position is used to determine the appropriate content assist processor to
+     * invoke.
+     *
+     * @param contentAssistSubjectControl the content assist subject control
+     * @param offset a document offset
+     * @return an array of context information objects
+     * @see IContentAssistProcessor#computeContextInformation(ITextViewer, int)
+     * @since 3.0
+     */
+    IContextInformation[] computeContextInformation(IContentAssistSubjectControl contentAssistSubjectControl, int offset) {
+        fLastErrorMessage= null;
+
+        IContextInformation[] result= null;
+
+        IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset);
+        if ( cast(ISubjectControlContentAssistProcessor)p ) {
+            result= (cast(ISubjectControlContentAssistProcessor) p).computeContextInformation(contentAssistSubjectControl, offset);
+            fLastErrorMessage= p.getErrorMessage();
+        }
+
+        return result;
+    }
+
+    /**
+     * Returns the context information validator that should be used to determine when the currently
+     * displayed context information should be dismissed. The position is used to determine the
+     * appropriate content assist processor to invoke.
+     *
+     * @param viewer the text viewer
+     * @param offset a document offset
+     * @return an validator
+     * @see IContentAssistProcessor#getContextInformationValidator()
+     * @since 3.0
+     */
+    IContextInformationValidator getContextInformationValidator(ITextViewer viewer, int offset) {
+        IContentAssistProcessor p= getProcessor(viewer, offset);
+        return p !is null ? p.getContextInformationValidator() : null;
+    }
+
+    /**
+     * Returns the context information validator that should be used to determine when the currently
+     * displayed context information should be dismissed. The position is used to determine the
+     * appropriate content assist processor to invoke.
+     *
+     * @param contentAssistSubjectControl the content assist subject control
+     * @param offset a document offset
+     * @return an validator
+     * @see IContentAssistProcessor#getContextInformationValidator()
+     * @since 3.0
+     */
+    IContextInformationValidator getContextInformationValidator(IContentAssistSubjectControl contentAssistSubjectControl, int offset) {
+        IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset);
+        return p !is null ? p.getContextInformationValidator() : null;
+    }
+
+    /**
+     * Returns the context information presenter that should be used to display context information.
+     * The position is used to determine the appropriate content assist processor to invoke.
+     *
+     * @param viewer the text viewer
+     * @param offset a document offset
+     * @return a presenter
+     * @since 2.0
+     */
+    IContextInformationPresenter getContextInformationPresenter(ITextViewer viewer, int offset) {
+        IContextInformationValidator validator= getContextInformationValidator(viewer, offset);
+        if ( cast(IContextInformationPresenter)validator )
+            return cast(IContextInformationPresenter) validator;
+        return null;
+    }
+
+    /**
+     * Returns the context information presenter that should be used to display context information.
+     * The position is used to determine the appropriate content assist processor to invoke.
+     *
+     * @param contentAssistSubjectControl the content assist subject control
+     * @param offset a document offset
+     * @return a presenter
+     * @since 3.0
+     */
+    IContextInformationPresenter getContextInformationPresenter(IContentAssistSubjectControl contentAssistSubjectControl, int offset) {
+        IContextInformationValidator validator= getContextInformationValidator(contentAssistSubjectControl, offset);
+        if ( cast(IContextInformationPresenter)validator )
+            return cast(IContextInformationPresenter) validator;
+        return null;
+    }
+
+    /**
+     * Returns the characters which when typed by the user should automatically initiate proposing
+     * completions. The position is used to determine the appropriate content assist processor to
+     * invoke.
+     *
+     * @param contentAssistSubjectControl the content assist subject control
+     * @param offset a document offset
+     * @return the auto activation characters
+     * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+     * @since 3.0
+     */
+    char[] getCompletionProposalAutoActivationCharacters(IContentAssistSubjectControl contentAssistSubjectControl, int offset) {
+        IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset);
+        return p !is null ? p.getCompletionProposalAutoActivationCharacters() : null;
+    }
+
+    /**
+     * Returns the characters which when typed by the user should automatically initiate proposing
+     * completions. The position is used to determine the appropriate content assist processor to
+     * invoke.
+     *
+     * @param viewer the text viewer
+     * @param offset a document offset
+     * @return the auto activation characters
+     * @see IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+     */
+    char[] getCompletionProposalAutoActivationCharacters(ITextViewer viewer, int offset) {
+        IContentAssistProcessor p= getProcessor(viewer, offset);
+        return p !is null ? p.getCompletionProposalAutoActivationCharacters() : null;
+    }
+
+    /**
+     * Returns the characters which when typed by the user should automatically initiate the
+     * presentation of context information. The position is used to determine the appropriate
+     * content assist processor to invoke.
+     *
+     * @param viewer the text viewer
+     * @param offset a document offset
+     * @return the auto activation characters
+     * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters()
+     * @since 3.0
+     */
+    char[] getContextInformationAutoActivationCharacters(ITextViewer viewer, int offset) {
+        IContentAssistProcessor p= getProcessor(viewer, offset);
+        return p !is null ? p.getContextInformationAutoActivationCharacters() : null;
+    }
+
+    /**
+     * Returns the characters which when typed by the user should automatically initiate the
+     * presentation of context information. The position is used to determine the appropriate
+     * content assist processor to invoke.
+     *
+     * @param contentAssistSubjectControl the content assist subject control
+     * @param offset a document offset
+     * @return the auto activation characters
+     * @see IContentAssistProcessor#getContextInformationAutoActivationCharacters()
+     * @since 3.0
+     */
+    char[] getContextInformationAutoActivationCharacters(IContentAssistSubjectControl contentAssistSubjectControl, int offset) {
+        IContentAssistProcessor p= getProcessor(contentAssistSubjectControl, offset);
+        return p !is null ? p.getContextInformationAutoActivationCharacters() : null;
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeper#requestWidgetToken(IWidgetTokenOwner)
+     * @since 2.0
+     */
+    public bool requestWidgetToken(IWidgetTokenOwner owner) {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeperExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner,
+     *      int)
+     * @since 3.0
+     */
+    public bool requestWidgetToken(IWidgetTokenOwner owner, int priority) {
+        if (priority > WIDGET_PRIORITY) {
+            hide();
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeperExtension#setFocus(dwtx.jface.text.IWidgetTokenOwner)
+     * @since 3.0
+     */
+    public bool setFocus(IWidgetTokenOwner owner) {
+        if (fProposalPopup !is null) {
+            fProposalPopup.setFocus();
+            return fProposalPopup.hasFocus();
+        }
+        return false;
+    }
+
+    /**
+     * Hides any open pop-ups.
+     *
+     * @since 3.0
+     */
+    protected void hide() {
+        if (fProposalPopup !is null)
+            fProposalPopup.hide();
+
+        if (fContextInfoPopup !is null)
+            fContextInfoPopup.hide();
+    }
+    package void hide_package() {
+        hide();
+    }
+
+    // ------ control's size handling dialog settings ------
+
+    /**
+     * Tells this information control manager to open the information control with the values
+     * contained in the given dialog settings and to store the control's last valid size in the
+     * given dialog settings.
+     * <p>
+     * Note: This API is only valid if the information control implements
+     * {@link dwtx.jface.text.IInformationControlExtension3}. Not following this restriction
+     * will later result in an {@link UnsupportedOperationException}.
+     * </p>
+     * <p>
+     * The constants used to store the values are:
+     * <ul>
+     * <li>{@link ContentAssistant#STORE_SIZE_X}</li>
+     * <li>{@link ContentAssistant#STORE_SIZE_Y}</li>
+     * </ul>
+     * </p>
+     *
+     * @param dialogSettings
+     * @since 3.0
+     */
+    public void setRestoreCompletionProposalSize(IDialogSettings dialogSettings) {
+        Assert.isTrue(dialogSettings !is null);
+        fDialogSettings= dialogSettings;
+    }
+
+    /**
+     * Stores the content assist pop-up's size.
+     */
+    protected void storeCompletionProposalPopupSize() {
+        if (fDialogSettings is null || fProposalPopup is null)
+            return;
+
+        Point size= fProposalPopup.getSize();
+        if (size is null)
+            return;
+
+        fDialogSettings.put(STORE_SIZE_X, size.x);
+        fDialogSettings.put(STORE_SIZE_Y, size.y);
+    }
+
+    /**
+     * Restores the content assist pop-up's size.
+     *
+     * @return the stored size
+     * @since 3.0
+     */
+    protected Point restoreCompletionProposalPopupSize() {
+        if (fDialogSettings is null)
+            return null;
+
+        Point size= new Point(-1, -1);
+
+        try {
+            size.x= fDialogSettings.getInt(STORE_SIZE_X);
+            size.y= fDialogSettings.getInt(STORE_SIZE_Y);
+        } catch (NumberFormatException ex) {
+            size.x= -1;
+            size.y= -1;
+        }
+
+        // sanity check
+        if (size.x is -1 && size.y is -1)
+            return null;
+
+        Rectangle maxBounds= null;
+        if (fContentAssistSubjectControl !is null && Helper.okToUse(fContentAssistSubjectControl.getControl()))
+            maxBounds= fContentAssistSubjectControl.getControl().getDisplay().getBounds();
+        else {
+            // fallback
+            Display display= Display.getCurrent();
+            if (display is null)
+                display= Display.getDefault();
+            if (display !is null && !display.isDisposed())
+                maxBounds= display.getBounds();
+        }
+
+        if (size.x > -1 && size.y > -1) {
+            if (maxBounds !is null) {
+                size.x= Math.min(size.x, maxBounds.width);
+                size.y= Math.min(size.y, maxBounds.height);
+            }
+
+            // Enforce an absolute minimal size
+            size.x= Math.max(size.x, 30);
+            size.y= Math.max(size.y, 30);
+        }
+
+        return size;
+    }
+    package Point restoreCompletionProposalPopupSize_package() {
+        return restoreCompletionProposalPopupSize();
+    }
+
+    /**
+     * Sets the prefix completion property. If enabled, content assist delegates completion to
+     * prefix completion.
+     *
+     * @param enabled <code>true</code> to enable prefix completion, <code>false</code> to
+     *        disable
+     */
+    public void enablePrefixCompletion(bool enabled) {
+        fIsPrefixCompletionEnabled= enabled;
+    }
+
+    /**
+     * Returns the prefix completion state.
+     *
+     * @return <code>true</code> if prefix completion is enabled, <code>false</code> otherwise
+     * @since 3.2
+     */
+    bool isPrefixCompletionEnabled() {
+        return fIsPrefixCompletionEnabled;
+    }
+
+    /**
+     * Returns whether the content assistant proposal popup has the focus.
+     *
+     * @return <code>true</code> if the proposal popup has the focus
+     * @since 3.0
+     */
+    public bool hasProposalPopupFocus() {
+        return fProposalPopup.hasFocus();
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#addCompletionListener(dwtx.jface.text.contentassist.ICompletionListener)
+     * @since 3.2
+     */
+    public void addCompletionListener(ICompletionListener listener) {
+        Assert.isLegal(listener !is null);
+        fCompletionListeners.add(listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#removeCompletionListener(dwtx.jface.text.contentassist.ICompletionListener)
+     * @since 3.2
+     */
+    public void removeCompletionListener(ICompletionListener listener) {
+        fCompletionListeners.remove(listener);
+    }
+
+    /**
+     * Fires a session begin event to all registered {@link ICompletionListener}s.
+     *
+     * @param isAutoActivated  <code>true</code> if this session was triggered by auto activation
+     * @since 3.2
+     */
+    void fireSessionBeginEvent(bool isAutoActivated) {
+        if (fContentAssistSubjectControlAdapter !is null && !isProposalPopupActive()) {
+            IContentAssistProcessor processor= getProcessor(fContentAssistSubjectControlAdapter, fContentAssistSubjectControlAdapter.getSelectedRange().x);
+            ContentAssistEvent event= new ContentAssistEvent(this, processor, isAutoActivated);
+            Object[] listeners= fCompletionListeners.getListeners();
+            for (int i= 0; i < listeners.length; i++) {
+                ICompletionListener listener= cast(ICompletionListener)listeners[i];
+                listener.assistSessionStarted(event);
+            }
+        }
+    }
+
+    /**
+     * Fires a session restart event to all registered {@link ICompletionListener}s.
+     *
+     * @since 3.4
+     */
+    void fireSessionRestartEvent() {
+        if (fContentAssistSubjectControlAdapter !is null) {
+            IContentAssistProcessor processor= getProcessor(fContentAssistSubjectControlAdapter, fContentAssistSubjectControlAdapter.getSelectedRange().x);
+            ContentAssistEvent event= new ContentAssistEvent(this, processor);
+            Object[] listeners= fCompletionListeners.getListeners();
+            for (int i= 0; i < listeners.length; i++) {
+                ICompletionListener listener= cast(ICompletionListener)listeners[i];
+                if ( cast(ICompletionListenerExtension)listener )
+                    (cast(ICompletionListenerExtension)listener).assistSessionRestarted(event);
+            }
+        }
+    }
+
+    /**
+     * Fires a session end event to all registered {@link ICompletionListener}s.
+     *
+     * @since 3.2
+     */
+    void fireSessionEndEvent() {
+        if (fContentAssistSubjectControlAdapter !is null) {
+            IContentAssistProcessor processor= getProcessor(fContentAssistSubjectControlAdapter, fContentAssistSubjectControlAdapter.getSelectedRange().x);
+            ContentAssistEvent event= new ContentAssistEvent(this, processor);
+            Object[] listeners= fCompletionListeners.getListeners();
+            for (int i= 0; i < listeners.length; i++) {
+                ICompletionListener listener= cast(ICompletionListener)listeners[i];
+                listener.assistSessionEnded(event);
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#setRepeatedInvocationMode(bool)
+     * @since 3.2
+     */
+    public void setRepeatedInvocationMode(bool cycling) {
+        fIsRepetitionMode= cycling;
+    }
+
+    /**
+     * Returns <code>true</code> if repeated invocation mode is enabled, <code>false</code>
+     * otherwise.
+     *
+     * @return <code>true</code> if repeated invocation mode is enabled, <code>false</code>
+     *         otherwise
+     * @since 3.2
+     */
+    bool isRepeatedInvocationMode() {
+        return fIsRepetitionMode;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#setShowEmptyList(bool)
+     * @since 3.2
+     */
+    public void setShowEmptyList(bool showEmpty) {
+        fShowEmptyList= showEmpty;
+    }
+
+    /**
+     * Returns <code>true</code> if empty lists should be displayed, <code>false</code>
+     * otherwise.
+     *
+     * @return <code>true</code> if empty lists should be displayed, <code>false</code>
+     *         otherwise
+     * @since 3.2
+     */
+    bool isShowEmptyList() {
+        return fShowEmptyList;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#setStatusLineVisible(bool)
+     * @since 3.2
+     */
+    public void setStatusLineVisible(bool show) {
+        fIsStatusLineVisible= show;
+        if (fProposalPopup !is null)
+            fProposalPopup.setStatusLineVisible(show);
+    }
+
+    /**
+     * Returns <code>true</code> if a message line should be displayed, <code>false</code>
+     * otherwise.
+     *
+     * @return <code>true</code> if a message line should be displayed, <code>false</code>
+     *         otherwise
+     * @since 3.2
+     */
+    bool isStatusLineVisible() {
+        return fIsStatusLineVisible;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#setStatusMessage(java.lang.String)
+     * @since 3.2
+     */
+    public void setStatusMessage(String message) {
+        Assert.isLegal(message !is null);
+        fMessage= message;
+        if (fProposalPopup !is null)
+            fProposalPopup.setMessage(message);
+    }
+
+    /**
+     * Returns the affordance caption for the cycling affordance at the bottom of the pop-up.
+     *
+     * @return the affordance caption for the cycling affordance at the bottom of the pop-up
+     * @since 3.2
+     */
+    String getStatusMessage() {
+        return fMessage;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistantExtension2#setEmptyMessage(java.lang.String)
+     * @since 3.2
+     */
+    public void setEmptyMessage(String message) {
+        Assert.isLegal(message !is null);
+        if (fProposalPopup !is null)
+            fProposalPopup.setEmptyMessage(message);
+    }
+
+    /**
+     * Fires a selection event, see {@link ICompletionListener}.
+     *
+     * @param proposal the selected proposal, possibly <code>null</code>
+     * @param smartToggle true if the smart toggle is on
+     * @since 3.2
+     */
+    void fireSelectionEvent(ICompletionProposal proposal, bool smartToggle) {
+        Object[] listeners= fCompletionListeners.getListeners();
+        for (int i= 0; i < listeners.length; i++) {
+            ICompletionListener listener= cast(ICompletionListener)listeners[i];
+            listener.selectionChanged(proposal, smartToggle);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistantExtension3#setInvocationTrigger(dwtx.jface.bindings.keys.KeySequence)
+     * @since 3.2
+     */
+    public void setRepeatedInvocationTrigger(KeySequence sequence) {
+        fRepeatedInvocationKeySequence= sequence;
+    }
+
+    /**
+     * Returns the repeated invocation key sequence.
+     *
+     * @return the repeated invocation key sequence or <code>null</code>, if none
+     * @since 3.2
+     */
+    KeySequence getRepeatedInvocationKeySequence() {
+        return fRepeatedInvocationKeySequence;
+    }
+
+    /**
+     * Returns whether proposal popup is active.
+     *
+     * @return <code>true</code> if the proposal popup is active, <code>false</code> otherwise
+     * @since 3.4
+     */
+    protected bool isProposalPopupActive(){
+        return fProposalPopup !is null && fProposalPopup.isActive();
+    }
+
+    /**
+     * Returns whether the context information popup is active.
+     *
+     * @return <code>true</code> if the context information popup is active, <code>false</code> otherwise
+     * @since 3.4
+     */
+    protected bool isContextInfoPopupActive(){
+        return fContextInfoPopup !is null && fContextInfoPopup.isActive();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 3.4
+     */
+    public final IHandler getHandler(String commandId) {
+        if (fHandlers is null)
+            throw new IllegalStateException();
+
+        IHandler handler= cast(IHandler)fHandlers.get(commandId);
+        if (handler !is null)
+            return handler;
+
+        Assert.isLegal(false);
+        return null;
+    }
+
+    /**
+     * Registers the given handler under the given command identifier.
+     *
+     * @param commandId the command identifier
+     * @param handler the handler
+     * @since 3.4
+     */
+    protected final void registerHandler(String commandId, IHandler handler) {
+        if (fHandlers is null)
+            fHandlers= new HashMap(2);
+        fHandlers.put(commandId, handler);
+    }
+
+    /**
+     * Tells whether the support for colored labels is enabled.
+     *
+     * @return <code>true</code> if the support for colored labels is enabled, <code>false</code> otherwise
+     * @since 3.4
+     */
+    bool isColoredLabelsSupportEnabled() {
+        return fIsColoredLabelsSupportEnabled;
+    }
+
+    /**
+     * Enables the support for colored labels in the proposal popup.
+     * <p>Completion proposals can implement {@link ICompletionProposalExtension6}
+     * to provide colored proposal labels.</p>
+     *
+     * @param isEnabled if <code>true</code> the support for colored labels is enabled in the proposal popup
+     * @since 3.4
+     */
+    public void enableColoredLabels(bool isEnabled) {
+        fIsColoredLabelsSupportEnabled= isEnabled;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ContextInformation.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ContextInformation;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.graphics.Image;
+import dwtx.core.runtime.Assert;
+
+
+
+/**
+ * A default implementation of the <code>IContextInformation</code> interface.
+ */
+public final class ContextInformation : IContextInformation {
+
+    /** The name of the context. */
+    private const String fContextDisplayString;
+    /** The information to be displayed. */
+    private const String fInformationDisplayString;
+    /** The image to be displayed. */
+    private const Image fImage;
+
+    /**
+     * Creates a new context information without an image.
+     *
+     * @param contextDisplayString the string to be used when presenting the context
+     * @param informationDisplayString the string to be displayed when presenting the context information
+     */
+    public this(String contextDisplayString, String informationDisplayString) {
+        this(null, contextDisplayString, informationDisplayString);
+    }
+
+    /**
+     * Creates a new context information with an image.
+     *
+     * @param image the image to display when presenting the context information
+     * @param contextDisplayString the string to be used when presenting the context
+     * @param informationDisplayString the string to be displayed when presenting the context information,
+     *      may not be <code>null</code>
+     */
+    public this(Image image, String contextDisplayString, String informationDisplayString) {
+
+        Assert.isNotNull(informationDisplayString);
+
+        fImage= image;
+        fContextDisplayString= contextDisplayString;
+        fInformationDisplayString= informationDisplayString;
+    }
+
+    /*
+     * @see IContextInformation#equals(Object)
+     */
+    public bool equals(Object object) {
+        if ( cast(IContextInformation)object ) {
+            IContextInformation contextInformation= cast(IContextInformation) object;
+            bool equals= fInformationDisplayString.equalsIgnoreCase(contextInformation.getInformationDisplayString());
+            if (fContextDisplayString !is null)
+                equals= equals && fContextDisplayString.equalsIgnoreCase(contextInformation.getContextDisplayString());
+            return equals;
+        }
+        return false;
+    }
+
+    /*
+     * @see java.lang.Object#hashCode()
+     * @since 3.1
+     */
+    public override hash_t toHash() {
+        int low= fContextDisplayString !is null ? .toHash(fContextDisplayString) : 0;
+        return (.toHash(fInformationDisplayString) << 16) | low;
+    }
+
+    /*
+     * @see IContextInformation#getInformationDisplayString()
+     */
+    public String getInformationDisplayString() {
+        return fInformationDisplayString;
+    }
+
+    /*
+     * @see IContextInformation#getImage()
+     */
+    public Image getImage() {
+        return fImage;
+    }
+
+    /*
+     * @see IContextInformation#getContextDisplayString()
+     */
+    public String getContextDisplayString() {
+        if (fContextDisplayString !is null)
+            return fContextDisplayString;
+        return fInformationDisplayString;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ContextInformationPopup.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,886 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ContextInformationPopup;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwt.DWT;
+import dwt.custom.BusyIndicator;
+import dwt.custom.StyledText;
+import dwt.events.KeyEvent;
+import dwt.events.SelectionAdapter;
+import dwt.events.SelectionEvent;
+import dwt.events.SelectionListener;
+import dwt.events.VerifyEvent;
+import dwt.graphics.Color;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.layout.GridData;
+import dwt.layout.GridLayout;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Shell;
+import dwt.widgets.Table;
+import dwt.widgets.TableItem;
+import dwtx.jface.contentassist.IContentAssistSubjectControl;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.TextPresentation;
+
+    /**
+     * Represents the state necessary for embedding contexts.
+     *
+     * @since 2.0
+     */
+    static class ContextFrame {
+
+        final int fBeginOffset;
+        final int fOffset;
+        final int fVisibleOffset;
+        final IContextInformation fInformation;
+        final IContextInformationValidator fValidator;
+        final IContextInformationPresenter fPresenter;
+
+        /*
+         * @since 3.1
+         */
+        public this(IContextInformation information, int beginOffset, int offset, int visibleOffset, IContextInformationValidator validator, IContextInformationPresenter presenter) {
+            fInformation = information;
+            fBeginOffset = beginOffset;
+            fOffset = offset;
+            fVisibleOffset = visibleOffset;
+            fValidator = validator;
+            fPresenter = presenter;
+        }
+
+        /*
+         * @see java.lang.Object#equals(java.lang.Object)
+         * @since 3.0
+         */
+        public override int opEquals(Object obj) {
+            if ( cast(ContextFrame)obj ) {
+                ContextFrame frame= cast(ContextFrame) obj;
+                return fInformation==/++/frame.fInformation && fBeginOffset is frame.fBeginOffset;
+            }
+            return super.opEquals(obj);
+        }
+
+        /*
+         * @see java.lang.Object#hashCode()
+         * @since 3.1
+         */
+        public override hash_t toHash() {
+            return ((cast(Object)fInformation).toHash() << 16) | fBeginOffset;
+        }
+    }
+
+    alias ContextFrame ContextInformationPopup_ContextFrame;
+/**
+ * This class is used to present context information to the user.
+ * If multiple contexts are valid at the current cursor location,
+ * a list is presented from which the user may choose one context.
+ * Once the user makes their choice, or if there was only a single
+ * possible context, the context information is shown in a tool tip like popup. <p>
+ * If the tool tip is visible and the user wants to see context information of
+ * a context embedded into the one for which context information is displayed,
+ * context information for the embedded context is shown. As soon as the
+ * cursor leaves the embedded context area, the context information for
+ * the embedding context is shown again.
+ *
+ * @see IContextInformation
+ * @see IContextInformationValidator
+ */
+class ContextInformationPopup : IContentAssistListener {
+
+
+
+    private ITextViewer fViewer;
+    private ContentAssistant fContentAssistant;
+
+    private PopupCloser fPopupCloser;
+    private Shell fContextSelectorShell;
+    private Table fContextSelectorTable;
+    private IContextInformation[] fContextSelectorInput;
+    private String fLineDelimiter= null;
+
+    private Shell fContextInfoPopup;
+    private StyledText fContextInfoText;
+    private TextPresentation fTextPresentation;
+
+    private Stack fContextFrameStack;
+    /**
+     * The content assist subject control.
+     *
+     * @since 3.0
+     */
+    private IContentAssistSubjectControl fContentAssistSubjectControl;
+    /**
+     * The content assist subject control adapter.
+     *
+     * @since 3.0
+     */
+    private ContentAssistSubjectControlAdapter fContentAssistSubjectControlAdapter;
+
+    /**
+     * Selection listener on the text widget which is active
+     * while a context information pop up is shown.
+     *
+     * @since 3.0
+     */
+    private SelectionListener fTextWidgetSelectionListener;
+
+    /**
+     * The last removed context frame is remembered in order to not re-query the
+     * user about which context should be used.
+     *
+     * @since 3.0
+     */
+    private ContextFrame fLastContext= null;
+
+    /**
+     * Creates a new context information popup.
+     *
+     * @param contentAssistant the content assist for computing the context information
+     * @param viewer the viewer on top of which the context information is shown
+     */
+    public this(ContentAssistant contentAssistant, ITextViewer viewer) {
+        fPopupCloser= new PopupCloser();
+        fContextFrameStack= new Stack();
+
+        fContentAssistant= contentAssistant;
+        fViewer= viewer;
+        fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fViewer);
+    }
+
+    /**
+     * Creates a new context information popup.
+     *
+     * @param contentAssistant the content assist for computing the context information
+     * @param contentAssistSubjectControl the content assist subject control on top of which the context information is shown
+     * @since 3.0
+     */
+    public this(ContentAssistant contentAssistant, IContentAssistSubjectControl contentAssistSubjectControl) {
+        fPopupCloser= new PopupCloser();
+        fContextFrameStack= new Stack();
+
+        fContentAssistant= contentAssistant;
+        fContentAssistSubjectControl= contentAssistSubjectControl;
+        fContentAssistSubjectControlAdapter= new ContentAssistSubjectControlAdapter(fContentAssistSubjectControl);
+    }
+
+    /**
+     * Shows all possible contexts for the given cursor position of the viewer.
+     *
+     * @param autoActivated <code>true</code>  if auto activated
+     * @return  a potential error message or <code>null</code> in case of no error
+     */
+    public String showContextProposals(bool autoActivated) {
+        final Control control= fContentAssistSubjectControlAdapter.getControl();
+        BusyIndicator.showWhile(control.getDisplay(), dgRunnable( {
+            int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
+
+            IContextInformation[] contexts= computeContextInformation(offset);
+            int count = (contexts is null ? 0 : contexts.length);
+            if (count is 1) {
+
+                ContextFrame frame= createContextFrame(contexts[0], offset);
+                if (isDuplicate(frame))
+                    validateContextInformation();
+                else
+                    // Show context information directly
+                    internalShowContextInfo(frame);
+
+            } else if (count > 0) {
+
+                // if any of the proposed context matches any of the contexts on the stack,
+                // assume that one (so, if context info is invoked repeatedly, the current
+                // info is kept)
+                for (int i= 0; i < contexts.length; i++) {
+                    IContextInformation info= contexts[i];
+                    ContextFrame frame= createContextFrame(info, offset);
+
+                    // check top of stack and stored context
+                    if (isDuplicate(frame)) {
+                        validateContextInformation();
+                        return;
+                    }
+
+                    if (isLastFrame(frame)) {
+                        internalShowContextInfo(frame);
+                        return;
+                    }
+
+                    // also check all other contexts
+                    for (Iterator it= fContextFrameStack.iterator(); it.hasNext(); ) {
+                        ContextFrame stackFrame= cast(ContextFrame) it.next();
+                        if (stackFrame==/++/frame) {
+                            validateContextInformation();
+                            return;
+                        }
+                    }
+                }
+
+                // otherwise:
+                // Precise context must be selected
+
+                if (fLineDelimiter is null)
+                    fLineDelimiter= fContentAssistSubjectControlAdapter.getLineDelimiter();
+
+                createContextSelector();
+                setContexts(contexts);
+                displayContextSelector();
+            }
+        }));
+
+        return getErrorMessage();
+    }
+
+    /**
+     * Displays the given context information for the given offset.
+     *
+     * @param info the context information
+     * @param offset the offset
+     * @since 2.0
+     */
+    public void showContextInformation(IContextInformation info, int offset) {
+        Control control= fContentAssistSubjectControlAdapter.getControl();
+        BusyIndicator.showWhile(control.getDisplay(), dgRunnable( (IContextInformation info_, int offset_){
+            if (info_ is null)
+                validateContextInformation();
+            else {
+                ContextFrame frame= createContextFrame(info_, offset_);
+                if (isDuplicate(frame))
+                    validateContextInformation();
+                else
+                    internalShowContextInfo(frame);
+                hideContextSelector();
+            }
+        }, info, offset ));
+    }
+
+    /**
+     * Displays the given context information for the given offset.
+     *
+     * @param frame the context frame to display, or <code>null</code>
+     * @since 3.0
+     */
+    private void internalShowContextInfo(ContextFrame frame) {
+        if (frame !is null) {
+            fContextFrameStack.push(frame);
+            if (fContextFrameStack.size() is 1)
+                fLastContext= null;
+            internalShowContextFrame(frame, fContextFrameStack.size() is 1);
+            validateContextInformation();
+        }
+    }
+
+    /**
+     * Creates a context frame for the given offset.
+     *
+     * @param information the context information
+     * @param offset the offset
+     * @return the created context frame
+     * @since 3.0
+     */
+    private ContextFrame createContextFrame(IContextInformation information, int offset) {
+        IContextInformationValidator validator= fContentAssistSubjectControlAdapter.getContextInformationValidator(fContentAssistant, offset);
+
+        if (validator !is null) {
+            int beginOffset= ( cast(IContextInformationExtension)information ) ? (cast(IContextInformationExtension) information).getContextInformationPosition() : offset;
+            if (beginOffset is -1) beginOffset= offset;
+            int visibleOffset= fContentAssistSubjectControlAdapter.getWidgetSelectionRange().x - (offset - beginOffset);
+            IContextInformationPresenter presenter = fContentAssistSubjectControlAdapter.getContextInformationPresenter(fContentAssistant, offset);
+            return new ContextFrame(information, beginOffset, offset, visibleOffset, validator, presenter);
+        }
+
+        return null;
+    }
+
+    /**
+     * Compares <code>frame</code> with the top of the stack, returns <code>true</code>
+     * if the frames are the same.
+     *
+     * @param frame the frame to check
+     * @return <code>true</code> if <code>frame</code> matches the top of the stack
+     * @since 3.0
+     */
+    private bool isDuplicate(ContextFrame frame) {
+        if (frame is null)
+            return false;
+        if (fContextFrameStack.isEmpty())
+            return false;
+        // stack not empty
+        ContextFrame top= cast(ContextFrame) fContextFrameStack.peek();
+        return cast(bool) frame.opEquals(top);
+    }
+
+    /**
+     * Compares <code>frame</code> with most recently removed context frame, returns <code>true</code>
+     * if the frames are the same.
+     *
+     * @param frame the frame to check
+     * @return <code>true</code> if <code>frame</code> matches the most recently removed
+     * @since 3.0
+     */
+    private bool isLastFrame(ContextFrame frame) {
+        return frame !is null && frame.opEquals(fLastContext);
+    }
+
+    /**
+     * Shows the given context frame.
+     *
+     * @param frame the frame to display
+     * @param initial <code>true</code> if this is the first frame to be displayed
+     * @since 2.0
+     */
+    private void internalShowContextFrame(ContextFrame frame, bool initial) {
+
+        fContentAssistSubjectControlAdapter.installValidator(frame);
+
+        if (frame.fPresenter !is null) {
+            if (fTextPresentation is null)
+                fTextPresentation= new TextPresentation();
+            fContentAssistSubjectControlAdapter.installContextInformationPresenter(frame);
+            frame.fPresenter.updatePresentation(frame.fOffset, fTextPresentation);
+        }
+
+        createContextInfoPopup();
+
+        fContextInfoText.setText(frame.fInformation.getInformationDisplayString());
+        if (fTextPresentation !is null)
+            TextPresentation.applyTextPresentation(fTextPresentation, fContextInfoText);
+        resize(frame.fVisibleOffset);
+
+        if (initial) {
+            if (fContentAssistant.addContentAssistListener(this, ContentAssistant.CONTEXT_INFO_POPUP)) {
+                if (fContentAssistSubjectControlAdapter.getControl() !is null) {
+                    fTextWidgetSelectionListener= new class()  SelectionAdapter {
+                        /*
+                         * @see dwt.events.SelectionAdapter#widgetSelected(dwt.events.SelectionEvent)
+                         */
+                        public void widgetSelected(SelectionEvent e) {
+                            validateContextInformation();
+                        }};
+                    fContentAssistSubjectControlAdapter.addSelectionListener(fTextWidgetSelectionListener);
+                }
+                fContentAssistant.addToLayout(this, fContextInfoPopup, ContentAssistant.LayoutManager.LAYOUT_CONTEXT_INFO_POPUP, frame.fVisibleOffset);
+                fContextInfoPopup.setVisible(true);
+            }
+        } else {
+            fContentAssistant.layout(ContentAssistant.LayoutManager.LAYOUT_CONTEXT_INFO_POPUP, frame.fVisibleOffset);
+        }
+    }
+
+    /**
+     * Computes all possible context information for the given offset.
+     *
+     * @param offset the offset
+     * @return all possible context information for the given offset
+     * @since 2.0
+     */
+    private IContextInformation[] computeContextInformation(int offset) {
+        return fContentAssistSubjectControlAdapter.computeContextInformation(fContentAssistant, offset);
+    }
+
+    /**
+     *Returns the error message generated while computing context information.
+     *
+     * @return the error message
+     */
+    private String getErrorMessage() {
+        return fContentAssistant.getErrorMessage();
+    }
+
+    /**
+     * Creates the context information popup. This is the tool tip like overlay window.
+     */
+    private void createContextInfoPopup() {
+        if (Helper.okToUse(fContextInfoPopup))
+            return;
+
+        Control control= fContentAssistSubjectControlAdapter.getControl();
+        Display display= control.getDisplay();
+
+        fContextInfoPopup= new Shell(control.getShell(), DWT.NO_TRIM | DWT.ON_TOP);
+        fContextInfoPopup.setBackground(display.getSystemColor(DWT.COLOR_BLACK));
+
+        fContextInfoText= new StyledText(fContextInfoPopup, DWT.MULTI | DWT.READ_ONLY | DWT.WRAP);
+
+        Color c= fContentAssistant.getContextInformationPopupBackground();
+        if (c is null)
+            c= display.getSystemColor(DWT.COLOR_INFO_BACKGROUND);
+        fContextInfoText.setBackground(c);
+
+        c= fContentAssistant.getContextInformationPopupForeground();
+        if (c is null)
+            c= display.getSystemColor(DWT.COLOR_INFO_FOREGROUND);
+        fContextInfoText.setForeground(c);
+    }
+
+    /**
+     * Resizes the context information popup.
+     *
+     * @param offset the caret offset in widget coordinates
+     * @since 2.0
+     */
+    private void resize(int offset) {
+        Point size= fContextInfoText.computeSize(DWT.DEFAULT, DWT.DEFAULT, true);
+        final int TEXT_PAD= 0;
+        final int BORDER_PAD= 2;
+        final int PAD= TEXT_PAD + BORDER_PAD;
+        size.x += PAD;
+        Rectangle bounds= fContentAssistant.getLayoutManager().computeBoundsAboveBelow_package(fContextInfoPopup, size, offset);
+        if (bounds.width < size.x)
+            // we don't fit on the screen - try again and wrap
+            size= fContextInfoText.computeSize(bounds.width - PAD, DWT.DEFAULT, true);
+
+        size.x += TEXT_PAD;
+        fContextInfoText.setSize(size);
+        fContextInfoText.setLocation(1,1);
+        size.x += BORDER_PAD;
+        size.y += BORDER_PAD;
+        fContextInfoPopup.setSize(size);
+    }
+
+    /**
+     * Hides the context information popup.
+     */
+    private void hideContextInfoPopup() {
+
+        if (Helper.okToUse(fContextInfoPopup)) {
+
+            int size= fContextFrameStack.size();
+            if (size > 0) {
+                fLastContext= cast(ContextFrame) fContextFrameStack.pop();
+                -- size;
+            }
+
+            if (size > 0) {
+                ContextFrame current= cast(ContextFrame) fContextFrameStack.peek();
+                internalShowContextFrame(current, false);
+            } else {
+
+                fContentAssistant.removeContentAssistListener(this, ContentAssistant.CONTEXT_INFO_POPUP);
+
+                if (fContentAssistSubjectControlAdapter.getControl() !is null)
+                    fContentAssistSubjectControlAdapter.removeSelectionListener(fTextWidgetSelectionListener);
+                fTextWidgetSelectionListener= null;
+
+                fContextInfoPopup.setVisible(false);
+                fContextInfoPopup.dispose();
+                fContextInfoPopup= null;
+
+                if (fTextPresentation !is null) {
+                    fTextPresentation.clear();
+                    fTextPresentation= null;
+                }
+            }
+        }
+
+        if (fContextInfoPopup is null)
+            fContentAssistant.contextInformationClosed_package();
+    }
+
+    /**
+     * Creates the context selector in case the user has the choice between multiple valid contexts
+     * at a given offset.
+     */
+    private void createContextSelector() {
+        if (Helper.okToUse(fContextSelectorShell))
+            return;
+
+        Control control= fContentAssistSubjectControlAdapter.getControl();
+        fContextSelectorShell= new Shell(control.getShell(), DWT.ON_TOP | DWT.RESIZE);
+        GridLayout layout= new GridLayout();
+        layout.marginWidth= 0;
+        layout.marginHeight= 0;
+        fContextSelectorShell.setLayout(layout);
+        fContextSelectorShell.setBackground(control.getDisplay().getSystemColor(DWT.COLOR_BLACK));
+
+
+        fContextSelectorTable= new Table(fContextSelectorShell, DWT.H_SCROLL | DWT.V_SCROLL);
+        fContextSelectorTable.setLocation(1, 1);
+        GridData gd= new GridData(GridData.FILL_BOTH);
+        gd.heightHint= fContextSelectorTable.getItemHeight() * 10;
+        gd.widthHint= 300;
+        fContextSelectorTable.setLayoutData(gd);
+
+        fContextSelectorShell.pack(true);
+
+        Color c= fContentAssistant.getContextSelectorBackground();
+        if (c is null)
+            c= control.getDisplay().getSystemColor(DWT.COLOR_INFO_BACKGROUND);
+        fContextSelectorTable.setBackground(c);
+
+        c= fContentAssistant.getContextSelectorForeground();
+        if (c is null)
+            c= control.getDisplay().getSystemColor(DWT.COLOR_INFO_FOREGROUND);
+        fContextSelectorTable.setForeground(c);
+
+        fContextSelectorTable.addSelectionListener(new class()  SelectionListener {
+            public void widgetSelected(SelectionEvent e) {
+            }
+
+            public void widgetDefaultSelected(SelectionEvent e) {
+                insertSelectedContext();
+                hideContextSelector();
+            }
+        });
+
+        fPopupCloser.install(fContentAssistant, fContextSelectorTable);
+
+        fContextSelectorTable.setHeaderVisible(false);
+        fContentAssistant.addToLayout(this, fContextSelectorShell, ContentAssistant.LayoutManager.LAYOUT_CONTEXT_SELECTOR, fContentAssistant.getSelectionOffset());
+    }
+
+    /**
+     * Returns the minimal required height for the popup, may return 0 if the popup has not been
+     * created yet.
+     *
+     * @return the minimal height
+     * @since 3.3
+     */
+    int getMinimalHeight() {
+        int height= 0;
+        if (Helper.okToUse(fContextSelectorTable)) {
+            int items= fContextSelectorTable.getItemHeight() * 10;
+            Rectangle trim= fContextSelectorTable.computeTrim(0, 0, DWT.DEFAULT, items);
+            height= trim.height;
+        }
+        return height;
+    }
+
+    /**
+     * Causes the context information of the context selected in the context selector
+     * to be displayed in the context information popup.
+     */
+    private void insertSelectedContext() {
+        int i= fContextSelectorTable.getSelectionIndex();
+
+        if (i < 0 || i >= fContextSelectorInput.length)
+            return;
+
+        int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
+        internalShowContextInfo(createContextFrame(fContextSelectorInput[i], offset));
+    }
+
+    /**
+     * Sets the contexts in the context selector to the given set.
+     *
+     * @param contexts the possible contexts
+     */
+    private void setContexts(IContextInformation[] contexts) {
+        if (Helper.okToUse(fContextSelectorTable)) {
+
+            fContextSelectorInput= contexts;
+
+            fContextSelectorTable.setRedraw(false);
+            fContextSelectorTable.removeAll();
+
+            TableItem item;
+            IContextInformation t;
+            for (int i= 0; i < contexts.length; i++) {
+                t= contexts[i];
+                item= new TableItem(fContextSelectorTable, DWT.NULL);
+                if (t.getImage() !is null)
+                    item.setImage(t.getImage());
+                item.setText(t.getContextDisplayString());
+            }
+
+            fContextSelectorTable.select(0);
+            fContextSelectorTable.setRedraw(true);
+        }
+    }
+
+    /**
+     * Displays the context selector.
+     */
+    private void displayContextSelector() {
+        if (fContentAssistant.addContentAssistListener(this, ContentAssistant.CONTEXT_SELECTOR))
+            fContextSelectorShell.setVisible(true);
+    }
+
+    /**
+     * Hides the context selector.
+     */
+    private void hideContextSelector() {
+        if (Helper.okToUse(fContextSelectorShell)) {
+            fContentAssistant.removeContentAssistListener(this, ContentAssistant.CONTEXT_SELECTOR);
+
+            fPopupCloser.uninstall();
+            fContextSelectorShell.setVisible(false);
+            fContextSelectorShell.dispose();
+            fContextSelectorShell= null;
+        }
+
+        if (!Helper.okToUse(fContextInfoPopup))
+            fContentAssistant.contextInformationClosed_package();
+    }
+
+    /**
+     *Returns whether the context selector has the focus.
+     *
+     * @return <code>true</code> if the context selector has the focus
+     */
+    public bool hasFocus() {
+        if (Helper.okToUse(fContextSelectorShell))
+            return (fContextSelectorShell.isFocusControl() || fContextSelectorTable.isFocusControl());
+
+        return false;
+    }
+
+    /**
+     * Hides context selector and context information popup.
+     */
+    public void hide() {
+        hideContextSelector();
+        hideContextInfoPopup();
+    }
+
+    /**
+     * Returns whether this context information popup is active. I.e., either
+     * a context selector or context information is displayed.
+     *
+     * @return <code>true</code> if the context selector is active
+     */
+    public bool isActive() {
+        return (Helper.okToUse(fContextInfoPopup) || Helper.okToUse(fContextSelectorShell));
+    }
+
+    /*
+     * @see IContentAssistListener#verifyKey(VerifyEvent)
+     */
+    public bool verifyKey(VerifyEvent e) {
+        if (Helper.okToUse(fContextSelectorShell))
+            return contextSelectorKeyPressed(e);
+        if (Helper.okToUse(fContextInfoPopup))
+            return contextInfoPopupKeyPressed(e);
+        return true;
+    }
+
+    /**
+     * Processes a key stroke in the context selector.
+     *
+     * @param e the verify event describing the key stroke
+     * @return <code>true</code> if processing can be stopped
+     */
+    private bool contextSelectorKeyPressed(VerifyEvent e) {
+
+        char key= e.character;
+        if (key is 0) {
+
+            int newSelection= fContextSelectorTable.getSelectionIndex();
+            int visibleRows= (fContextSelectorTable.getSize().y / fContextSelectorTable.getItemHeight()) - 1;
+            int itemCount= fContextSelectorTable.getItemCount();
+            switch (e.keyCode) {
+                case DWT.ARROW_UP :
+                    newSelection -= 1;
+                    if (newSelection < 0)
+                        newSelection= itemCount - 1;
+                    break;
+
+                case DWT.ARROW_DOWN :
+                    newSelection += 1;
+                    if (newSelection > itemCount - 1)
+                        newSelection= 0;
+                    break;
+
+                case DWT.PAGE_DOWN :
+                    newSelection += visibleRows;
+                    if (newSelection >= itemCount)
+                        newSelection= itemCount - 1;
+                    break;
+
+                case DWT.PAGE_UP :
+                    newSelection -= visibleRows;
+                    if (newSelection < 0)
+                        newSelection= 0;
+                    break;
+
+                case DWT.HOME :
+                    newSelection= 0;
+                    break;
+
+                case DWT.END :
+                    newSelection= itemCount - 1;
+                    break;
+
+                default :
+                    if (e.keyCode !is DWT.CAPS_LOCK && e.keyCode !is DWT.MOD1 && e.keyCode !is DWT.MOD2 && e.keyCode !is DWT.MOD3 && e.keyCode !is DWT.MOD4)
+                        hideContextSelector();
+                    return true;
+            }
+
+            fContextSelectorTable.setSelection(newSelection);
+            fContextSelectorTable.showSelection();
+            e.doit= false;
+            return false;
+
+        } else if ('\t' is key) {
+            // switch focus to selector shell
+            e.doit= false;
+            fContextSelectorShell.setFocus();
+            return false;
+        } else if (key is DWT.ESC) {
+            e.doit= false;
+            hideContextSelector();
+        }
+
+        return true;
+    }
+
+    /**
+     * Processes a key stroke while the info popup is up.
+     *
+     * @param e the verify event describing the key stroke
+     * @return <code>true</code> if processing can be stopped
+     */
+    private bool contextInfoPopupKeyPressed(KeyEvent e) {
+
+        char key= e.character;
+        if (key is 0) {
+
+            switch (e.keyCode) {
+                case DWT.ARROW_LEFT:
+                case DWT.ARROW_RIGHT:
+                    validateContextInformation();
+                    break;
+                default:
+                    if (e.keyCode !is DWT.CAPS_LOCK && e.keyCode !is DWT.MOD1 && e.keyCode !is DWT.MOD2 && e.keyCode !is DWT.MOD3 && e.keyCode !is DWT.MOD4)
+                        hideContextInfoPopup();
+                    break;
+            }
+
+        } else if (key is DWT.ESC) {
+            e.doit= false;
+            hideContextInfoPopup();
+        } else {
+            validateContextInformation();
+        }
+        return true;
+    }
+
+    /*
+     * @see IEventConsumer#processEvent(VerifyEvent)
+     */
+    public void processEvent(VerifyEvent event) {
+        if (Helper.okToUse(fContextSelectorShell))
+            contextSelectorProcessEvent(event);
+        if (Helper.okToUse(fContextInfoPopup))
+            contextInfoPopupProcessEvent(event);
+    }
+
+    /**
+     * Processes a key stroke in the context selector.
+     *
+     * @param e the verify event describing the key stroke
+     */
+    private void contextSelectorProcessEvent(VerifyEvent e) {
+
+        if (e.start is e.end && e.text !is null && e.text.equals(fLineDelimiter)) {
+            e.doit= false;
+            insertSelectedContext();
+        }
+
+        hideContextSelector();
+    }
+
+    /**
+     * Processes a key stroke while the info popup is up.
+     *
+     * @param e the verify event describing the key stroke
+     */
+    private void contextInfoPopupProcessEvent(VerifyEvent e) {
+        if (e.start !is e.end && (e.text is null || e.text.length() is 0))
+            validateContextInformation();
+    }
+
+    /**
+     * Validates the context information for the viewer's actual cursor position.
+     */
+    private void validateContextInformation() {
+        /*
+         * Post the code in the event queue in order to ensure that the
+         * action described by this verify key event has already been executed.
+         * Otherwise, we'd validate the context information based on the
+         * pre-key-stroke state.
+         */
+        if (!Helper.okToUse(fContextInfoPopup))
+            return;
+
+        fContextInfoPopup.getDisplay().asyncExec(new class()  Runnable {
+
+            private ContextFrame fFrame;
+
+            this() {
+                fFrame= cast(ContextFrame) fContextFrameStack.peek();
+            }
+
+            public void run() {
+                // only do this if no other frames have been added in between
+                if (!fContextFrameStack.isEmpty() && fFrame is fContextFrameStack.peek()) {
+                    int offset= fContentAssistSubjectControlAdapter.getSelectedRange().x;
+
+                    // iterate all contexts on the stack
+                    while (Helper.okToUse(fContextInfoPopup) && !fContextFrameStack.isEmpty()) {
+                        ContextFrame top= cast(ContextFrame) fContextFrameStack.peek();
+                        if (top.fValidator is null || !top.fValidator.isContextInformationValid(offset)) {
+                            hideContextInfoPopup(); // loop variant: reduces the number of contexts on the stack
+                        } else if (top.fPresenter !is null && top.fPresenter.updatePresentation(offset, fTextPresentation)) {
+                            int widgetOffset= fContentAssistSubjectControlAdapter.getWidgetSelectionRange().x;
+                            TextPresentation.applyTextPresentation(fTextPresentation, fContextInfoText);
+                            resize(widgetOffset);
+                            break;
+                        } else
+                            break;
+                    }
+                }
+            }
+        });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ContextInformationValidator.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ContextInformationValidator;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * A default implementation of the <code>IContextInfomationValidator</code> interface.
+ * This implementation determines whether the information is valid by asking the content
+ * assist processor for all  context information objects for the current position. If the
+ * currently displayed information is in the result set, the context information is
+ * considered valid.
+ */
+public final class ContextInformationValidator : IContextInformationValidator {
+
+    /** The content assist processor. */
+    private IContentAssistProcessor fProcessor;
+    /** The context information to be validated. */
+    private IContextInformation fContextInformation;
+    /** The associated text viewer. */
+    private ITextViewer fViewer;
+
+    /**
+     * Creates a new context information validator which is ready to be installed on
+     * a particular context information.
+     *
+     * @param processor the processor to be used for validation
+     */
+    public this(IContentAssistProcessor processor) {
+        fProcessor= processor;
+    }
+
+    /*
+     * @see IContextInformationValidator#install(IContextInformation, ITextViewer, int)
+     */
+    public void install(IContextInformation contextInformation, ITextViewer viewer, int offset) {
+        fContextInformation= contextInformation;
+        fViewer= viewer;
+    }
+
+    /*
+     * @see IContentAssistTipCloser#isContextInformationValid(int)
+     */
+    public bool isContextInformationValid(int offset) {
+        IContextInformation[] infos= fProcessor.computeContextInformation(fViewer, offset);
+        if (infos !is null && infos.length > 0) {
+            for (int i= 0; i < infos.length; i++)
+                if (fContextInformation==/+eq+/infos[i])
+                    return true;
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/Helper.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.Helper;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.widgets.Widget;
+
+
+/**
+ * Helper class for testing widget state.
+ */
+class Helper {
+
+    /**
+     * Returns whether the widget is <code>null</code> or disposed.
+     *
+     * @param widget the widget to check
+     * @return <code>true</code> if the widget is neither <code>null</code> nor disposed
+     */
+    public static bool okToUse(Widget widget) {
+        return (widget !is null && !widget.isDisposed());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ICompletionListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ICompletionListener;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A completion listener is informed before the content assistant computes completion proposals.
+ * <p>
+ * In order to provide backward compatibility for clients of <code>ICompletionListener</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ *   <li>{@link dwtx.jface.text.contentassist.ICompletionListenerExtension} since version 3.4 introducing
+ *      the following functions:
+ *      <ul>
+ *          <li>additional notification about restarting the current code assist session</li>
+ *      </ul>
+ *   </li>
+ * </ul>
+ * </p>
+ *
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ * 
+ * @since 3.2
+ */
+public interface ICompletionListener {
+    /**
+     * Called when code assist is invoked when there is no current code assist session.
+     * 
+     * @param event the content assist event
+     */
+    void assistSessionStarted(ContentAssistEvent event);
+
+    /**
+     * Called when a code assist session ends (for example, the proposal popup is closed).
+     * 
+     * @param event the content assist event
+     */
+    void assistSessionEnded(ContentAssistEvent event);
+
+    /**
+     * Called when the selection in the proposal popup is changed or if the insert-mode changed.
+     * 
+     * @param proposal the newly selected proposal, possibly <code>null</code>
+     * @param smartToggle <code>true</code> if the insert-mode toggle is being pressed,
+     *        <code>false</code> otherwise
+     */
+    void selectionChanged(ICompletionProposal proposal, bool smartToggle);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ICompletionListenerExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ICompletionListenerExtension;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.ICompletionListener}
+ * with an additional notification about restarting the current code assist session.
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ * 
+ * @since 3.4
+ */
+public interface ICompletionListenerExtension {
+    /**
+     * Called when code assist is invoked when there is already a current code assist session.
+     * 
+     * @param event the content assist event
+     */
+    void assistSessionRestarted(ContentAssistEvent event);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ICompletionProposal.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ICompletionProposal;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.graphics.Image;
+import dwt.graphics.Point;
+import dwtx.jface.text.IDocument;
+
+
+/**
+ * The interface of completion proposals generated by content assist processors.
+ * A completion proposal contains information used to present the proposed completion
+ * to the user, to insert the completion should the user select it, and to present
+ * context information for the chosen completion once it has been inserted.
+ * <p>
+ * In order to provide backward compatibility for clients of <code>ICompletionProposal</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.contentassist.ICompletionProposalExtension} since version 2.0 introducing
+ *      the following functions:
+ *          <ul>
+ *              <li>handling of trigger characters other than ENTER</li>
+ *              <li>completion proposal validation for a given offset</li>
+ *              <li>context information can be freely positioned</li>
+ *          </ul>
+ * </li>
+ * <li>{@link dwtx.jface.text.contentassist.ICompletionProposalExtension2} since version 2.1 introducing
+ *      the following functions:
+ *          <ul>
+ *              <li>handling of trigger characters with modifiers</li>
+ *              <li>visual indication for selection of a proposal</li>
+ *          </ul>
+ * </li>
+ * <li>{@link dwtx.jface.text.contentassist.ICompletionProposalExtension3} since version 3.0 introducing
+ *      the following functions:
+ *          <ul>
+ *              <li>provision of a custom information control creator</li>
+ *              <li>provide a custom completion text and offset for prefix completion</li>
+ *          </ul>
+ * </li>
+ * <li>{@link dwtx.jface.text.contentassist.ICompletionProposalExtension4} since version 3.1 introducing
+ *      the following functions:
+ *          <ul>
+ *              <li>specify whether a proposal is automatically insertable</li>
+ *          </ul>
+ * </li>
+ * <li>{@link dwtx.jface.text.contentassist.ICompletionProposalExtension5} since version 3.2 introducing
+ *      the following function:
+ *          <ul>
+ *              <li>Allow background computation of the additional info</li>
+ *          </ul>
+ * </li>
+ * <li>{@link dwtx.jface.text.contentassist.ICompletionProposalExtension6} since version 3.4 introducing
+ *      the following function:
+ *          <ul>
+ *              <li>Allow styled ranges in the display string.</li>
+ *          </ul>
+ * </li>
+ * </ul>
+ * </p>
+ * <p>
+ * This interface can be implemented by clients. By default, clients use
+ * {@link dwtx.jface.text.contentassist.CompletionProposal} as the
+ * standard implementer of this interface.
+ * </p>
+ *
+ * @see IContentAssistProcessor
+ */
+public interface ICompletionProposal {
+
+    /**
+     * Inserts the proposed completion into the given document.
+     *
+     * @param document the document into which to insert the proposed completion
+     */
+    void apply(IDocument document);
+
+    /**
+     * Returns the new selection after the proposal has been applied to
+     * the given document in absolute document coordinates. If it returns
+     * <code>null</code>, no new selection is set.
+     *
+     * A document change can trigger other document changes, which have
+     * to be taken into account when calculating the new selection. Typically,
+     * this would be done by installing a document listener or by using a
+     * document position during {@link #apply(IDocument)}.
+     *
+     * @param document the document into which the proposed completion has been inserted
+     * @return the new selection in absolute document coordinates
+     */
+    Point getSelection(IDocument document);
+
+    /**
+     * Returns optional additional information about the proposal. The additional information will
+     * be presented to assist the user in deciding if the selected proposal is the desired choice.
+     * <p>
+     * If {@link ICompletionProposalExtension5} is implemented, this method should not be called any
+     * longer. This method may be deprecated in a future release.
+     * </p>
+     * 
+     * @return the additional information or <code>null</code>
+     */
+    String getAdditionalProposalInfo();
+
+    /**
+     * Returns the string to be displayed in the list of completion proposals.
+     *
+     * @return the string to be displayed
+     */
+    String getDisplayString();
+
+    /**
+     * Returns the image to be displayed in the list of completion proposals.
+     * The image would typically be shown to the left of the display string.
+     *
+     * @return the image to be shown or <code>null</code> if no image is desired
+     */
+    Image getImage();
+
+    /**
+     * Returns optional context information associated with this proposal.
+     * The context information will automatically be shown if the proposal
+     * has been applied.
+     *
+     * @return the context information for this proposal or <code>null</code>
+     */
+    IContextInformation getContextInformation();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ICompletionProposalExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,103 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ICompletionProposalExtension;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.IDocument;
+
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.ICompletionProposal}
+ * with the following functions:
+ * <ul>
+ *  <li>handling of trigger characters other than ENTER</li>
+ *  <li>completion proposal validation for a given offset</li>
+ *  <li>context information can be freely positioned</li>
+ * </ul>
+ *
+ * @since 2.0
+ */
+public interface ICompletionProposalExtension {
+
+    /**
+     * Applies the proposed completion to the given document. The insertion
+     * has been triggered by entering the given character at the given offset.
+     * This method assumes that {@link #isValidFor(IDocument, int)} returns
+     * <code>true</code> if called for <code>offset</code>.
+     *
+     * @param document the document into which to insert the proposed completion
+     * @param trigger the trigger to apply the completion
+     * @param offset the offset at which the trigger has been activated
+     */
+    void apply(IDocument document, char trigger, int offset);
+
+    /**
+     * Returns whether this completion proposal is valid for the given
+     * position in the given document.
+     *
+     * @param document the document for which the proposal is tested
+     * @param offset the offset for which the proposal is tested
+     * @return <code>true</code> iff valid
+     */
+    bool isValidFor(IDocument document, int offset);
+
+    /**
+     * Returns the characters which trigger the application of this completion proposal.
+     *
+     * @return the completion characters for this completion proposal or <code>null</code>
+     *      if no completion other than the new line character is possible
+     */
+    char[] getTriggerCharacters();
+
+    /**
+     * Returns the position to which the computed context information refers to or
+     * <code>-1</code> if no context information can be provided by this completion proposal.
+     *
+     * @return the position to which the context information refers to or <code>-1</code> for no information
+     */
+    int getContextInformationPosition();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ICompletionProposalExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ICompletionProposalExtension2;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.ICompletionProposal}
+ * with the following functions:
+ * <ul>
+ *  <li>handling of trigger characters with modifiers</li>
+ *  <li>visual indication for selection of a proposal</li>
+ * </ul>
+ *
+ * @since 2.1
+ */
+public interface ICompletionProposalExtension2 {
+
+    /**
+     * Applies the proposed completion to the given document. The insertion
+     * has been triggered by entering the given character with a modifier at the given offset.
+     * This method assumes that {@link #validate(IDocument, int, DocumentEvent)}
+     * returns <code>true</code> if called for <code>offset</code>.
+     *
+     * @param viewer the text viewer into which to insert the proposed completion
+     * @param trigger the trigger to apply the completion
+     * @param stateMask the state mask of the modifiers
+     * @param offset the offset at which the trigger has been activated
+     */
+    void apply(ITextViewer viewer, char trigger, int stateMask, int offset);
+
+    /**
+     * Called when the proposal is selected.
+     *
+     * @param viewer the text viewer.
+     * @param smartToggle the smart toggle key was pressed
+     */
+    void selected(ITextViewer viewer, bool smartToggle);
+
+    /**
+     * Called when the proposal is unselected.
+     *
+     * @param viewer the text viewer.
+     */
+    void unselected(ITextViewer viewer);
+
+    /**
+     * Requests the proposal to be validated with respect to the document event.
+     * If the proposal cannot be validated, the methods returns <code>false</code>.
+     * If the document event was <code>null</code>, only the caret offset was changed, but not the document.
+     *
+     * This method replaces {@link ICompletionProposalExtension#isValidFor(IDocument, int)}
+     *
+     * @param document the document
+     * @param offset the caret offset
+     * @param event the document event, may be <code>null</code>
+     * @return bool
+     */
+    bool validate(IDocument document, int offset, DocumentEvent event);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ICompletionProposalExtension3.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ICompletionProposalExtension3;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IInformationControlCreator;
+
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.ICompletionProposal}
+ * with the following functions:
+ * <ul>
+ *  <li>provision of a custom information control creator</li>
+ *  <li>provide a custom completion text and offset for prefix completion</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public interface ICompletionProposalExtension3 {
+    /**
+     * Returns the information control creator of this completion proposal.
+     *
+     * @return the information control creator, or <code>null</code> if no custom control creator is available
+     */
+    IInformationControlCreator getInformationControlCreator();
+
+    /**
+     * Returns the string that would be inserted at the position returned from
+     * {@link #getPrefixCompletionStart(IDocument, int)} if this proposal was
+     * applied. If the replacement string cannot be determined,
+     * <code>null</code> may be returned.
+     *
+     * @param document the document that the receiver applies to
+     * @param completionOffset the offset into <code>document</code> where the
+     *        completion takes place
+     * @return the replacement string or <code>null</code> if it cannot be
+     *         determined
+     */
+    CharSequence getPrefixCompletionText(IDocument document, int completionOffset);
+
+    /**
+     * Returns the document offset at which the receiver would insert its
+     * proposal.
+     *
+     * @param document the document that the receiver applies to
+     * @param completionOffset the offset into <code>document</code> where the
+     *        completion takes place
+     * @return the offset at which the proposal would insert its proposal
+     */
+    int getPrefixCompletionStart(IDocument document, int completionOffset);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ICompletionProposalExtension4.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ICompletionProposalExtension4;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extends
+ * {@link dwtx.jface.text.contentassist.ICompletionProposal} with
+ * the following functions:
+ * <ul>
+ *   <li>specify whether a proposal is automatically insertable</li>
+ * </ul>
+ * 
+ * @since 3.1
+ */
+public interface ICompletionProposalExtension4 {
+
+    /**
+     * Returns <code>true</code> if the proposal may be automatically
+     * inserted, <code>false</code> otherwise. Automatic insertion can
+     * happen if the proposal is the only one being proposed, in which
+     * case the content assistant may decide to not prompt the user with
+     * a list of proposals, but simply insert the single proposal. A
+     * proposal may veto this behavior by returning <code>false</code>
+     * to a call to this method.
+     * 
+     * @return <code>true</code> if the proposal may be inserted
+     *         automatically, <code>false</code> if not
+     */
+    bool isAutoInsertable();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ICompletionProposalExtension5.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ICompletionProposalExtension5;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.IProgressMonitor;
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.ICompletionProposal} with the following
+ * function:
+ * <ul>
+ * <li>Allow background computation of the additional info.</li>
+ * </ul>
+ * 
+ * @since 3.2
+ */
+public interface ICompletionProposalExtension5 {
+    /**
+     * Returns additional information about the proposal. The additional information will be
+     * presented to assist the user in deciding if the selected proposal is the desired choice.
+     * <p>
+     * This method may be called on a non-UI thread.
+     * </p>
+     * <p>
+     * By default, the returned information is converted to a string and displayed as text; if
+     * {@link ICompletionProposalExtension3#getInformationControlCreator()} is implemented, the
+     * information will be passed to a custom information control for display.
+     * </p>
+     * 
+     * @param monitor a monitor to report progress and to watch for
+     *        {@link IProgressMonitor#isCanceled() cancelation}.
+     * @return the additional information, <code>null</code> for no information
+     */
+    Object getAdditionalProposalInfo(IProgressMonitor monitor);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/ICompletionProposalExtension6.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.ICompletionProposalExtension6;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.viewers.StyledString;
+
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.ICompletionProposal} with the following
+ * function:
+ * <ul>
+ *  <li>Allow styled ranges in the display string.</li>
+ * </ul>
+ * 
+ * @since 3.4
+ */
+public interface ICompletionProposalExtension6 {
+    
+    /**
+     * Returns the styled string used to display this proposal in the list of completion proposals.
+     * This can for example be used to draw mixed colored labels.
+     * <p>
+     * <strong>Note:</strong> {@link ICompletionProposal#getDisplayString()} still needs to be
+     * correctly implemented as this method might be ignored in case of uninstalled owner draw
+     * support.
+     * </p>
+     * 
+     * @return the string builder used to display this proposal
+     */
+    StyledString getStyledDisplayString();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/IContentAssistListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.IContentAssistListener;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.events.VerifyEvent;
+import dwtx.jface.text.IEventConsumer;
+
+
+/**
+ * An interface whereby listeners can not only receive key events,
+ * but can also consume them to prevent subsequent listeners from
+ * processing the event.
+ */
+interface IContentAssistListener : IEventConsumer {
+
+    /**
+     * Verifies the key event.
+     *
+     * @param event the verify event
+     * @return <code>true</code> if processing should be continued by additional listeners
+     * @see dwt.custom.VerifyKeyListener#verifyKey(VerifyEvent)
+     */
+    public bool verifyKey(VerifyEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/IContentAssistProcessor.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.IContentAssistProcessor;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * A content assist processor proposes completions and
+ * computes context information for a particular content type.
+ * A content assist processor is a {@link dwtx.jface.text.contentassist.IContentAssistant}
+ * plug-in.
+ * <p>
+ * This interface must be implemented by clients. Implementers should be
+ * registered with a content assistant in order to get involved in the
+ * assisting process.
+ * </p>
+*/
+public interface IContentAssistProcessor {
+
+    /**
+     * Returns a list of completion proposals based on the
+     * specified location within the document that corresponds
+     * to the current cursor position within the text viewer.
+     *
+     * @param viewer the viewer whose document is used to compute the proposals
+     * @param offset an offset within the document for which completions should be computed
+     * @return an array of completion proposals or <code>null</code> if no proposals are possible
+     */
+    ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset);
+
+    /**
+     * Returns information about possible contexts based on the
+     * specified location within the document that corresponds
+     * to the current cursor position within the text viewer.
+     *
+     * @param viewer the viewer whose document is used to compute the possible contexts
+     * @param offset an offset within the document for which context information should be computed
+     * @return an array of context information objects or <code>null</code> if no context could be found
+     */
+    IContextInformation[] computeContextInformation(ITextViewer viewer, int offset);
+
+    /**
+     * Returns the characters which when entered by the user should
+     * automatically trigger the presentation of possible completions.
+     *
+     * @return the auto activation characters for completion proposal or <code>null</code>
+     *      if no auto activation is desired
+     */
+    char[] getCompletionProposalAutoActivationCharacters();
+
+    /**
+     * Returns the characters which when entered by the user should
+     * automatically trigger the presentation of context information.
+     *
+     * @return the auto activation characters for presenting context information
+     *      or <code>null</code> if no auto activation is desired
+     */
+    char[] getContextInformationAutoActivationCharacters();
+
+    /**
+     * Returns the reason why this content assist processor
+     * was unable to produce any completion proposals or context information.
+     *
+     * @return an error message or <code>null</code> if no error occurred
+     */
+    String getErrorMessage();
+
+    /**
+     * Returns a validator used to determine when displayed context information
+     * should be dismissed. May only return <code>null</code> if the processor is
+     * incapable of computing context information. <p>
+     *
+     * @return a context information validator, or <code>null</code> if the processor
+     *          is incapable of computing context information
+     */
+    IContextInformationValidator getContextInformationValidator();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/IContentAssistant.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,165 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.IContentAssistant;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * An <code>IContentAssistant</code> provides support on interactive content completion.
+ * The content assistant is a {@link dwtx.jface.text.ITextViewer} add-on. Its
+ * purpose is to propose, display, and insert completions of the content
+ * of the text viewer's document at the viewer's cursor position. In addition
+ * to handle completions, a content assistant can also be requested to provide
+ * context information. Context information is shown in a tool tip like popup.
+ * As it is not always possible to determine the exact context at a given
+ * document offset, a content assistant displays the possible contexts and requests
+ * the user to choose the one whose information should be displayed.
+ * <p>
+ * A content assistant has a list of {@link dwtx.jface.text.contentassist.IContentAssistProcessor}
+ * objects each of which is registered for a  particular document content
+ * type. The content assistant uses the processors to react on the request
+ * of completing documents or presenting context information.
+ * </p>
+ * <p>
+ * In order to provide backward compatibility for clients of <code>IContentAssistant</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.contentassist.IContentAssistantExtension} since version 3.0 introducing
+ *      the following functions:
+ *          <ul>
+ *              <li>handle documents with multiple partitions</li>
+ *              <li>insertion of common completion prefixes</li>
+ *          </ul>
+ * </li>
+ * <li>{@link dwtx.jface.text.contentassist.IContentAssistantExtension2} since version 3.2 introducing
+ *      the following functions:
+ *          <ul>
+ *              <li>repeated invocation (cycling) mode</li>
+ *              <li>completion listeners</li>
+ *              <li>a local status line for the completion popup</li>
+ *              <li>control over the behavior when no proposals are available</li>
+ *          </ul>
+ * </li>
+ * <li>{@link dwtx.jface.text.contentassist.IContentAssistantExtension3} since version 3.2 introducing
+ *      the following function:
+ *          <ul>
+ *              <li>a key-sequence to listen for in repeated invocation mode</li>
+ *          </ul>
+ * </li>
+ * <li>{@link dwtx.jface.text.contentassist.IContentAssistantExtension4} since version 3.4 introducing
+ *      the following function:
+ *          <ul>
+ *              <li>allows to get a handler for the given command identifier</li>
+ *          </ul>
+ * </li>
+ * </ul>
+ * </p>
+ * <p>
+ * The interface can be implemented by clients. By default, clients use
+ * {@link dwtx.jface.text.contentassist.ContentAssistant} as the standard
+ * implementer of this interface.
+ * </p>
+ *
+ * @see dwtx.jface.text.ITextViewer
+ * @see dwtx.jface.text.contentassist.IContentAssistProcessor
+ */
+ public interface IContentAssistant {
+
+    //------ proposal popup orientation styles ------------
+    /** The context info list will overlay the list of completion proposals. */
+    public const static int PROPOSAL_OVERLAY= 10;
+    /** The completion proposal list will be removed before the context info list will be shown. */
+    public const static int PROPOSAL_REMOVE=  11;
+    /** The context info list will be presented without hiding or overlapping the completion proposal list. */
+    public const static int PROPOSAL_STACKED= 12;
+
+    //------ context info box orientation styles ----------
+    /** Context info will be shown above the location it has been requested for without hiding the location. */
+    public const static int CONTEXT_INFO_ABOVE= 20;
+    /** Context info will be shown below the location it has been requested for without hiding the location. */
+    public const static int CONTEXT_INFO_BELOW= 21;
+
+
+    /**
+     * Installs content assist support on the given text viewer.
+     *
+     * @param textViewer the text viewer on which content assist will work
+     */
+    void install(ITextViewer textViewer);
+
+    /**
+     * Uninstalls content assist support from the text viewer it has
+     * previously be installed on.
+     */
+    void uninstall();
+
+    /**
+     * Shows all possible completions of the content at the viewer's cursor position.
+     *
+     * @return an optional error message if no proposals can be computed
+     */
+    String showPossibleCompletions();
+
+    /**
+     * Shows context information for the content at the viewer's cursor position.
+     *
+     * @return an optional error message if no context information can be computed
+     */
+    String showContextInformation();
+
+    /**
+     * Returns the content assist processor to be used for the given content type.
+     *
+     * @param contentType the type of the content for which this
+     *        content assistant is to be requested
+     * @return an instance content assist processor or
+     *         <code>null</code> if none exists for the specified content type
+     */
+    IContentAssistProcessor getContentAssistProcessor(String contentType);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/IContentAssistantExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.IContentAssistantExtension;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.IContentAssistant}
+ * with the following functions:
+ * <ul>
+ *  <li>handle documents with multiple partitions</li>
+ *  <li>insertion of common completion prefixes</li>
+ * </ul>
+ *
+ * @since 3.0
+ */
+public interface IContentAssistantExtension {
+
+    /**
+     * Returns the document partitioning this content assistant is using.
+     *
+     * @return the document partitioning this content assistant is using
+     */
+    String getDocumentPartitioning();
+
+    /**
+     * Inserts the common prefix of the available completions. If no common
+     * prefix can be computed it is identical to
+     * {@link IContentAssistant#showPossibleCompletions()}.
+     *
+     * @return an optional error message if no proposals can be computed
+     */
+    String completePrefix();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/IContentAssistantExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.IContentAssistantExtension2;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.IContentAssistant} with the following
+ * functions:
+ * <ul>
+ * <li>completion listeners</li>
+ * <li>repeated invocation mode</li>
+ * <li>a local status line for the completion popup</li>
+ * <li>control over the behavior when no proposals are available</li>
+ * </ul>
+ * 
+ * @since 3.2
+ */
+public interface IContentAssistantExtension2 {
+
+    /**
+     * Adds a completion listener that will be informed before proposals are computed.
+     * 
+     * @param listener the listener
+     */
+    public void addCompletionListener(ICompletionListener listener);
+
+    /**
+     * Removes a completion listener.
+     * 
+     * @param listener the listener to remove
+     */
+    public void removeCompletionListener(ICompletionListener listener);
+
+    /**
+     * Enables repeated invocation mode, which will trigger re-computation of the proposals when
+     * code assist is executed repeatedly. The default is no <code>false</code>.
+     * 
+     * @param cycling <code>true</code> to enable repetition mode, <code>false</code> to disable
+     */
+    public void setRepeatedInvocationMode(bool cycling);
+
+    /**
+     * Enables displaying an empty completion proposal pop-up. The default is not to show an empty
+     * list.
+     * 
+     * @param showEmpty <code>true</code> to show empty lists
+     */
+    public void setShowEmptyList(bool showEmpty);
+
+    /**
+     * Enables displaying a status line below the proposal popup. The default is not to show the
+     * status line. The contents of the status line may be set via {@link #setStatusMessage(String)}.
+     * 
+     * @param show <code>true</code> to show a message line, <code>false</code> to not show one.
+     */
+    public void setStatusLineVisible(bool show);
+
+    /**
+     * Sets the caption message displayed at the bottom of the completion proposal popup.
+     * 
+     * @param message the message
+     */
+    public void setStatusMessage(String message);
+
+    /**
+     * Sets the text to be shown if no proposals are available and
+     * {@link #setShowEmptyList(bool) empty lists} are displayed.
+     * 
+     * @param message the text for the empty list
+     */
+    public void setEmptyMessage(String message);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/IContentAssistantExtension3.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.IContentAssistantExtension3;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.bindings.keys.KeySequence;
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.IContentAssistant} with the following
+ * function:
+ * <ul>
+ * <li>a key-sequence to listen for in repeated invocation mode</li>
+ * </ul>
+ *
+ * @since 3.2
+ */
+public interface IContentAssistantExtension3 {
+
+    /**
+     * Sets the key sequence to listen for in repeated invocation mode. If the key sequence is
+     * encountered, a step in the repetition iteration is triggered.
+     * 
+     * @param sequence the key sequence used for the repeated invocation mode or <code>null</code> if none
+     */
+    public void setRepeatedInvocationTrigger(KeySequence sequence);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/IContentAssistantExtension4.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.IContentAssistantExtension4;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.commands.IHandler;
+
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.IContentAssistant} with
+ * the following function:
+ * <ul>
+ * <li>allows to get a handler for the given command identifier</li>
+ * </ul>
+ * 
+ * @since 3.4
+ */
+public interface IContentAssistantExtension4 {
+
+    /**
+     * Returns the handler for the given command identifier.
+     * <p>
+     * The same handler instance will be returned when called a more than once
+     * with the same command identifier.
+     * </p>
+     * 
+     * @param commandId the command identifier
+     * @return the handler for the given command identifier
+     * @throws IllegalArgumentException if the command is not supported by this
+     *             content assistant
+     * @throws IllegalStateException if called when this content assistant is
+     *             uninstalled
+     */
+    IHandler getHandler(String commandId);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/IContextInformation.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.IContextInformation;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.graphics.Image;
+
+
+/**
+ * The interface of context information presented to the user and
+ * generated by content assist processors.
+ * <p>
+ * In order to provide backward compatibility for clients of
+ * <code>IContextInformation</code>, extension interfaces are used to
+ * provide a means of evolution. The following extension interfaces
+ * exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.contentassist.IContextInformationExtension}
+ * since version 2.0 introducing the ability to freely position the
+ * context information.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * The interface can be implemented by clients. By default, clients use
+ * {@link dwtx.jface.text.contentassist.ContextInformation} as
+ * the standard implementer of this interface.
+ * </p>
+ * 
+ * @see IContentAssistProcessor
+ */
+public interface IContextInformation {
+
+    /**
+     * Returns the string to be displayed in the list of contexts.
+     * This method is used to supply a unique presentation for
+     * situations where the context is ambiguous. These strings are
+     * used to allow the user to select the specific context.
+     *
+     * @return the string to be displayed for the context
+     */
+    String getContextDisplayString();
+
+    /**
+     * Returns the image for this context information.
+     * The image will be shown to the left of the display string.
+     *
+     * @return the image to be shown or <code>null</code> if no image is desired
+     */
+    Image getImage();
+
+    /**
+     * Returns the string to be displayed in the tool tip like information popup.
+     *
+     * @return the string to be displayed
+     */
+    String getInformationDisplayString();
+
+    /**
+     * Compares the given object with this receiver. Two context informations are
+     * equal if there information display strings and their context display strings
+     * are equal.
+     *
+     * @see Object#equals(Object)
+     */
+    bool equals(Object object);
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/IContextInformationExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.IContextInformationExtension;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extends {@link dwtx.jface.text.contentassist.IContextInformation} with
+ * the ability to freely position the context information.
+ *
+ * @since 2.0
+ */
+public interface IContextInformationExtension {
+
+    /**
+     * Returns the start offset of the range for which this context
+     * information is valid or <code>-1</code> if unknown.
+     * 
+     * @return the start offset of the range for which this context
+     *         information is valid
+     */
+    int getContextInformationPosition();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/IContextInformationPresenter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.IContextInformationPresenter;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.TextPresentation;
+
+
+/**
+ * A context information presenter determines the presentation
+ * of context information depending on a given document position.
+ * <p>
+ * The interface can be implemented by clients.
+ * </p>
+ *
+ * @since 2.0
+ */
+public interface IContextInformationPresenter {
+
+    /**
+     * Installs this presenter for the given context information.
+     *
+     * @param info the context information which this presenter should style
+     * @param viewer the text viewer on which the information is presented
+     * @param offset the document offset for which the information has been computed
+     */
+    void install(IContextInformation info, ITextViewer viewer, int offset);
+
+    /**
+     * Updates the given presentation of the given context information
+     * at the given document position. Returns whether update changed the
+     * presentation.
+     *
+     * @param offset the current offset within the document
+     * @param presentation the presentation to be updated
+     * @return <code>true</code> if the given presentation has been changed
+     */
+    bool updatePresentation(int offset, TextPresentation presentation);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/IContextInformationValidator.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.IContextInformationValidator;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * A context information validator is used to determine if
+ * a displayed context information is still valid or should
+ * be dismissed.
+ * <p>
+ * The interface can be implemented by clients.
+ * </p>
+ *
+ * @see IContextInformationPresenter
+ */
+public interface IContextInformationValidator {
+
+    /**
+     * Installs this validator for the given context information.
+     *
+     * @param info the context information which this validator should check
+     * @param viewer the text viewer on which the information is presented
+     * @param offset the document offset for which the information has been computed
+     */
+    void install(IContextInformation info, ITextViewer viewer, int offset);
+
+    /**
+     * Returns whether the information this validator is installed on is still valid
+     * at the given document position.
+     *
+     * @param offset the current offset within the document
+     * @return <code>true</code> if the information also valid at the given document position
+     */
+    bool isContextInformationValid(int offset);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/JFaceTextMessages.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.JFaceTextMessages;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.PopupCloser; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.dwthelper.ResourceBundle;
+
+/**
+ * Helper class to get NLSed messages.
+ */
+class JFaceTextMessages {
+
+//     private static const String RESOURCE_BUNDLE= JFaceTextMessages.classinfo.getName();
+
+    private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+    static this() {
+        fgResourceBundle = ResourceBundle.getBundle(
+            getImportData!("dwtx.jface.text.contentassist.JFaceTextMessages.properties"));
+    }
+
+    private this() {
+    }
+
+    /**
+     * Gets a string from the resource bundle.
+     *
+     * @param key the string used to get the bundle value, must not be <code>null</code>
+     * @return the string from the resource bundle
+     */
+    public static String getString(String key) {
+        try {
+            return fgResourceBundle.getString(key);
+        } catch (MissingResourceException e) {
+            return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/contentassist/PopupCloser.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,306 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.contentassist.PopupCloser;
+
+import dwtx.jface.text.contentassist.ContentAssistEvent; // packageimport
+import dwtx.jface.text.contentassist.Helper; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension5; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListener; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension4; // packageimport
+import dwtx.jface.text.contentassist.ContextInformation; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationValidator; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposal; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistProcessor; // packageimport
+import dwtx.jface.text.contentassist.AdditionalInfoController; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationPresenter; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension4; // packageimport
+import dwtx.jface.text.contentassist.ICompletionListenerExtension; // packageimport
+import dwtx.jface.text.contentassist.ContextInformationPopup; // packageimport
+import dwtx.jface.text.contentassist.IContextInformationExtension; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension2; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistSubjectControlAdapter; // packageimport
+import dwtx.jface.text.contentassist.CompletionProposalPopup; // packageimport
+import dwtx.jface.text.contentassist.ICompletionProposalExtension; // packageimport
+import dwtx.jface.text.contentassist.IContextInformation; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension3; // packageimport
+import dwtx.jface.text.contentassist.ContentAssistant; // packageimport
+import dwtx.jface.text.contentassist.IContentAssistantExtension; // packageimport
+import dwtx.jface.text.contentassist.JFaceTextMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.DWT;
+import dwt.events.FocusEvent;
+import dwt.events.FocusListener;
+import dwt.events.SelectionEvent;
+import dwt.events.SelectionListener;
+import dwt.events.ShellAdapter;
+import dwt.events.ShellEvent;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwt.widgets.ScrollBar;
+import dwt.widgets.Shell;
+import dwt.widgets.Table;
+import dwtx.jface.internal.text.DelayedInputChangeListener;
+import dwtx.jface.internal.text.InformationControlReplacer;
+import dwtx.jface.text.IDelayedInputChangeProvider;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlExtension5;
+import dwtx.jface.text.IInputChangedListener;
+
+
+/**
+ * A generic closer class used to monitor various
+ * interface events in order to determine whether
+ * a content assistant should be terminated and all
+ * associated windows be closed.
+ */
+class PopupCloser : ShellAdapter , FocusListener, SelectionListener, Listener {
+
+    /** The content assistant to be monitored. */
+    private ContentAssistant fContentAssistant;
+    /** The table of a selector popup opened by the content assistant. */
+    private Table fTable;
+    /** The scroll bar of the table for the selector popup. */
+    private ScrollBar fScrollbar;
+    /** Indicates whether the scroll bar thumb has been grabbed. */
+    private bool fScrollbarClicked= false;
+    /**
+     * The shell on which some listeners are registered.
+     * @since 3.1
+     */
+    private Shell fShell;
+    /**
+     * The display on which some filters are registered.
+     * @since 3.4
+     */
+    private Display fDisplay;
+    /**
+     * The additional info controller, or <code>null</code>.
+     * @since 3.4
+     */
+    private AdditionalInfoController fAdditionalInfoController;
+
+    /**
+     * Installs this closer on the given table opened by the given content assistant.
+     *
+     * @param contentAssistant the content assistant
+     * @param table the table to be tracked
+     */
+    public void install(ContentAssistant contentAssistant, Table table) {
+        install(contentAssistant, table, null);
+    }
+
+    /**
+     * Installs this closer on the given table opened by the given content assistant.
+     *
+     * @param contentAssistant the content assistant
+     * @param table the table to be tracked
+     * @param additionalInfoController the additional info controller, or <code>null</code>
+     * @since 3.4
+     */
+    public void install(ContentAssistant contentAssistant, Table table, AdditionalInfoController additionalInfoController) {
+        fContentAssistant= contentAssistant;
+        fTable= table;
+        fAdditionalInfoController= additionalInfoController;
+
+        if (Helper.okToUse(fTable)) {
+            fShell= fTable.getShell();
+            fDisplay= fShell.getDisplay();
+
+            fShell.addShellListener(this);
+            fTable.addFocusListener(this);
+            fScrollbar= fTable.getVerticalBar();
+            if (fScrollbar !is null)
+                fScrollbar.addSelectionListener(this);
+
+            fDisplay.addFilter(DWT.Activate, this);
+            fDisplay.addFilter(DWT.MouseWheel, this);
+
+            fDisplay.addFilter(DWT.Deactivate, this);
+
+            fDisplay.addFilter(DWT.MouseUp, this);
+        }
+    }
+
+    /**
+     * Uninstalls this closer if previously installed.
+     */
+    public void uninstall() {
+        fContentAssistant= null;
+        if (Helper.okToUse(fShell))
+            fShell.removeShellListener(this);
+        fShell= null;
+        if (Helper.okToUse(fScrollbar))
+            fScrollbar.removeSelectionListener(this);
+        if (Helper.okToUse(fTable))
+            fTable.removeFocusListener(this);
+        if (fDisplay !is null && ! fDisplay.isDisposed()) {
+            fDisplay.removeFilter(DWT.Activate, this);
+            fDisplay.removeFilter(DWT.MouseWheel, this);
+
+            fDisplay.removeFilter(DWT.Deactivate, this);
+
+            fDisplay.removeFilter(DWT.MouseUp, this);
+        }
+    }
+
+    /*
+     * @see dwt.events.SelectionListener#widgetSelected(dwt.events.SelectionEvent)
+     */
+    public void widgetSelected(SelectionEvent e) {
+        fScrollbarClicked= true;
+    }
+
+    /*
+     * @see dwt.events.SelectionListener#widgetDefaultSelected(dwt.events.SelectionEvent)
+     */
+    public void widgetDefaultSelected(SelectionEvent e) {
+        fScrollbarClicked= true;
+    }
+
+    /*
+     * @see dwt.events.FocusListener#focusGained(dwt.events.FocusEvent)
+     */
+    public void focusGained(FocusEvent e) {
+    }
+
+    /*
+     * @see dwt.events.FocusListener#focusLost(dwt.events.FocusEvent)
+     */
+    public void focusLost(FocusEvent e) {
+        fScrollbarClicked= false;
+        Display d= fTable.getDisplay();
+        d.asyncExec(dgRunnable((FocusEvent e_) {
+            if (Helper.okToUse(fTable) && !fTable.isFocusControl() && !fScrollbarClicked && fContentAssistant !is null)
+                fContentAssistant.popupFocusLost(e_);
+        }, e ));
+    }
+
+    /*
+     * @see dwt.events.ShellAdapter#shellDeactivated(dwt.events.ShellEvent)
+     * @since 3.1
+     */
+    public void shellDeactivated(ShellEvent e) {
+        if (fContentAssistant !is null && ! fContentAssistant.hasProposalPopupFocus())
+            fContentAssistant.hide_package();
+    }
+
+
+    /*
+     * @see dwt.events.ShellAdapter#shellClosed(dwt.events.ShellEvent)
+     * @since 3.1
+     */
+    public void shellClosed(ShellEvent e) {
+        if (fContentAssistant !is null)
+            fContentAssistant.hide_package();
+    }
+
+    /*
+     * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event)
+     * @since 3.4
+     */
+    public void handleEvent(Event event) {
+        switch (event.type) {
+            case DWT.Activate:
+            case DWT.MouseWheel:
+                if (fAdditionalInfoController is null)
+                    return;
+                if (event.widget is fShell || event.widget is fTable || event.widget is fScrollbar)
+                    return;
+
+                if (fAdditionalInfoController.getInternalAccessor().getInformationControlReplacer() is null)
+                    fAdditionalInfoController.hideInformationControl_package();
+                else if (!fAdditionalInfoController.getInternalAccessor().isReplaceInProgress()) {
+                    IInformationControl infoControl= fAdditionalInfoController.getCurrentInformationControl2();
+                    // During isReplaceInProgress(), events can come from the replacing information control
+                    if (cast(Control)event.widget && cast(IInformationControlExtension5)infoControl ) {
+                        Control control= cast(Control) event.widget;
+                        IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) infoControl;
+                        if (!(iControl5.containsControl(control)))
+                            fAdditionalInfoController.hideInformationControl_package();
+                        else if (event.type is DWT.MouseWheel)
+                            fAdditionalInfoController.getInternalAccessor().replaceInformationControl(false);
+                    } else if (infoControl !is null && infoControl.isFocusControl()) {
+                        fAdditionalInfoController.getInternalAccessor().replaceInformationControl(true);
+                    }
+                }
+                break;
+
+            case DWT.MouseUp:
+                if (fAdditionalInfoController is null || fAdditionalInfoController.getInternalAccessor().isReplaceInProgress())
+                    break;
+                if (cast(Control)event.widget) {
+                    Control control= cast(Control) event.widget;
+                    IInformationControl infoControl= fAdditionalInfoController.getCurrentInformationControl2();
+                    if ( cast(IInformationControlExtension5)infoControl ) {
+                        final IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) infoControl;
+                        if (iControl5.containsControl(control)) {
+                            if ( cast(IDelayedInputChangeProvider)infoControl ) {
+                                final IDelayedInputChangeProvider delayedICP= cast(IDelayedInputChangeProvider) infoControl;
+                                final IInputChangedListener inputChangeListener= new DelayedInputChangeListener(delayedICP, fAdditionalInfoController.getInternalAccessor().getInformationControlReplacer());
+                                delayedICP.setDelayedInputChangeListener(inputChangeListener);
+                                // cancel automatic input updating after a small timeout:
+                                control.getShell().getDisplay().timerExec(1000, new class()  Runnable {
+                                    public void run() {
+                                        delayedICP.setDelayedInputChangeListener(null);
+                                    }
+                                });
+                            }
+
+                            // XXX: workaround for https://bugs.eclipse.org/bugs/show_bug.cgi?id=212392 :
+                            control.getShell().getDisplay().asyncExec(new class()  Runnable {
+                                public void run() {
+                                    fAdditionalInfoController.getInternalAccessor().replaceInformationControl(true);
+                                }
+                            });
+                        }
+                    }
+                }
+                break;
+
+            case DWT.Deactivate:
+                if (fAdditionalInfoController is null)
+                    break;
+                InformationControlReplacer replacer= fAdditionalInfoController.getInternalAccessor().getInformationControlReplacer();
+                if (replacer !is null && fContentAssistant !is null) {
+                    IInformationControl iControl= replacer.getCurrentInformationControl2();
+                    if (cast(Control)event.widget  && cast(IInformationControlExtension5)iControl ) {
+                        Control control= cast(Control) event.widget;
+                        IInformationControlExtension5 iControl5= cast(IInformationControlExtension5) iControl;
+                        if (iControl5.containsControl(control)) {
+                            control.getDisplay().asyncExec(new class()  Runnable {
+                                public void run() {
+                                    if (fContentAssistant !is null && ! fContentAssistant.hasProposalPopupFocus())
+                                        fContentAssistant.hide_package();
+                                }
+                            });
+                        }
+                    }
+                }
+                break;
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/formatter/ContentFormatter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,812 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.formatter.ContentFormatter;
+
+import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport
+import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.FormattingContext; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport
+import dwtx.jface.text.formatter.IContentFormatter; // packageimport
+import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport
+import dwtx.jface.text.formatter.IFormattingContext; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DefaultPositionUpdater;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentExtension3;
+import dwtx.jface.text.IPositionUpdater;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITypedRegion;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.TextUtilities;
+import dwtx.jface.text.TypedPosition;
+
+
+/**
+ * Standard implementation of <code>IContentFormatter</code>.
+ * The formatter supports two operation modes: partition aware and
+ * partition unaware. <p>
+ * In the partition aware mode, the formatter determines the
+ * partitioning of the document region to be formatted. For each
+ * partition it determines all document positions  which are affected
+ * when text changes are applied to the partition. Those which overlap
+ * with the partition are remembered as character positions. These
+ * character positions are passed over to the formatting strategy
+ * registered for the partition's content type. The formatting strategy
+ * returns a string containing the formatted document partition as well
+ * as the adapted character positions. The formatted partition replaces
+ * the old content of the partition. The remembered document positions
+ * are updated with the adapted character positions. In addition, all
+ * other document positions are accordingly adapted to the formatting
+ * changes.<p>
+ * In the partition unaware mode, the document's partitioning is ignored
+ * and the document is considered consisting of only one partition of
+ * the content type <code>IDocument.DEFAULT_CONTENT_TYPE</code>. The
+ * formatting process is similar to the partition aware mode, with the
+ * exception of having only one partition.<p>
+ * Usually, clients instantiate this class and configure it before using it.
+ *
+ * @see IContentFormatter
+ * @see IDocument
+ * @see ITypedRegion
+ * @see Position
+ */
+public class ContentFormatter : IContentFormatter {
+
+    /**
+     * Defines a reference to either the offset or the end offset of
+     * a particular position.
+     */
+    static class PositionReference : Comparable {
+
+        /** The referenced position */
+        protected Position fPosition;
+        /** The reference to either the offset or the end offset */
+        protected bool fRefersToOffset;
+        /** The original category of the referenced position */
+        protected String fCategory;
+
+        /**
+         * Creates a new position reference.
+         *
+         * @param position the position to be referenced
+         * @param refersToOffset <code>true</code> if position offset should be referenced
+         * @param category the category the given position belongs to
+         */
+        protected this(Position position, bool refersToOffset, String category) {
+            fPosition= position;
+            fRefersToOffset= refersToOffset;
+            fCategory= category;
+        }
+
+        /**
+         * Returns the offset of the referenced position.
+         *
+         * @return the offset of the referenced position
+         */
+        protected int getOffset() {
+            return fPosition.getOffset();
+        }
+
+        /**
+         * Manipulates the offset of the referenced position.
+         *
+         * @param offset the new offset of the referenced position
+         */
+        protected void setOffset(int offset) {
+            fPosition.setOffset(offset);
+        }
+
+        /**
+         * Returns the length of the referenced position.
+         *
+         * @return the length of the referenced position
+         */
+        protected int getLength() {
+            return fPosition.getLength();
+        }
+
+        /**
+         * Manipulates the length of the referenced position.
+         *
+         * @param length the new length of the referenced position
+         */
+        protected void setLength(int length) {
+            fPosition.setLength(length);
+        }
+
+        /**
+         * Returns whether this reference points to the offset or end offset
+         * of the references position.
+         *
+         * @return <code>true</code> if the offset of the position is referenced, <code>false</code> otherwise
+         */
+        protected bool refersToOffset() {
+            return fRefersToOffset;
+        }
+
+        /**
+         * Returns the category of the referenced position.
+         *
+         * @return the category of the referenced position
+         */
+        protected String getCategory() {
+            return fCategory;
+        }
+
+        /**
+         * Returns the referenced position.
+         *
+         * @return the referenced position
+         */
+        protected Position getPosition() {
+            return fPosition;
+        }
+
+        /**
+         * Returns the referenced character position
+         *
+         * @return the referenced character position
+         */
+        protected int getCharacterPosition() {
+            if (fRefersToOffset)
+                return getOffset();
+            return getOffset() + getLength();
+        }
+
+        /*
+         * @see Comparable#compareTo(Object)
+         */
+        public int compareTo(Object obj) {
+
+            if ( cast(PositionReference)obj ) {
+                PositionReference r= cast(PositionReference) obj;
+                return getCharacterPosition() - r.getCharacterPosition();
+            }
+
+            throw new ClassCastException();
+        }
+    }
+
+    /**
+     * The position updater used to update the remembered partitions.
+     *
+     * @see IPositionUpdater
+     * @see DefaultPositionUpdater
+     */
+    class NonDeletingPositionUpdater : DefaultPositionUpdater {
+
+        /**
+         * Creates a new updater for the given category.
+         *
+         * @param category the category
+         */
+        protected this(String category) {
+            super(category);
+        }
+
+        /*
+         * @see DefaultPositionUpdater#notDeleted()
+         */
+        protected bool notDeleted() {
+            return true;
+        }
+    }
+
+    /**
+     * The position updater which runs as first updater on the document's positions.
+     * Used to remove all affected positions from their categories to avoid them
+     * from being regularly updated.
+     *
+     * @see IPositionUpdater
+     */
+    class RemoveAffectedPositions : IPositionUpdater {
+        /*
+         * @see IPositionUpdater#update(DocumentEvent)
+         */
+        public void update(DocumentEvent event) {
+            removeAffectedPositions(event.getDocument());
+        }
+    }
+
+    /**
+     * The position updater which runs as last updater on the document's positions.
+     * Used to update all affected positions and adding them back to their
+     * original categories.
+     *
+     * @see IPositionUpdater
+     */
+    class UpdateAffectedPositions : IPositionUpdater {
+
+        /** The affected positions */
+        private int[] fPositions;
+        /** The offset */
+        private int fOffset;
+
+        /**
+         * Creates a new updater.
+         *
+         * @param positions the affected positions
+         * @param offset the offset
+         */
+        public this(int[] positions, int offset) {
+            fPositions= positions;
+            fOffset= offset;
+        }
+
+        /*
+         * @see IPositionUpdater#update(DocumentEvent)
+         */
+        public void update(DocumentEvent event) {
+            updateAffectedPositions(event.getDocument(), fPositions, fOffset);
+        }
+    }
+
+
+    /** Internal position category used for the formatter partitioning */
+    private const static String PARTITIONING= "__formatter_partitioning"; //$NON-NLS-1$
+
+    /** The map of <code>IFormattingStrategy</code> objects */
+    private Map fStrategies;
+    /** The indicator of whether the formatter operates in partition aware mode or not */
+    private bool fIsPartitionAware= true;
+
+    /** The partition information managing document position categories */
+    private String[] fPartitionManagingCategories;
+    /** The list of references to offset and end offset of all overlapping positions */
+    private List fOverlappingPositionReferences;
+    /** Position updater used for partitioning positions */
+    private IPositionUpdater fPartitioningUpdater;
+    /**
+     * The document partitioning used by this formatter.
+     * @since 3.0
+     */
+    private String fPartitioning;
+    /**
+     * The document this formatter works on.
+     * @since 3.0
+     */
+    private IDocument fDocument;
+    /**
+     * The external partition managing categories.
+     * @since 3.0
+     */
+    private String[] fExternalPartitonManagingCategories;
+    /**
+     * Indicates whether <code>fPartitionManagingCategories</code> must be computed.
+     * @since 3.0
+     */
+    private bool fNeedsComputation= true;
+
+
+    /**
+     * Creates a new content formatter. The content formatter operates by default
+     * in the partition-aware mode. There are no preconfigured formatting strategies.
+     * Will use the default document partitioning if not further configured.
+     */
+    public this() {
+        fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING;
+    }
+
+    /**
+     * Registers a strategy for a particular content type. If there is already a strategy
+     * registered for this type, the new strategy is registered instead of the old one.
+     * If the given content type is <code>null</code> the given strategy is registered for
+     * all content types as is called only once per formatting session.
+     *
+     * @param strategy the formatting strategy to register, or <code>null</code> to remove an existing one
+     * @param contentType the content type under which to register
+     */
+    public void setFormattingStrategy(IFormattingStrategy strategy, String contentType) {
+
+        Assert.isNotNull(contentType);
+
+        if (fStrategies is null)
+            fStrategies= new HashMap();
+
+        if (strategy is null)
+            fStrategies.remove(contentType);
+        else
+            fStrategies.put(contentType, cast(Object)strategy);
+    }
+
+    /**
+     * Informs this content formatter about the names of those position categories
+     * which are used to manage the document's partitioning information and thus should
+     * be ignored when this formatter updates positions.
+     *
+     * @param categories the categories to be ignored
+     * @deprecated incompatible with an open set of document partitionings. The provided information is only used
+     *      if this formatter can not compute the partition managing position categories.
+     */
+    public void setPartitionManagingPositionCategories(String[] categories) {
+        fExternalPartitonManagingCategories= TextUtilities.copy(categories);
+    }
+
+    /**
+     * Sets the document partitioning to be used by this formatter.
+     *
+     * @param partitioning the document partitioning
+     * @since 3.0
+     */
+    public void setDocumentPartitioning(String partitioning) {
+        fPartitioning= partitioning;
+    }
+
+    /**
+     * Sets the formatter's operation mode.
+     *
+     * @param enable indicates whether the formatting process should be partition ware
+     */
+    public void enablePartitionAwareFormatting(bool enable) {
+        fIsPartitionAware= enable;
+    }
+
+    /*
+     * @see IContentFormatter#getFormattingStrategy(String)
+     */
+    public IFormattingStrategy getFormattingStrategy(String contentType) {
+
+        Assert.isNotNull(contentType);
+
+        if (fStrategies is null)
+            return null;
+
+        return cast(IFormattingStrategy) fStrategies.get(contentType);
+    }
+
+    /*
+     * @see IContentFormatter#format(IDocument, IRegion)
+     */
+    public void format(IDocument document, IRegion region) {
+        fNeedsComputation= true;
+        fDocument= document;
+        try {
+
+            if (fIsPartitionAware)
+                formatPartitions(region);
+            else
+                formatRegion(region);
+
+        } finally {
+            fNeedsComputation= true;
+            fDocument= null;
+        }
+    }
+
+    /**
+     * Determines the partitioning of the given region of the document.
+     * Informs the formatting strategies of each partition about the start,
+     * the process, and the termination of the formatting session.
+     *
+     * @param region the document region to be formatted
+     * @since 3.0
+     */
+    private void formatPartitions(IRegion region) {
+
+        addPartitioningUpdater();
+
+        try {
+
+            TypedPosition[] ranges= getPartitioning(region);
+            if (ranges !is null) {
+                start(ranges, getIndentation(region.getOffset()));
+                format(ranges);
+                stop(ranges);
+            }
+
+        } catch (BadLocationException x) {
+        }
+
+        removePartitioningUpdater();
+    }
+
+    /**
+     * Formats the given region with the strategy registered for the default
+     * content type. The strategy is informed about the start, the process, and
+     * the termination of the formatting session.
+     *
+     * @param region the region to be formatted
+     * @since 3.0
+     */
+    private void formatRegion(IRegion region) {
+
+        IFormattingStrategy strategy= getFormattingStrategy(IDocument.DEFAULT_CONTENT_TYPE);
+        if (strategy !is null) {
+            strategy.formatterStarts(getIndentation(region.getOffset()));
+            format(strategy, new TypedPosition(region.getOffset(), region.getLength(), IDocument.DEFAULT_CONTENT_TYPE));
+            strategy.formatterStops();
+        }
+    }
+
+    /**
+     * Returns the partitioning of the given region of the document to be formatted.
+     * As one partition after the other will be formatted and formatting will
+     * probably change the length of the formatted partition, it must be kept
+     * track of the modifications in order to submit the correct partition to all
+     * formatting strategies. For this, all partitions are remembered as positions
+     * in a dedicated position category. (As formatting strategies might rely on each
+     * other, calling them in reversed order is not an option.)
+     *
+     * @param region the region for which the partitioning must be determined
+     * @return the partitioning of the specified region
+     * @exception BadLocationException of region is invalid in the document
+     * @since 3.0
+     */
+    private TypedPosition[] getPartitioning(IRegion region)  {
+
+        ITypedRegion[] regions= TextUtilities.computePartitioning(fDocument, fPartitioning, region.getOffset(), region.getLength(), false);
+        TypedPosition[] positions= new TypedPosition[regions.length];
+
+        for (int i= 0; i < regions.length; i++) {
+            positions[i]= new TypedPosition(regions[i]);
+            try {
+                fDocument.addPosition(PARTITIONING, positions[i]);
+            } catch (BadPositionCategoryException x) {
+                // should not happen
+            }
+        }
+
+        return positions;
+    }
+
+    /**
+     * Fires <code>formatterStarts</code> to all formatter strategies
+     * which will be involved in the forthcoming formatting process.
+     *
+     * @param regions the partitioning of the document to be formatted
+     * @param indentation the initial indentation
+     */
+    private void start(TypedPosition[] regions, String indentation) {
+        for (int i= 0; i < regions.length; i++) {
+            IFormattingStrategy s= getFormattingStrategy(regions[i].getType());
+            if (s !is null)
+                s.formatterStarts(indentation);
+        }
+    }
+
+    /**
+     * Formats one partition after the other using the formatter strategy registered for
+     * the partition's content type.
+     *
+     * @param ranges the partitioning of the document region to be formatted
+     * @since 3.0
+     */
+    private void format(TypedPosition[] ranges) {
+        for (int i= 0; i < ranges.length; i++) {
+            IFormattingStrategy s= getFormattingStrategy(ranges[i].getType());
+            if (s !is null) {
+                format(s, ranges[i]);
+            }
+        }
+    }
+
+    /**
+     * Formats the given region of the document using the specified formatting
+     * strategy. In order to maintain positions correctly, first all affected
+     * positions determined, after all document listeners have been informed about
+     * the coming change, the affected positions are removed to avoid that they
+     * are regularly updated. After all position updaters have run, the affected
+     * positions are updated with the formatter's information and added back to
+     * their categories, right before the first document listener is informed about
+     * that a change happened.
+     *
+     * @param strategy the strategy to be used
+     * @param region the region to be formatted
+     * @since 3.0
+     */
+    private void format(IFormattingStrategy strategy, TypedPosition region) {
+        try {
+
+            final int offset= region.getOffset();
+            int length= region.getLength();
+
+            String content= fDocument.get(offset, length);
+            final int[] positions= getAffectedPositions(offset, length);
+            String formatted= strategy.format(content, isLineStart(offset), getIndentation(offset), positions);
+
+            if (formatted !is null && !formatted.equals(content)) {
+
+                IPositionUpdater first= new RemoveAffectedPositions();
+                fDocument.insertPositionUpdater(first, 0);
+                IPositionUpdater last= new UpdateAffectedPositions(positions, offset);
+                fDocument.addPositionUpdater(last);
+
+                fDocument.replace(offset, length, formatted);
+
+                fDocument.removePositionUpdater(first);
+                fDocument.removePositionUpdater(last);
+            }
+
+        } catch (BadLocationException x) {
+            // should not happen
+        }
+    }
+
+    /**
+     * Fires <code>formatterStops</code> to all formatter strategies which were
+     * involved in the formatting process which is about to terminate.
+     *
+     * @param regions the partitioning of the document which has been formatted
+     */
+    private void stop(TypedPosition[] regions) {
+        for (int i= 0; i < regions.length; i++) {
+            IFormattingStrategy s= getFormattingStrategy(regions[i].getType());
+            if (s !is null)
+                s.formatterStops();
+        }
+    }
+
+    /**
+     * Installs those updaters which the formatter needs to keep track of the partitions.
+     * @since 3.0
+     */
+    private void addPartitioningUpdater() {
+        fPartitioningUpdater= new NonDeletingPositionUpdater(PARTITIONING);
+        fDocument.addPositionCategory(PARTITIONING);
+        fDocument.addPositionUpdater(fPartitioningUpdater);
+    }
+
+    /**
+     * Removes the formatter's internal position updater and category.
+     *
+     * @since 3.0
+     */
+    private void removePartitioningUpdater() {
+
+        try {
+
+            fDocument.removePositionUpdater(fPartitioningUpdater);
+            fDocument.removePositionCategory(PARTITIONING);
+            fPartitioningUpdater= null;
+
+        } catch (BadPositionCategoryException x) {
+            // should not happen
+        }
+    }
+
+    /**
+     * Returns the partition managing position categories for the formatted document.
+     *
+     * @return the position managing position categories
+     * @since 3.0
+     */
+    private String[] getPartitionManagingCategories() {
+        if (fNeedsComputation) {
+            fNeedsComputation= false;
+            fPartitionManagingCategories= TextUtilities.computePartitionManagingCategories(fDocument);
+            if (fPartitionManagingCategories is null)
+                fPartitionManagingCategories= fExternalPartitonManagingCategories;
+        }
+        return fPartitionManagingCategories;
+    }
+
+    /**
+     * Determines whether the given document position category should be ignored
+     * by this formatter's position updating.
+     *
+     * @param category the category to check
+     * @return <code>true</code> if the category should be ignored, <code>false</code> otherwise
+     */
+    private bool ignoreCategory(String category) {
+
+        if (PARTITIONING.equals(category))
+            return true;
+
+        String[] categories= getPartitionManagingCategories();
+        if (categories !is null) {
+            for (int i= 0; i < categories.length; i++) {
+                if (categories[i].equals(category))
+                    return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Determines all embracing, overlapping, and follow up positions
+     * for the given region of the document.
+     *
+     * @param offset the offset of the document region to be formatted
+     * @param length the length of the document to be formatted
+     * @since 3.0
+     */
+    private void determinePositionsToUpdate(int offset, int length) {
+
+        String[] categories= fDocument.getPositionCategories();
+        if (categories !is null) {
+            for (int i= 0; i < categories.length; i++) {
+
+                if (ignoreCategory(categories[i]))
+                    continue;
+
+                try {
+
+                    Position[] positions= fDocument.getPositions(categories[i]);
+
+                    for (int j= 0; j < positions.length; j++) {
+
+                        Position p= positions[j];
+                        if (p.overlapsWith(offset, length)) {
+
+                            if (offset < p.getOffset())
+                                fOverlappingPositionReferences.add(new PositionReference(p, true, categories[i]));
+
+                            if (p.getOffset() + p.getLength() < offset + length)
+                                fOverlappingPositionReferences.add(new PositionReference(p, false, categories[i]));
+                        }
+                    }
+
+                } catch (BadPositionCategoryException x) {
+                    // can not happen
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns all offset and the end offset of all positions overlapping with the
+     * specified document range.
+     *
+     * @param offset the offset of the document region to be formatted
+     * @param length the length of the document to be formatted
+     * @return all character positions of the interleaving positions
+     * @since 3.0
+     */
+    private int[] getAffectedPositions(int offset, int length) {
+
+        fOverlappingPositionReferences= new ArrayList();
+
+        determinePositionsToUpdate(offset, length);
+
+        Collections.sort(fOverlappingPositionReferences);
+
+        int[] positions= new int[fOverlappingPositionReferences.size()];
+        for (int i= 0; i < positions.length; i++) {
+            PositionReference r= cast(PositionReference) fOverlappingPositionReferences.get(i);
+            positions[i]= r.getCharacterPosition() - offset;
+        }
+
+        return positions;
+    }
+
+    /**
+     * Removes the affected positions from their categories to avoid
+     * that they are invalidly updated.
+     *
+     * @param document the document
+     */
+    private void removeAffectedPositions(IDocument document) {
+        int size= fOverlappingPositionReferences.size();
+        for (int i= 0; i < size; i++) {
+            PositionReference r= cast(PositionReference) fOverlappingPositionReferences.get(i);
+            try {
+                document.removePosition(r.getCategory(), r.getPosition());
+            } catch (BadPositionCategoryException x) {
+                // can not happen
+            }
+        }
+    }
+
+    /**
+     * Updates all the overlapping positions. Note, all other positions are
+     * automatically updated by their document position updaters.
+     *
+     * @param document the document to has been formatted
+     * @param positions the adapted character positions to be used to update the document positions
+     * @param offset the offset of the document region that has been formatted
+     */
+    protected void updateAffectedPositions(IDocument document, int[] positions, int offset) {
+
+        if (document !is fDocument)
+            return;
+
+        if (positions.length is 0)
+            return;
+
+        for (int i= 0; i < positions.length; i++) {
+
+            PositionReference r= cast(PositionReference) fOverlappingPositionReferences.get(i);
+
+            if (r.refersToOffset())
+                r.setOffset(offset + positions[i]);
+            else
+                r.setLength((offset + positions[i]) - r.getOffset());
+
+            Position p= r.getPosition();
+            String category= r.getCategory();
+            if (!document.containsPosition(category, p.offset, p.length)) {
+                try {
+                    if (positionAboutToBeAdded(document, category, p))
+                        document.addPosition(r.getCategory(), p);
+                } catch (BadPositionCategoryException x) {
+                    // can not happen
+                } catch (BadLocationException x) {
+                    // should not happen
+                }
+            }
+
+        }
+
+        fOverlappingPositionReferences= null;
+    }
+
+    /**
+     * The given position is about to be added to the given position category of the given document. <p>
+     * This default implementation return <code>true</code>.
+     *
+     * @param document the document
+     * @param category the position category
+     * @param position the position that will be added
+     * @return <code>true</code> if the position can be added, <code>false</code> if it should be ignored
+     */
+    protected bool positionAboutToBeAdded(IDocument document, String category, Position position) {
+        return true;
+    }
+
+    /**
+     * Returns the indentation of the line of the given offset.
+     *
+     * @param offset the offset
+     * @return the indentation of the line of the offset
+     * @since 3.0
+     */
+    private String getIndentation(int offset) {
+
+        try {
+            int start= fDocument.getLineOfOffset(offset);
+            start= fDocument.getLineOffset(start);
+
+            int end= start;
+            char c= fDocument.getChar(end);
+            while ('\t' is c || ' ' is c)
+                c= fDocument.getChar(++end);
+
+            return fDocument.get(start, end - start);
+        } catch (BadLocationException x) {
+        }
+
+        return ""; //$NON-NLS-1$
+    }
+
+    /**
+     * Determines whether the offset is the beginning of a line in the given document.
+     *
+     * @param offset the offset
+     * @return <code>true</code> if offset is the beginning of a line
+     * @exception BadLocationException if offset is invalid in document
+     * @since 3.0
+     */
+    private bool isLineStart(int offset)  {
+        int start= fDocument.getLineOfOffset(offset);
+        start= fDocument.getLineOffset(start);
+        return (start is offset);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/formatter/ContextBasedFormattingStrategy.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.formatter.ContextBasedFormattingStrategy;
+
+import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport
+import dwtx.jface.text.formatter.FormattingContext; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport
+import dwtx.jface.text.formatter.IContentFormatter; // packageimport
+import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport
+import dwtx.jface.text.formatter.ContentFormatter; // packageimport
+import dwtx.jface.text.formatter.IFormattingContext; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+/**
+ * Formatting strategy for context based content formatting. Retrieves the preferences
+ * set on the formatting context's {@link FormattingContextProperties#CONTEXT_PREFERENCES}
+ * property and makes them available to subclasses.
+ * <p>
+ *
+ * @since 3.0
+ */
+public abstract class ContextBasedFormattingStrategy : IFormattingStrategy, IFormattingStrategyExtension {
+
+    /** The current preferences for formatting */
+    private Map fCurrentPreferences= null;
+
+    /** The list of preferences for initiated the formatting steps */
+    private const LinkedList fPreferences;
+
+    this(){
+        fPreferences= new LinkedList();
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingStrategyExtension#format()
+     */
+    public void format() {
+        fCurrentPreferences= cast(Map)fPreferences.removeFirst();
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingStrategy#format(java.lang.String, bool, java.lang.String, int[])
+     */
+    public String format(String content, bool start, String indentation, int[] positions) {
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingStrategyExtension#formatterStarts(dwtx.jface.text.formatter.IFormattingContext)
+     */
+    public void formatterStarts(IFormattingContext context) {
+        fPreferences.addLast(context.getProperty(stringcast(FormattingContextProperties.CONTEXT_PREFERENCES)));
+    }
+
+    /*
+     * @see IFormattingStrategy#formatterStarts(String)
+     */
+    public void formatterStarts(String indentation) {
+        // Do nothing
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingStrategyExtension#formatterStops()
+     */
+    public void formatterStops() {
+        fPreferences.clear();
+
+        fCurrentPreferences= null;
+    }
+
+    /**
+     * Returns the preferences used for the current formatting step.
+     *
+     * @return The preferences for the current formatting step
+     */
+    public final Map getPreferences() {
+        return fCurrentPreferences;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/formatter/FormattingContext.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,183 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.formatter.FormattingContext;
+
+import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport
+import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport
+import dwtx.jface.text.formatter.IContentFormatter; // packageimport
+import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport
+import dwtx.jface.text.formatter.ContentFormatter; // packageimport
+import dwtx.jface.text.formatter.IFormattingContext; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.jface.preference.IPreferenceStore;
+
+/**
+ * Default implementation of <code>IFormattingContext</code>.
+ *
+ * @since 3.0
+ */
+public class FormattingContext : IFormattingContext {
+
+    /** Map to store the properties */
+    private const Map fMap;
+
+    this(){
+        fMap= new HashMap();
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingContext#dispose()
+     */
+    public void dispose() {
+        fMap.clear();
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingContext#getPreferenceKeys()
+     */
+    public String[] getPreferenceKeys() {
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingContext#getProperty(java.lang.Object)
+     */
+    public Object getProperty(Object key) {
+        return fMap.get(key);
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingContext#isBooleanPreference(java.lang.String)
+     */
+    public bool isBooleanPreference(String key) {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingContext#isDoublePreference(java.lang.String)
+     */
+    public bool isDoublePreference(String key) {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingContext#isFloatPreference(java.lang.String)
+     */
+    public bool isFloatPreference(String key) {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingContext#isIntegerPreference(java.lang.String)
+     */
+    public bool isIntegerPreference(String key) {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingContext#isLongPreference(java.lang.String)
+     */
+    public bool isLongPreference(String key) {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingContext#isStringPreference(java.lang.String)
+     */
+    public bool isStringPreference(String key) {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingContext#mapToStore(java.util.Map, dwtx.jface.preference.IPreferenceStore)
+     */
+    public void mapToStore(Map map, IPreferenceStore store) {
+
+        final String[] preferences= getPreferenceKeys();
+
+        String result= null;
+        String preference= null;
+
+        for (int index= 0; index < preferences.length; index++) {
+
+            preference= preferences[index];
+            result= stringcast(map.get(preference));
+
+            if (result !is null) {
+
+                try {
+                    if (isBooleanPreference(preference)) {
+                        store.setValue(preference, result.equals(IPreferenceStore.TRUE));
+                    } else if (isIntegerPreference(preference)) {
+                        store.setValue(preference, Integer.parseInt(result));
+                    } else if (isStringPreference(preference)) {
+                        store.setValue(preference, result);
+                    } else if (isDoublePreference(preference)) {
+                        store.setValue(preference, Double.parseDouble(result));
+                    } else if (isFloatPreference(preference)) {
+                        store.setValue(preference, Float.parseFloat(result));
+                    } else if (isLongPreference(preference)) {
+                        store.setValue(preference, Long.parseLong(result));
+                    }
+                } catch (NumberFormatException exception) {
+                    // Do nothing
+                }
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingContext#setProperty(java.lang.Object, java.lang.Object)
+     */
+    public void setProperty(Object key, Object property) {
+        fMap.put(key, property);
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IFormattingContext#storeToMap(dwtx.jface.preference.IPreferenceStore, java.util.Map, bool)
+     */
+    public void storeToMap(IPreferenceStore store, Map map, bool useDefault) {
+
+        final String[] preferences= getPreferenceKeys();
+
+        String preference= null;
+        for (int index= 0; index < preferences.length; index++) {
+
+            preference= preferences[index];
+
+            if (isBooleanPreference(preference)) {
+                map.put(preference, (useDefault ? store.getDefaultBoolean(preference) : store.getBoolean(preference)) ? IPreferenceStore.TRUE : IPreferenceStore.FALSE);
+            } else if (isIntegerPreference(preference)) {
+                map.put(preference, String_valueOf(useDefault ? store.getDefaultInt(preference) : store.getInt(preference)));
+            } else if (isStringPreference(preference)) {
+                map.put(preference, useDefault ? store.getDefaultString(preference) : store.getString(preference));
+            } else if (isDoublePreference(preference)) {
+                map.put(preference, String_valueOf(useDefault ? store.getDefaultDouble(preference) : store.getDouble(preference)));
+            } else if (isFloatPreference(preference)) {
+                map.put(preference, String_valueOf(useDefault ? store.getDefaultFloat(preference) : store.getFloat(preference)));
+            } else if (isLongPreference(preference)) {
+                map.put(preference, String_valueOf(useDefault ? store.getDefaultLong(preference) : store.getLong(preference)));
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/formatter/FormattingContextProperties.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.formatter.FormattingContextProperties;
+
+import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport
+import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.FormattingContext; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport
+import dwtx.jface.text.formatter.IContentFormatter; // packageimport
+import dwtx.jface.text.formatter.ContentFormatter; // packageimport
+import dwtx.jface.text.formatter.IFormattingContext; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Keys used by <code>IFormattingContext</code> objects to register specific
+ * properties needed during the formatting process of a content formatter
+ * implementing <code>IContentFormatterExtension</code>.
+ *
+ * @see IFormattingContext
+ * @see IFormattingStrategyExtension
+ * @see IContentFormatterExtension
+ * @since 3.0
+ */
+public class FormattingContextProperties {
+
+    /**
+     * Property key of the document property. The property must implement
+     * <code>java.lang#Boolean</code>. If set to <code>true</code> the whole
+     * document is formatted.
+     * <p>
+     * Value: <code>"formatting.context.document"</code>
+     */
+    public static const String CONTEXT_DOCUMENT= "formatting.context.document"; //$NON-NLS-1$
+
+    /**
+     * Property key of the partition property. The property must implement
+     * <code>dwtx.jface.text#TypedPosition</code>. The partition
+     * a context based formatting strategy should format.
+     * <p>
+     * Value: <code>"formatting.context.partition"</code>
+     */
+    public static const String CONTEXT_PARTITION= "formatting.context.partition"; //$NON-NLS-1$
+
+    /**
+     * Property key of the preferences property. The property must implement
+     * <code>java.util#Map</code>. The formatting preferences mapping preference
+     * keys to values.
+     * <p>
+     * Value: <code>"formatting.context.preferences"</code>
+     */
+    public static const String CONTEXT_PREFERENCES= "formatting.context.preferences"; //$NON-NLS-1$
+
+    /**
+     * Property key of the region property. The property must implement <code>dwtx.jface.text#IRegion</code>.
+     * The region to format. If set, {@link FormattingContextProperties#CONTEXT_DOCUMENT} should be <code>false</code>
+     * for this to take effect.
+     * <p>
+     * Value: <code>"formatting.context.region"</code>
+     */
+    public static const String CONTEXT_REGION= "formatting.context.region"; //$NON-NLS-1$
+
+    /**
+     * Property key of the medium property. The property must implement <code>dwtx.jface.text#IDocument</code>.
+     * The document to format.
+     * <p>
+     * Value: <code>"formatting.context.medium"</code>
+     */
+    public static const String CONTEXT_MEDIUM= "formatting.context.medium"; //$NON-NLS-1$
+
+    /**
+     * Ensure that this class cannot be instantiated.
+     */
+    private this() {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/formatter/IContentFormatter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.formatter.IContentFormatter;
+
+import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport
+import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.FormattingContext; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport
+import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport
+import dwtx.jface.text.formatter.ContentFormatter; // packageimport
+import dwtx.jface.text.formatter.IFormattingContext; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+
+
+/**
+ * The interface of a document content formatter. The formatter formats ranges
+ * within documents. The documents are modified by the formatter.<p>
+ * The content formatter is assumed to determine the partitioning of the document
+ * range to be formatted. For each partition, the formatter determines based
+ * on the partition's content type the formatting strategy to be used. Before
+ * the first strategy is activated all strategies are informed about the
+ * start of the formatting process. After that, the formatting strategies are
+ * activated in the sequence defined by the partitioning of the document range to be
+ * formatted. It is assumed that a strategy must be finished before the next strategy
+ * can be activated. After the last strategy has been finished, all strategies are
+ * informed about the termination of the formatting process.</p>
+ * <p>
+ * The interface can be implemented by clients. By default, clients use <code>ContentFormatter</code>
+ * or <code>MultiPassContentFormatter</code> as the standard implementers of this interface.</p>
+ *
+ * @see IDocument
+ * @see IFormattingStrategy
+ */
+public interface IContentFormatter {
+
+    /**
+     * Formats the given region of the specified document.The formatter may safely
+     * assume that it is the only subject that modifies the document at this point in time.
+     *
+     * @param document the document to be formatted
+     * @param region the region within the document to be formatted
+     */
+    void format(IDocument document, IRegion region);
+
+    /**
+     * Returns the formatting strategy registered for the given content type.
+     *
+     * @param contentType the content type for which to look up the formatting strategy
+     * @return the formatting strategy for the given content type, or
+     *      <code>null</code> if there is no such strategy
+     */
+    IFormattingStrategy getFormattingStrategy(String contentType);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/formatter/IContentFormatterExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.formatter.IContentFormatterExtension;
+
+import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport
+import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.FormattingContext; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport
+import dwtx.jface.text.formatter.IContentFormatter; // packageimport
+import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport
+import dwtx.jface.text.formatter.ContentFormatter; // packageimport
+import dwtx.jface.text.formatter.IFormattingContext; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.IDocument;
+
+/**
+ * Extension interface for {@link IContentFormatter}.
+ * <p>
+ * Updates the content formatter to be able to pass {@link IFormattingContext}
+ * context objects to {@link IFormattingStrategyExtension} objects
+ * operating in context based mode.
+ * <p>
+ * Clients using context based formatting call the method
+ * <code>format(IDocument, IFormattingContext)</code> with a properly
+ * initialized formatting context.<br>
+ * The formatting context must be set up according to the desired formatting mode:
+ * <ul>
+ * <li>For whole document formatting set the property {@link FormattingContextProperties#CONTEXT_DOCUMENT}.
+ * This is equivalent to setting {@link FormattingContextProperties#CONTEXT_REGION} with a region spanning
+ * the whole document.</li>
+ * <li>For multiple region formatting set the property {@link FormattingContextProperties#CONTEXT_REGION}.
+ * Note that the content formatter automatically aligns the region to a block selected region,
+ * and if the region spans multiple partitions, it also completes eventual partitions covered only
+ * partially by the region.</li>
+ * </ul>
+ * Depending on the registered formatting strategies, more context information must
+ * be passed in the formatting context, like e.g. {@link FormattingContextProperties#CONTEXT_PREFERENCES}.
+ * <p>
+ * Note that in context based mode the content formatter is fully reentrant, but not
+ * thread-safe.
+ * <p>
+ *
+ * @see IFormattingContext
+ * @see FormattingContextProperties
+ * @since 3.0
+ */
+public interface IContentFormatterExtension {
+
+    /**
+     * Formats the given region of the specified document.
+     * <p>
+     * The formatter may safely assume that it is the only subject that
+     * modifies the document at this point in time. This method is fully
+     * reentrant, but not thread-safe.
+     * <p>
+     * The formatting process performed by <code>format(IDocument, IFormattingContext)</code>
+     * happens as follows:
+     * <ul>
+     * <li>In a first pass the content formatter formats the range of the
+     * document to be formatted by using the master formatting strategy. This
+     * happens regardless of the content type of the underlying partition.
+     * </li>
+     * <li>In the second pass, the range is formatted again, this time using
+     * the registered slave formatting strategies. For each partition contained
+     * in the range to be formatted, the content formatter determines its
+     * content type and formats the partition with the correct formatting
+     * strategy.
+     * </li>
+     *
+     * @param document
+     *                  The document to be formatted
+     * @param context
+     *                   The formatting context to pass to the formatting strategies.
+     *                   This argument must not be <code>null</code>.
+     */
+    void format(IDocument document, IFormattingContext context);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/formatter/IFormattingContext.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,171 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.formatter.IFormattingContext;
+
+import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport
+import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.FormattingContext; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport
+import dwtx.jface.text.formatter.IContentFormatter; // packageimport
+import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport
+import dwtx.jface.text.formatter.ContentFormatter; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+import dwtx.jface.preference.IPreferenceStore;
+
+/**
+ * Formatting context used in formatting strategies implementing interface
+ * <code>IFormattingStrategyExtension</code>.
+ *
+ * @see IFormattingStrategyExtension
+ * @since 3.0
+ */
+public interface IFormattingContext {
+
+    /**
+     * Dispose of the formatting context.
+     * <p>
+     * Must be called after the formatting context has been used in a
+     * formatting process.
+     */
+    void dispose();
+
+    /**
+     * Returns the preference keys used for the retrieval of formatting
+     * preferences.
+     *
+     * @return The preference keys for formatting
+     */
+    String[] getPreferenceKeys();
+
+    /**
+     * Retrieves the property <code>key</code> from the formatting context
+     *
+     * @param key
+     *                  Key of the property to store in the context
+     * @return The property <code>key</code> if available, <code>null</code>
+     *               otherwise
+     */
+    Object getProperty(Object key);
+
+    /**
+     * Is this preference key for a bool preference?
+     *
+     * @param key
+     *                  The preference key to query its type
+     * @return <code>true</code> iff this key is for a bool preference,
+     *               <code>false</code> otherwise.
+     */
+    bool isBooleanPreference(String key);
+
+    /**
+     * Is this preference key for a double preference?
+     *
+     * @param key
+     *                  The preference key to query its type
+     * @return <code>true</code> iff this key is for a double preference,
+     *               <code>false</code> otherwise.
+     */
+    bool isDoublePreference(String key);
+
+    /**
+     * Is this preference key for a float preference?
+     *
+     * @param key
+     *                  The preference key to query its type
+     * @return <code>true</code> iff this key is for a float preference,
+     *               <code>false</code> otherwise.
+     */
+    bool isFloatPreference(String key);
+
+    /**
+     * Is this preference key for an integer preference?
+     *
+     * @param key
+     *                  The preference key to query its type
+     * @return <code>true</code> iff this key is for an integer preference,
+     *               <code>false</code> otherwise.
+     */
+    bool isIntegerPreference(String key);
+
+    /**
+     * Is this preference key for a long preference?
+     *
+     * @param key
+     *                  The preference key to query its type
+     * @return <code>true</code> iff this key is for a long preference,
+     *               <code>false</code> otherwise.
+     */
+    bool isLongPreference(String key);
+
+    /**
+     * Is this preference key for a string preference?
+     *
+     * @param key
+     *                  The preference key to query its type
+     * @return <code>true</code> iff this key is for a string preference,
+     *               <code>false</code> otherwise.
+     */
+    bool isStringPreference(String key);
+
+    /**
+     * Stores the preferences from a map to a preference store.
+     * <p>
+     * Note that the preference keys returned by
+     * {@link #getPreferenceKeys()} must not be used in the preference store.
+     * Otherwise the preferences are overwritten.
+     * </p>
+     *
+     * @param map
+     *                  Map to retrieve the preferences from
+     * @param store
+     *                  Preference store to store the preferences in
+     */
+    void mapToStore(Map map, IPreferenceStore store);
+
+    /**
+     * Stores the property <code>key</code> in the formatting context.
+     *
+     * @param key
+     *                  Key of the property to store in the context
+     * @param property
+     *                  Property to store in the context. If already present, the new
+     *                  property overwrites the present one.
+     */
+    void setProperty(Object key, Object property);
+
+    /**
+     * Retrieves the preferences from a preference store in a map.
+     * <p>
+     * Note that the preference keys returned by
+     * {@link #getPreferenceKeys()} must not be used in the map. Otherwise the
+     * preferences are overwritten.
+     * </p>
+     *
+     * @param store
+     *                  Preference store to retrieve the preferences from
+     * @param map
+     *                  Map to store the preferences in
+     * @param useDefault
+     *                  <code>true</code> if the default preferences should be
+     *                  used, <code>false</code> otherwise
+     */
+    void storeToMap(IPreferenceStore store, Map map, bool useDefault);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/formatter/IFormattingStrategy.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.formatter.IFormattingStrategy;
+
+import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport
+import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.FormattingContext; // packageimport
+import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport
+import dwtx.jface.text.formatter.IContentFormatter; // packageimport
+import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport
+import dwtx.jface.text.formatter.ContentFormatter; // packageimport
+import dwtx.jface.text.formatter.IFormattingContext; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A formatting strategy is assumed to be specialized on formatting text
+ * of a particular content type. Each formatting process calls the strategy's
+ * methods in the following sequence:
+ * <ul>
+ * <li><code>formatterStarts</code>
+ * <li><code>format</code>
+ * <li><code>formatterStops</code>
+ * </ul>
+ * <p>
+ * This interface must be implemented by clients. Implementers should be registered with
+ * a content formatter in order get involved in the formatting process.</p>
+ */
+public interface IFormattingStrategy {
+
+    /**
+     * Informs the strategy about the start of a formatting process in which it will
+     * participate.
+     *
+     * @param initialIndentation the indent string of the first line at which the
+     *      overall formatting process starts.
+     */
+    void formatterStarts(String initialIndentation);
+
+    /**
+     * Formats the given string. During the formatting process this strategy must update
+     * the given character positions according to the changes applied to the given string.
+     *
+     * @param content the initial string to be formatted
+     * @param isLineStart indicates whether the beginning of content is a line start in its document
+     * @param indentation the indentation string to be used
+     * @param positions the character positions to be updated
+     * @return the formatted string
+     */
+    String format(String content, bool isLineStart, String indentation, int[] positions);
+
+    /**
+     * Informs the strategy that the formatting process in which it has participated
+     * has been finished.
+     */
+    void formatterStops();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/formatter/IFormattingStrategyExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.formatter.IFormattingStrategyExtension;
+
+import dwtx.jface.text.formatter.MultiPassContentFormatter; // packageimport
+import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.FormattingContext; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport
+import dwtx.jface.text.formatter.IContentFormatter; // packageimport
+import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport
+import dwtx.jface.text.formatter.ContentFormatter; // packageimport
+import dwtx.jface.text.formatter.IFormattingContext; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for <code>IFormattingStrategy</code>.
+ * <p>
+ * Updates formatting strategies to be able to receive a more general <code>IFormattingContext</code>
+ * object from its associated content formatters.
+ * <p>
+ * Each formatting process calls the strategy's methods in the following
+ * sequence:
+ * <ul>
+ * <li><code>formatterStarts</code>
+ * <li><code>format</code>
+ * <li><code>formatterStops</code>
+ * </ul>
+ * <p>
+ * Note that multiple calls to <code>formatterStarts</code> can be issued to
+ * a strategy before launching the formatting process with <code>format</code>.
+ * <p>
+ * This interface must be implemented by clients. Implementers should be
+ * registered with a content formatter in order get involved in the formatting
+ * process.
+ *
+ * @see IFormattingContext
+ * @since 3.0
+ */
+public interface IFormattingStrategyExtension {
+
+    /**
+     * Formats the region with the properties indicated in the formatting
+     * context previously supplied by <code>formatterStarts(IFormattingContext)</code>.
+     */
+    void format();
+
+    /**
+     * Informs the strategy about the start of a formatting process in which it
+     * will participate.
+     *
+     * @param context
+     *                  Formatting context used in the corresponding formatting
+     *                  process.
+     */
+    void formatterStarts(IFormattingContext context);
+
+    /**
+     * Informs the strategy that the formatting process in which it has
+     * participated has been finished.
+     */
+    void formatterStops();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/formatter/MultiPassContentFormatter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,333 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.formatter.MultiPassContentFormatter;
+
+import dwtx.jface.text.formatter.ContextBasedFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.FormattingContext; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategy; // packageimport
+import dwtx.jface.text.formatter.IContentFormatterExtension; // packageimport
+import dwtx.jface.text.formatter.IFormattingStrategyExtension; // packageimport
+import dwtx.jface.text.formatter.IContentFormatter; // packageimport
+import dwtx.jface.text.formatter.FormattingContextProperties; // packageimport
+import dwtx.jface.text.formatter.ContentFormatter; // packageimport
+import dwtx.jface.text.formatter.IFormattingContext; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.DefaultPositionUpdater;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITypedRegion;
+import dwtx.jface.text.TextUtilities;
+import dwtx.jface.text.TypedPosition;
+
+/**
+ * Content formatter for edit-based formatting strategies.
+ * <p>
+ * Two kinds of formatting strategies can be registered with this formatter:
+ * <ul>
+ * <li>one master formatting strategy for the default content type</li>
+ * <li>one formatting strategy for each non-default content type</li>
+ * </ul>
+ * The master formatting strategy always formats the whole region to be
+ * formatted in the first pass. In a second pass, all partitions of the region
+ * to be formatted that are not of master content type are formatted using the
+ * slave formatting strategy registered for the underlying content type. All
+ * formatting strategies must implement {@link IFormattingStrategyExtension}.
+ * <p>
+ * Regions to be formatted with the master formatting strategy always have
+ * an offset aligned to the line start. Regions to be formatted with slave formatting
+ * strategies are aligned on partition boundaries.
+ *
+ * @see IFormattingStrategyExtension
+ * @since 3.0
+ */
+public class MultiPassContentFormatter : IContentFormatter, IContentFormatterExtension {
+
+    /**
+     * Position updater that shifts otherwise deleted positions to the next
+     * non-whitespace character. The length of the positions are truncated to
+     * one if the position was shifted.
+     */
+    protected class NonDeletingPositionUpdater : DefaultPositionUpdater {
+
+        /**
+         * Creates a new non-deleting position updater.
+         *
+         * @param category The position category to update its positions
+         */
+        public this(String category) {
+            super(category);
+        }
+
+        /*
+         * @see dwtx.jface.text.DefaultPositionUpdater#notDeleted()
+         */
+        protected final bool notDeleted() {
+
+            if (fOffset < fPosition.offset && (fPosition.offset + fPosition.length < fOffset + fLength)) {
+
+                int offset= fOffset + fLength;
+                if (offset < fDocument.getLength()) {
+
+                    try {
+
+                        bool moved= false;
+                        char character= fDocument.getChar(offset);
+
+                        while (offset < fDocument.getLength() && Character.isWhitespace(character)) {
+
+                            moved= true;
+                            character= fDocument.getChar(offset++);
+                        }
+
+                        if (moved)
+                            offset--;
+
+                    } catch (BadLocationException exception) {
+                        // Can not happen
+                    }
+
+                    fPosition.offset= offset;
+                    fPosition.length= 0;
+                }
+            }
+            return true;
+        }
+    }
+
+    /** The master formatting strategy */
+    private IFormattingStrategyExtension fMaster= null;
+    /** The partitioning of this content formatter */
+    private const String fPartitioning;
+    /** The slave formatting strategies */
+    private const Map fSlaves;
+    /** The default content type */
+    private const String fType;
+
+    /**
+     * Creates a new content formatter.
+     *
+     * @param partitioning the document partitioning for this formatter
+     * @param type the default content type
+     */
+    public this(String partitioning, String type) {
+        fSlaves= new HashMap();
+
+        fPartitioning= partitioning;
+        fType= type;
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IContentFormatterExtension#format(dwtx.jface.text.IDocument, dwtx.jface.text.formatter.IFormattingContext)
+     */
+    public final void format(IDocument medium, IFormattingContext context) {
+
+        context.setProperty(stringcast(FormattingContextProperties.CONTEXT_MEDIUM), cast(Object)medium);
+
+        final Boolean document= cast(Boolean)context.getProperty(stringcast(FormattingContextProperties.CONTEXT_DOCUMENT));
+        if (document is null || !document.booleanValue()) {
+
+            final IRegion region= cast(IRegion)context.getProperty(stringcast(FormattingContextProperties.CONTEXT_REGION));
+            if (region !is null) {
+                try {
+                    formatMaster(context, medium, region.getOffset(), region.getLength());
+                } finally {
+                    formatSlaves(context, medium, region.getOffset(), region.getLength());
+                }
+            }
+        } else {
+            try {
+                formatMaster(context, medium, 0, medium.getLength());
+            } finally {
+                formatSlaves(context, medium, 0, medium.getLength());
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IContentFormatter#format(dwtx.jface.text.IDocument, dwtx.jface.text.IRegion)
+     */
+    public final void format(IDocument medium, IRegion region) {
+
+        final FormattingContext context= new FormattingContext();
+
+        context.setProperty(stringcast(FormattingContextProperties.CONTEXT_DOCUMENT), Boolean.FALSE);
+        context.setProperty(stringcast(FormattingContextProperties.CONTEXT_REGION), cast(Object)region);
+
+        format(medium, context);
+    }
+
+    /**
+     * Formats the document specified in the formatting context with the master
+     * formatting strategy.
+     * <p>
+     * The master formatting strategy covers all regions of the document. The
+     * offset of the region to be formatted is aligned on line start boundaries,
+     * whereas the end index of the region remains the same. For this formatting
+     * type the document partitioning is not taken into account.
+     *
+     * @param context The formatting context to use
+     * @param document The document to operate on
+     * @param offset The offset of the region to format
+     * @param length The length of the region to format
+     */
+    protected void formatMaster(IFormattingContext context, IDocument document, int offset, int length) {
+
+        try {
+
+            final int delta= offset - document.getLineInformationOfOffset(offset).getOffset();
+            offset -= delta;
+            length += delta;
+
+        } catch (BadLocationException exception) {
+            // Do nothing
+        }
+
+        if (fMaster !is null) {
+
+            context.setProperty(stringcast(FormattingContextProperties.CONTEXT_PARTITION), new TypedPosition(offset, length, fType));
+
+            fMaster.formatterStarts(context);
+            fMaster.format();
+            fMaster.formatterStops();
+        }
+    }
+
+    /**
+     * Formats the document specified in the formatting context with the
+     * formatting strategy registered for the content type.
+     * <p>
+     * For this formatting type only slave strategies are used. The region to be
+     * formatted is aligned on partition boundaries of the underlying content
+     * type. The exact formatting strategy is determined by the underlying
+     * content type of the document partitioning.
+     *
+     * @param context The formatting context to use
+     * @param document The document to operate on
+     * @param offset The offset of the region to format
+     * @param length The length of the region to format
+     * @param type The content type of the region to format
+     */
+    protected void formatSlave(IFormattingContext context, IDocument document, int offset, int length, String type) {
+
+        final IFormattingStrategyExtension strategy= cast(IFormattingStrategyExtension)fSlaves.get(type);
+        if (strategy !is null) {
+
+            context.setProperty(stringcast(FormattingContextProperties.CONTEXT_PARTITION), new TypedPosition(offset, length, type));
+
+            strategy.formatterStarts(context);
+            strategy.format();
+            strategy.formatterStops();
+        }
+    }
+
+    /**
+     * Formats the document specified in the formatting context with the slave
+     * formatting strategies.
+     * <p>
+     * For each content type of the region to be formatted in the document
+     * partitioning, the registered slave formatting strategy is used to format
+     * that particular region. The region to be formatted is aligned on
+     * partition boundaries of the underlying content type. If the content type
+     * is the document's default content type, nothing happens.
+     *
+     * @param context The formatting context to use
+     * @param document The document to operate on
+     * @param offset The offset of the region to format
+     * @param length The length of the region to format
+     */
+    protected void formatSlaves(IFormattingContext context, IDocument document, int offset, int length) {
+
+        Map partitioners= new HashMap(0);
+        try {
+
+            final ITypedRegion[] partitions= TextUtilities.computePartitioning(document, fPartitioning, offset, length, false);
+
+            if (!fType.equals(partitions[0].getType()))
+                partitions[0]= TextUtilities.getPartition(document, fPartitioning, partitions[0].getOffset(), false);
+
+            if (partitions.length > 1) {
+
+                if (!fType.equals(partitions[partitions.length - 1].getType()))
+                    partitions[partitions.length - 1]= TextUtilities.getPartition(document, fPartitioning, partitions[partitions.length - 1].getOffset(), false);
+            }
+
+            String type= null;
+            ITypedRegion partition= null;
+
+            partitioners= TextUtilities.removeDocumentPartitioners(document);
+
+            for (int index= partitions.length - 1; index >= 0; index--) {
+
+                partition= partitions[index];
+                type= partition.getType();
+
+                if (!fType.equals(type))
+                    formatSlave(context, document, partition.getOffset(), partition.getLength(), type);
+            }
+
+        } catch (BadLocationException exception) {
+            // Should not happen
+        } finally {
+            TextUtilities.addDocumentPartitioners(document, partitioners);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.formatter.IContentFormatter#getFormattingStrategy(java.lang.String)
+     */
+    public final IFormattingStrategy getFormattingStrategy(String type) {
+        return null;
+    }
+
+    /**
+     * Registers a master formatting strategy.
+     * <p>
+     * The strategy may already be registered with a certain content type as
+     * slave strategy. The master strategy is registered for the default content
+     * type of documents. If a master strategy has already been registered, it
+     * is overridden by the new one.
+     *
+     * @param strategy The master formatting strategy, must implement
+     *  {@link IFormattingStrategyExtension}
+     */
+    public final void setMasterStrategy(IFormattingStrategy strategy) {
+        Assert.isTrue( null !is cast(IFormattingStrategyExtension)strategy );
+        fMaster= cast(IFormattingStrategyExtension) strategy;
+    }
+
+    /**
+     * Registers a slave formatting strategy for a certain content type.
+     * <p>
+     * The strategy may already be registered as master strategy. An
+     * already registered slave strategy for the specified content type
+     * will be replaced. However, the same strategy may be registered with
+     * several content types. Slave strategies cannot be registered for the
+     * default content type of documents.
+     *
+     * @param strategy The slave formatting strategy
+     * @param type The content type to register this strategy with,
+     *  must implement {@link IFormattingStrategyExtension}
+     */
+    public final void setSlaveStrategy(IFormattingStrategy strategy, String type) {
+        Assert.isTrue( null !is cast(IFormattingStrategyExtension)strategy );
+        if (!fType.equals(type))
+            fSlaves.put(type, cast(Object)strategy);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/hyperlink/AbstractHyperlinkDetector.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.hyperlink.AbstractHyperlinkDetector;
+
+import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport
+import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlink; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.IAdaptable;
+
+
+/**
+ * A hyperlink detector that can provide adapters through
+ * a context that can be set by the creator of this hyperlink
+ * detector.
+ * <p>
+ * Clients may subclass.
+ * </p>
+ * 
+ * @since 3.3
+ */
+public abstract class AbstractHyperlinkDetector : IHyperlinkDetector, IHyperlinkDetectorExtension {
+
+    /**
+     * The context of this hyperlink detector.
+     */
+    private IAdaptable fContext;
+
+    /**
+     * Sets this hyperlink detector's context which
+     * is responsible to provide the adapters.
+     * 
+     * @param context the context for this hyperlink detector
+     * @throws IllegalArgumentException if the context is <code>null</code>
+     * @throws IllegalStateException if this method is called more than once
+     */
+    public final void setContext(IAdaptable context)  {
+        Assert.isLegal(context !is null);
+        if (fContext !is null)
+            throw new IllegalStateException();
+        fContext= context;
+    }
+
+    /*
+     * @see dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension#dispose()
+     */
+    public void dispose() {
+        fContext= null;
+    }
+
+    /**
+     * Returns an object which is an instance of the given class
+     * and provides additional context for this hyperlink detector.
+     *
+     * @param adapterClass the adapter class to look up
+     * @return an instance that can be cast to the given class, 
+     *          or <code>null</code> if this object does not
+     *          have an adapter for the given class
+     */
+    protected final Object getAdapter(ClassInfo adapterClass) {
+        Assert.isLegal(adapterClass !is null);
+        if (fContext !is null)
+            return fContext.getAdapter(adapterClass);
+        return null;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/hyperlink/DefaultHyperlinkPresenter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,396 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter;
+
+import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport
+import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlink; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+
+import dwt.DWT;
+import dwt.custom.StyleRange;
+import dwt.custom.StyledText;
+import dwt.graphics.Color;
+import dwt.graphics.Cursor;
+import dwt.graphics.RGB;
+import dwt.widgets.Display;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.preference.IPreferenceStore;
+import dwtx.jface.preference.PreferenceConverter;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentListener;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextInputListener;
+import dwtx.jface.text.ITextPresentationListener;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension2;
+import dwtx.jface.text.ITextViewerExtension4;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextPresentation;
+import dwtx.jface.util.IPropertyChangeListener;
+import dwtx.jface.util.PropertyChangeEvent;
+
+
+/**
+ * The default hyperlink presenter underlines the
+ * link and colors the line and the text with
+ * the given color.
+ * <p>
+ * It can only be used together with the {@link HyperlinkManager#FIRST}
+ * or the {@link HyperlinkManager#LONGEST_REGION_FIRST} hyperlink strategy.
+ * </p>
+ *
+ * @since 3.1
+ */
+public class DefaultHyperlinkPresenter : IHyperlinkPresenter, IHyperlinkPresenterExtension, ITextPresentationListener, ITextInputListener, IDocumentListener, IPropertyChangeListener {
+
+    /**
+     * A named preference that holds the color used for hyperlinks.
+     * <p>
+     * Value is of type <code>String</code>. A RGB color value encoded as a string
+     * using class <code>PreferenceConverter</code>
+     * </p>
+     *
+     * @see dwtx.jface.resource.StringConverter
+     * @see dwtx.jface.preference.PreferenceConverter
+     */
+    public const static String HYPERLINK_COLOR= "hyperlinkColor"; //$NON-NLS-1$
+
+
+    /** The text viewer. */
+    private ITextViewer fTextViewer;
+    /** The hand cursor. */
+    private Cursor fCursor;
+    /** The link color. */
+    private Color fColor;
+    /** The link color specification. May be <code>null</code>. */
+    private RGB fRGB;
+    /** Tells whether to dispose the color on uninstall. */
+    private bool fDisposeColor;
+    /** The currently active region. */
+    private IRegion fActiveRegion;
+    /** The currently active style range as position. */
+    private Position fRememberedPosition;
+    /** The optional preference store. May be <code>null</code>. */
+    private IPreferenceStore fPreferenceStore;
+
+
+    /**
+     * Creates a new default hyperlink presenter which uses
+     * {@link #HYPERLINK_COLOR} to read the color from the given preference store.
+     *
+     * @param store the preference store
+     */
+    public this(IPreferenceStore store) {
+        fPreferenceStore= store;
+        fDisposeColor= true;
+    }
+
+    /**
+     * Creates a new default hyperlink presenter.
+     *
+     * @param color the hyperlink color, to be disposed by the caller
+     */
+    public this(Color color) {
+        fDisposeColor= false;
+        fColor= color;
+    }
+
+    /**
+     * Creates a new default hyperlink presenter.
+     *
+     * @param color the hyperlink color
+     */
+    public this(RGB color) {
+        fRGB= color;
+        fDisposeColor= true;
+    }
+
+    /*
+     * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#canShowMultipleHyperlinks()
+     */
+    public bool canShowMultipleHyperlinks() {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#activate(dwtx.jdt.internal.ui.javaeditor.IHyperlink[])
+     */
+    public void showHyperlinks(IHyperlink[] hyperlinks) {
+        Assert.isLegal(hyperlinks !is null && hyperlinks.length is 1);
+        highlightRegion(hyperlinks[0].getHyperlinkRegion());
+        activateCursor();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 3.4
+     */
+    public bool canHideHyperlinks() {
+        return true;
+    }
+
+    /*
+     * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#deactivate()
+     */
+    public void hideHyperlinks() {
+        repairRepresentation();
+        fRememberedPosition= null;
+    }
+
+    /*
+     * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#install(dwtx.jface.text.ITextViewer)
+     */
+    public void install(ITextViewer textViewer) {
+        Assert.isNotNull(cast(Object)textViewer);
+        fTextViewer= textViewer;
+        fTextViewer.addTextInputListener(this);
+        if ( cast(ITextViewerExtension4)fTextViewer )
+            (cast(ITextViewerExtension4)fTextViewer).addTextPresentationListener(this);
+
+        StyledText text= fTextViewer.getTextWidget();
+        if (text !is null && !text.isDisposed()) {
+            if (fPreferenceStore !is null)
+                fColor= createColor(fPreferenceStore, HYPERLINK_COLOR, text.getDisplay());
+            else if (fRGB !is null)
+                fColor= new Color(text.getDisplay(), fRGB);
+        }
+
+        if (fPreferenceStore !is null)
+            fPreferenceStore.addPropertyChangeListener(this);
+    }
+
+    /*
+     * @see dwtx.jdt.internal.ui.javaeditor.IHyperlinkControl#uninstall()
+     */
+    public void uninstall() {
+        fTextViewer.removeTextInputListener(this);
+        IDocument document= fTextViewer.getDocument();
+        if (document !is null)
+            document.removeDocumentListener(this);
+
+        if (fColor !is null) {
+            if (fDisposeColor)
+                fColor.dispose();
+            fColor= null;
+        }
+
+        if (fCursor !is null) {
+            fCursor.dispose();
+            fCursor= null;
+        }
+
+        if ( cast(ITextViewerExtension4)fTextViewer )
+            (cast(ITextViewerExtension4)fTextViewer).removeTextPresentationListener(this);
+        fTextViewer= null;
+
+        if (fPreferenceStore !is null)
+            fPreferenceStore.removePropertyChangeListener(this);
+    }
+
+    public void setColor(Color color) {
+        Assert.isNotNull(cast(Object)fTextViewer);
+        fColor= color;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextPresentationListener#applyTextPresentation(dwtx.jface.text.TextPresentation)
+     */
+    public void applyTextPresentation(TextPresentation textPresentation) {
+        if (fActiveRegion is null)
+            return;
+        IRegion region= textPresentation.getExtent();
+        if (fActiveRegion.getOffset() + fActiveRegion.getLength() >= region.getOffset() && region.getOffset() + region.getLength() > fActiveRegion.getOffset()) {
+            StyleRange styleRange= new StyleRange(fActiveRegion.getOffset(), fActiveRegion.getLength(), fColor, null);
+            styleRange.underline= true;
+            textPresentation.mergeStyleRange(styleRange);
+        }
+    }
+
+    private void highlightRegion(IRegion region) {
+
+        if ((cast(Object)region).opEquals(cast(Object)fActiveRegion))
+            return;
+
+        repairRepresentation();
+
+        StyledText text= fTextViewer.getTextWidget();
+        if (text is null || text.isDisposed())
+            return;
+
+        // Invalidate region is> apply text presentation
+        fActiveRegion= region;
+        if ( cast(ITextViewerExtension2)fTextViewer )
+            (cast(ITextViewerExtension2)fTextViewer).invalidateTextPresentation(region.getOffset(), region.getLength());
+        else
+            fTextViewer.invalidateTextPresentation();
+    }
+
+    private void activateCursor() {
+        StyledText text= fTextViewer.getTextWidget();
+        if (text is null || text.isDisposed())
+            return;
+        Display display= text.getDisplay();
+        if (fCursor is null)
+            fCursor= new Cursor(display, DWT.CURSOR_HAND);
+        text.setCursor(fCursor);
+    }
+
+    private void resetCursor() {
+        StyledText text= fTextViewer.getTextWidget();
+        if (text !is null && !text.isDisposed())
+            text.setCursor(null);
+
+        if (fCursor !is null) {
+            fCursor.dispose();
+            fCursor= null;
+        }
+    }
+
+    private void repairRepresentation() {
+
+        if (fActiveRegion is null)
+            return;
+
+        int offset= fActiveRegion.getOffset();
+        int length= fActiveRegion.getLength();
+        fActiveRegion= null;
+
+        resetCursor();
+
+        // Invalidate is> remove applied text presentation
+        if ( cast(ITextViewerExtension2)fTextViewer )
+            (cast(ITextViewerExtension2) fTextViewer).invalidateTextPresentation(offset, length);
+        else
+            fTextViewer.invalidateTextPresentation();
+
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentListener#documentAboutToBeChanged(dwtx.jface.text.DocumentEvent)
+     */
+    public void documentAboutToBeChanged(DocumentEvent event) {
+        if (fActiveRegion !is null) {
+            fRememberedPosition= new Position(fActiveRegion.getOffset(), fActiveRegion.getLength());
+            try {
+                event.getDocument().addPosition(fRememberedPosition);
+            } catch (BadLocationException x) {
+                fRememberedPosition= null;
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentListener#documentChanged(dwtx.jface.text.DocumentEvent)
+     */
+    public void documentChanged(DocumentEvent event) {
+        if (fRememberedPosition !is null) {
+            if (!fRememberedPosition.isDeleted()) {
+                event.getDocument().removePosition(fRememberedPosition);
+                fActiveRegion= new Region(fRememberedPosition.getOffset(), fRememberedPosition.getLength());
+            } else {
+                fActiveRegion= new Region(event.getOffset(), event.getLength());
+            }
+            fRememberedPosition= null;
+
+            StyledText widget= fTextViewer.getTextWidget();
+            if (widget !is null && !widget.isDisposed()) {
+                widget.getDisplay().asyncExec(new class()  Runnable {
+                    public void run() {
+                        hideHyperlinks();
+                    }
+                });
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument)
+     */
+    public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
+        if (oldInput is null)
+            return;
+        hideHyperlinks();
+        oldInput.removeDocumentListener(this);
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextInputListener#inputDocumentChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument)
+     */
+    public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+        if (newInput is null)
+            return;
+        newInput.addDocumentListener(this);
+    }
+
+    /**
+     * Creates a color from the information stored in the given preference store.
+     *
+     * @param store the preference store
+     * @param key the key
+     * @param display the display
+     * @return the color or <code>null</code> if there is no such information available
+     */
+    private Color createColor(IPreferenceStore store, String key, Display display) {
+
+        RGB rgb= null;
+
+        if (store.contains(key)) {
+
+            if (store.isDefault(key))
+                rgb= PreferenceConverter.getDefaultColor(store, key);
+            else
+                rgb= PreferenceConverter.getColor(store, key);
+
+            if (rgb !is null)
+                return new Color(display, rgb);
+        }
+
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.util.IPropertyChangeListener#propertyChange(dwtx.jface.util.PropertyChangeEvent)
+     */
+    public void propertyChange(PropertyChangeEvent event) {
+        if (!HYPERLINK_COLOR.equals(event.getProperty()))
+            return;
+
+        if (fDisposeColor && fColor !is null && !fColor.isDisposed())
+            fColor.dispose();
+        fColor= null;
+
+        StyledText textWidget= fTextViewer.getTextWidget();
+        if (textWidget !is null && !textWidget.isDisposed())
+            fColor= createColor(fPreferenceStore, HYPERLINK_COLOR, textWidget.getDisplay());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/hyperlink/HyperlinkManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,610 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Steffen Pingel <steffen.pingel@tasktop.com> (Tasktop Technologies Inc.) - [navigation] hyperlink decoration is not erased when mouse is moved out of Text widget - https://bugs.eclipse.org/bugs/show_bug.cgi?id=100278
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.hyperlink.HyperlinkManager;
+
+import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport
+import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlink; // packageimport
+
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.FocusEvent;
+import dwt.events.FocusListener;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.events.MouseMoveListener;
+import dwt.events.MouseTrackListener;
+import dwt.graphics.Point;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextListener;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextEvent;
+
+
+/**
+ * Default implementation of a hyperlink manager.
+ *
+ * @since 3.1
+ */
+public class HyperlinkManager : ITextListener, Listener, KeyListener, MouseListener, MouseMoveListener, FocusListener, MouseTrackListener {
+
+    /**
+     * Detection strategy.
+     */
+    public static final class DETECTION_STRATEGY {
+
+        String fName;
+
+        private this(String name) {
+            fName= name;
+        }
+
+        /*
+         * @see java.lang.Object#toString()
+         */
+        public override String toString() {
+            return fName;
+        }
+    }
+
+
+    /**
+     * The first detected hyperlink is passed to the
+     * hyperlink presenter and no further detector
+     * is consulted.
+     */
+    private static DETECTION_STRATEGY FIRST_;
+    public static DETECTION_STRATEGY FIRST(){
+        if( FIRST_ is null ){
+            synchronized( HyperlinkManager.classinfo ){
+                if( FIRST_ is null ){
+                    FIRST_ = new DETECTION_STRATEGY("first"); //$NON-NLS-1$
+                }
+            }
+        }
+        return FIRST_;
+    }
+
+    /**
+     * All detected hyperlinks from all detectors are collected
+     * and passed to the hyperlink presenter.
+     * <p>
+     * This strategy is only allowed if {@link IHyperlinkPresenter#canShowMultipleHyperlinks()}
+     * returns <code>true</code>.
+     * </p>
+     */
+    private static DETECTION_STRATEGY ALL_;
+    public static DETECTION_STRATEGY ALL(){
+        if( ALL_ is null ){
+            synchronized( HyperlinkManager.classinfo ){
+                if( ALL_ is null ){
+                    ALL_ = new DETECTION_STRATEGY("all"); //$NON-NLS-1$
+                }
+            }
+        }
+        return ALL_;
+    }
+
+    /**
+     * All detected hyperlinks from all detectors are collected
+     * and all those with the longest region are passed to the
+     * hyperlink presenter.
+     * <p>
+     * This strategy is only allowed if {@link IHyperlinkPresenter#canShowMultipleHyperlinks()}
+     * returns <code>true</code>.
+     * </p>
+     */
+    private static DETECTION_STRATEGY LONGEST_REGION_ALL_;
+    public static DETECTION_STRATEGY LONGEST_REGION_ALL(){
+        if( LONGEST_REGION_ALL_ is null ){
+            synchronized( HyperlinkManager.classinfo ){
+                if( LONGEST_REGION_ALL_ is null ){
+                    LONGEST_REGION_ALL_ = new DETECTION_STRATEGY("all with same longest region"); //$NON-NLS-1$
+                }
+            }
+        }
+        return LONGEST_REGION_ALL_;
+    }
+
+    /**
+     * All detected hyperlinks from all detectors are collected
+     * and form all those with the longest region only the first
+     * one is passed to the hyperlink presenter.
+     */
+    private static DETECTION_STRATEGY LONGEST_REGION_FIRST_;
+    public static DETECTION_STRATEGY LONGEST_REGION_FIRST(){
+        if( LONGEST_REGION_FIRST_ is null ){
+            synchronized( HyperlinkManager.classinfo ){
+                if( LONGEST_REGION_FIRST_ is null ){
+                    LONGEST_REGION_FIRST_ = new DETECTION_STRATEGY("first with longest region"); //$NON-NLS-1$
+                }
+            }
+        }
+        return LONGEST_REGION_FIRST_;
+    }
+
+
+    /** The text viewer on which this hyperlink manager works. */
+    private ITextViewer fTextViewer;
+    /** The session is active. */
+    private bool fActive;
+    /** The key modifier mask. */
+    private int fHyperlinkStateMask;
+    /**
+     * The active key modifier mask.
+     * @since 3.3
+     */
+    private int fActiveHyperlinkStateMask;
+    /** The active hyperlinks. */
+    private IHyperlink[] fActiveHyperlinks;
+    /** The hyperlink detectors. */
+    private IHyperlinkDetector[] fHyperlinkDetectors;
+    /** The hyperlink presenter. */
+    private IHyperlinkPresenter fHyperlinkPresenter;
+    /** The detection strategy. */
+    private const DETECTION_STRATEGY fDetectionStrategy;
+
+
+    /**
+     * Creates a new hyperlink manager.
+     *
+     * @param detectionStrategy the detection strategy one of {{@link #ALL}, {@link #FIRST}, {@link #LONGEST_REGION_ALL}, {@link #LONGEST_REGION_FIRST}}
+     */
+    public this(DETECTION_STRATEGY detectionStrategy) {
+        Assert.isNotNull(detectionStrategy);
+        fDetectionStrategy= detectionStrategy;
+    }
+
+    /**
+     * Installs this hyperlink manager with the given arguments.
+     *
+     * @param textViewer the text viewer
+     * @param hyperlinkPresenter the hyperlink presenter
+     * @param hyperlinkDetectors the array of hyperlink detectors, must not be empty
+     * @param eventStateMask the DWT event state mask to activate hyperlink mode
+     */
+    public void install(ITextViewer textViewer, IHyperlinkPresenter hyperlinkPresenter, IHyperlinkDetector[] hyperlinkDetectors, int eventStateMask) {
+        Assert.isNotNull(cast(Object)textViewer);
+        Assert.isNotNull(cast(Object)hyperlinkPresenter);
+        fTextViewer= textViewer;
+        fHyperlinkPresenter= hyperlinkPresenter;
+        Assert.isLegal(fHyperlinkPresenter.canShowMultipleHyperlinks() || fDetectionStrategy is FIRST || fDetectionStrategy is LONGEST_REGION_FIRST);
+        setHyperlinkDetectors(hyperlinkDetectors);
+        setHyperlinkStateMask(eventStateMask);
+
+        StyledText text= fTextViewer.getTextWidget();
+        if (text is null || text.isDisposed())
+            return;
+
+        text.getDisplay().addFilter(DWT.KeyUp, this);
+        text.addKeyListener(this);
+        text.addMouseListener(this);
+        text.addMouseMoveListener(this);
+        text.addFocusListener(this);
+        text.addMouseTrackListener(this);
+
+        fTextViewer.addTextListener(this);
+
+        fHyperlinkPresenter.install(fTextViewer);
+    }
+
+    /**
+     * Sets the hyperlink detectors for this hyperlink manager.
+     * <p>
+     * It is allowed to call this method after this
+     * hyperlink manger has been installed.
+     * </p>
+     *
+     * @param hyperlinkDetectors and array of hyperlink detectors, must not be empty
+     */
+    public void setHyperlinkDetectors(IHyperlinkDetector[] hyperlinkDetectors) {
+        Assert.isTrue(hyperlinkDetectors !is null && hyperlinkDetectors.length > 0);
+        if (fHyperlinkDetectors is null){
+            fHyperlinkDetectors= hyperlinkDetectors;
+        }
+        else {
+            synchronized (/+fHyperlinkDetectors+/this) {
+                fHyperlinkDetectors= hyperlinkDetectors;
+            }
+        }
+    }
+
+    /**
+     * Sets the DWT event state mask which in combination
+     * with the left mouse button triggers the hyperlink mode.
+     * <p>
+     * It is allowed to call this method after this
+     * hyperlink manger has been installed.
+     * </p>
+     *
+     * @param eventStateMask the DWT event state mask to activate hyperlink mode
+     */
+    public void setHyperlinkStateMask(int eventStateMask) {
+        fHyperlinkStateMask= eventStateMask;
+    }
+
+    /**
+     * Uninstalls this hyperlink manager.
+     */
+    public void uninstall() {
+        deactivate();
+
+        StyledText text= fTextViewer.getTextWidget();
+        if (text !is null && !text.isDisposed()) {
+            text.removeKeyListener(this);
+            text.getDisplay().removeFilter(DWT.KeyUp, this);
+            text.removeMouseListener(this);
+            text.removeMouseMoveListener(this);
+            text.removeFocusListener(this);
+            text.removeMouseTrackListener(this);
+        }
+        fTextViewer.removeTextListener(this);
+
+        fHyperlinkPresenter.uninstall();
+
+        fHyperlinkPresenter= null;
+        fTextViewer= null;
+        fHyperlinkDetectors= null;
+    }
+
+    /**
+     * Deactivates the currently shown hyperlinks.
+     */
+    protected void deactivate() {
+        fHyperlinkPresenter.hideHyperlinks();
+        fActive= false;
+    }
+
+    /**
+     * Finds hyperlinks at the current offset.
+     *
+     * @return the hyperlinks or <code>null</code> if none.
+     */
+    protected IHyperlink[] findHyperlinks() {
+        int offset= getCurrentTextOffset();
+        if (offset is -1)
+            return null;
+
+        bool canShowMultipleHyperlinks= fHyperlinkPresenter.canShowMultipleHyperlinks();
+        IRegion region= new Region(offset, 0);
+        List allHyperlinks= new ArrayList(fHyperlinkDetectors.length * 2);
+        synchronized (/+fHyperlinkDetectors+/this) {
+            for (int i= 0, length= fHyperlinkDetectors.length; i < length; i++) {
+                IHyperlinkDetector detector= fHyperlinkDetectors[i];
+                if (detector is null)
+                    continue;
+
+                if ( cast(IHyperlinkDetectorExtension2)detector ) {
+                    int stateMask= (cast(IHyperlinkDetectorExtension2)detector).getStateMask();
+                    if (stateMask !is -1 && stateMask !is fActiveHyperlinkStateMask)
+                        continue;
+                    else if (stateMask is -1 && fActiveHyperlinkStateMask !is fHyperlinkStateMask)
+                    continue;
+                } else if (fActiveHyperlinkStateMask !is fHyperlinkStateMask)
+                    continue;
+
+                IHyperlink[] hyperlinks= detector.detectHyperlinks(fTextViewer, region, canShowMultipleHyperlinks);
+                if (hyperlinks is null)
+                    continue;
+
+                Assert.isLegal(hyperlinks.length > 0);
+
+                if (fDetectionStrategy is FIRST) {
+                    if (hyperlinks.length is 1)
+                        return hyperlinks;
+                    return [hyperlinks[0]];
+                }
+                allHyperlinks.addAll(Arrays.asList(arraycast!(Object)(hyperlinks)));
+            }
+        }
+
+        if (allHyperlinks.isEmpty())
+            return null;
+
+        if (fDetectionStrategy !is ALL) {
+            int maxLength= computeLongestHyperlinkLength(allHyperlinks);
+            Iterator iter= (new ArrayList(allHyperlinks)).iterator();
+            while (iter.hasNext()) {
+                IHyperlink hyperlink= cast(IHyperlink)iter.next();
+                if (hyperlink.getHyperlinkRegion().getLength() < maxLength)
+                    allHyperlinks.remove(cast(Object)hyperlink);
+            }
+        }
+
+        if (fDetectionStrategy is LONGEST_REGION_FIRST)
+            return [cast(IHyperlink)allHyperlinks.get(0)];
+
+        return arraycast!(IHyperlink)(allHyperlinks.toArray());
+
+    }
+
+    /**
+     * Computes the length of the longest detected
+     * hyperlink.
+     *
+     * @param hyperlinks
+     * @return the length of the longest detected
+     */
+    protected int computeLongestHyperlinkLength(List hyperlinks) {
+        Assert.isLegal(hyperlinks !is null && !hyperlinks.isEmpty());
+        Iterator iter= hyperlinks.iterator();
+        int length= Integer.MIN_VALUE;
+        while (iter.hasNext()) {
+            IRegion region= (cast(IHyperlink)iter.next()).getHyperlinkRegion();
+            if (region.getLength() < length)
+                continue;
+            length= region.getLength();
+        }
+        return length;
+    }
+
+    /**
+     * Returns the current text offset.
+     *
+     * @return the current text offset
+     */
+    protected int getCurrentTextOffset() {
+
+        try {
+            StyledText text= fTextViewer.getTextWidget();
+            if (text is null || text.isDisposed())
+                return -1;
+
+            Display display= text.getDisplay();
+            Point absolutePosition= display.getCursorLocation();
+            Point relativePosition= text.toControl(absolutePosition);
+
+            int widgetOffset= text.getOffsetAtLocation(relativePosition);
+            Point p= text.getLocationAtOffset(widgetOffset);
+            if (p.x > relativePosition.x)
+                widgetOffset--;
+
+            if ( cast(ITextViewerExtension5)fTextViewer ) {
+                ITextViewerExtension5 extension= cast(ITextViewerExtension5)fTextViewer;
+                return extension.widgetOffset2ModelOffset(widgetOffset);
+            }
+
+            return widgetOffset + fTextViewer.getVisibleRegion().getOffset();
+
+        } catch (IllegalArgumentException e) {
+            return -1;
+        }
+    }
+
+    /*
+     * @see dwt.events.KeyListener#keyPressed(dwt.events.KeyEvent)
+     */
+    public void keyPressed(KeyEvent event) {
+
+        if (fActive) {
+            deactivate();
+            return;
+        }
+
+        if (!isRegisteredStateMask(event.keyCode)) {
+            deactivate();
+            return;
+        }
+
+        fActive= true;
+        fActiveHyperlinkStateMask= event.keyCode;
+
+//          removed for #25871 (hyperlinks could interact with typing)
+//
+//          ITextViewer viewer= getSourceViewer();
+//          if (viewer is null)
+//              return;
+//
+//          IRegion region= getCurrentTextRegion(viewer);
+//          if (region is null)
+//              return;
+//
+//          highlightRegion(viewer, region);
+//          activateCursor(viewer);
+    }
+
+    /*
+     * @see dwt.events.KeyListener#keyReleased(dwt.events.KeyEvent)
+     */
+    public void keyReleased(KeyEvent event) {
+    }
+
+    /*
+     * @see dwt.events.MouseListener#mouseDoubleClick(dwt.events.MouseEvent)
+     */
+    public void mouseDoubleClick(MouseEvent e) {
+
+    }
+
+    /*
+     * @see dwt.events.MouseListener#mouseDown(dwt.events.MouseEvent)
+     */
+    public void mouseDown(MouseEvent event) {
+
+        if (!fActive)
+            return;
+
+        if (event.stateMask !is fActiveHyperlinkStateMask) {
+            deactivate();
+            return;
+        }
+
+        if (event.button !is 1) {
+            deactivate();
+            return;
+        }
+    }
+
+    /*
+     * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent)
+     */
+    public void mouseUp(MouseEvent e) {
+
+        if (!fActive) {
+            fActiveHyperlinks= null;
+            return;
+        }
+
+        if (e.button !is 1)
+            fActiveHyperlinks= null;
+
+        deactivate();
+
+        if (fActiveHyperlinks !is null)
+            fActiveHyperlinks[0].open();
+    }
+
+    /*
+     * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent)
+     */
+    public void mouseMove(MouseEvent event) {
+        if ( cast(IHyperlinkPresenterExtension)fHyperlinkPresenter ) {
+            if (!(cast(IHyperlinkPresenterExtension)fHyperlinkPresenter).canHideHyperlinks())
+                return;
+        }
+
+        if (!isRegisteredStateMask(event.stateMask)) {
+            if (fActive)
+                deactivate();
+
+            return;
+        }
+
+        fActive= true;
+        fActiveHyperlinkStateMask= event.stateMask;
+
+        StyledText text= fTextViewer.getTextWidget();
+        if (text is null || text.isDisposed()) {
+            deactivate();
+            return;
+        }
+
+        if ((event.stateMask & DWT.BUTTON1) !is 0 && text.getSelectionCount() !is 0) {
+            deactivate();
+            return;
+        }
+
+        fActiveHyperlinks= findHyperlinks();
+        if (fActiveHyperlinks is null || fActiveHyperlinks.length is 0) {
+            fHyperlinkPresenter.hideHyperlinks();
+            return;
+        }
+
+        fHyperlinkPresenter.showHyperlinks(fActiveHyperlinks);
+
+    }
+
+    /**
+     * Checks whether the given state mask is registered.
+     *
+     * @param stateMask
+     * @return <code>true</code> if a detector is registered for the given state mask
+     * @since 3.3
+     */
+    private bool isRegisteredStateMask(int stateMask) {
+        if (stateMask is fHyperlinkStateMask)
+            return true;
+
+        synchronized (/+fHyperlinkDetectors+/this) {
+            for (int i= 0; i < fHyperlinkDetectors.length; i++) {
+                if (cast(IHyperlinkDetectorExtension2)fHyperlinkDetectors[i] ) {
+                    if (stateMask is (cast(IHyperlinkDetectorExtension2)fHyperlinkDetectors[i]).getStateMask())
+                        return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /*
+     * @see dwt.events.FocusListener#focusGained(dwt.events.FocusEvent)
+     */
+    public void focusGained(FocusEvent e) {}
+
+    /*
+     * @see dwt.events.FocusListener#focusLost(dwt.events.FocusEvent)
+     */
+    public void focusLost(FocusEvent event) {
+        deactivate();
+    }
+
+    /*
+     * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event)
+     * @since 3.2
+     */
+    public void handleEvent(Event event) {
+        //key up
+        deactivate();
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextListener#textChanged(TextEvent)
+     * @since 3.2
+     */
+    public void textChanged(TextEvent event) {
+        if (event.getDocumentEvent() !is null)
+            deactivate();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 3.4
+     */
+    public void mouseExit(MouseEvent e) {
+        if ( cast(IHyperlinkPresenterExtension)fHyperlinkPresenter ) {
+            if (!(cast(IHyperlinkPresenterExtension)fHyperlinkPresenter).canHideHyperlinks())
+                return;
+        }
+        deactivate();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 3.4
+     */
+    public void mouseEnter(MouseEvent e) {
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 3.4
+     */
+    public void mouseHover(MouseEvent e) {
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/hyperlink/HyperlinkMessages.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.hyperlink.HyperlinkMessages;
+
+import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport
+import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlink; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.dwthelper.ResourceBundle;
+
+
+/**
+ * Helper class to get NLSed messages.
+ *
+ * @since 3.4
+ */
+class HyperlinkMessages {
+//     private static const String BUNDLE_NAME= HyperlinkMessages.classinfo.getName();
+
+    private static const ResourceBundle RESOURCE_BUNDLE;//= ResourceBundle.getBundle(BUNDLE_NAME);
+
+    static this() {
+        RESOURCE_BUNDLE = ResourceBundle.getBundle(
+            getImportData!("dwtx.jface.text.hyperlink.HyperlinkMessages.properties"));
+    }
+
+    private this() {
+    }
+
+    /**
+     * Gets a string from the resource bundle.
+     *
+     * @param key the string used to get the bundle value, must not be
+     *            <code>null</code>
+     * @return the string from the resource bundle
+     */
+    public static String getString(String key) {
+        try {
+            return RESOURCE_BUNDLE.getString(key);
+        } catch (MissingResourceException e) {
+            return '!' ~ key ~ '!';
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/hyperlink/IHyperlink.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.hyperlink.IHyperlink;
+
+import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport
+import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.IRegion;
+
+
+/**
+ * Represents a hyperlink.
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ *
+ * @since 3.1
+ */
+public interface IHyperlink {
+
+    /**
+     * The region covered by this type of hyperlink.
+     *
+     * @return the hyperlink region
+     */
+    IRegion getHyperlinkRegion();
+
+    /**
+     * Optional label for this type of hyperlink.
+     * <p>
+     * This type label can be used by {@link IHyperlinkPresenter}s
+     * which show several hyperlinks at once.
+     * </p>
+     *
+     * @return the type label or <code>null</code> if none
+     */
+    String getTypeLabel();
+
+    /**
+     * Optional text for this hyperlink.
+     * <p>
+     * This can be used in situations where there are
+     * several targets for the same hyperlink location.
+     * </p>
+     *
+     * @return the text or <code>null</code> if none
+     */
+    String getHyperlinkText();
+
+    /**
+     * Opens the given hyperlink.
+     */
+    void open();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/hyperlink/IHyperlinkDetector.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.hyperlink.IHyperlinkDetector;
+
+import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport
+import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlink; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.source.SourceViewerConfiguration;
+
+
+/**
+ * A hyperlink detector tries to find a hyperlink at
+ * a given location in a given text viewer.
+ * <p>
+ * In order to provide backward compatibility for clients of <code>IHyperlinkDetector</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link IHyperlinkDetectorExtension} since version 3.3,
+ *      adds the ability to dispose a hyperlink detector
+ * </li>
+ * <li>{@link IHyperlinkDetectorExtension2} since version 3.3,
+ *      adds the ability to specify the state mask of the modifier
+ *      keys that need to be pressed for this hyperlink detector
+ * </li>
+ * </ul></p>
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ *
+ * @see SourceViewerConfiguration#getHyperlinkDetectors(dwtx.jface.text.source.ISourceViewer)
+ * @since 3.1
+ */
+public interface IHyperlinkDetector {
+
+    /**
+     * Tries to detect hyperlinks for the given region in
+     * the given text viewer and returns them.
+     * <p>
+     * In most of the cases only one hyperlink should be returned.
+     * </p>
+     * @param textViewer the text viewer on which the hover popup should be shown
+     * @param region the text range in the text viewer which is used to detect the hyperlinks
+     * @param canShowMultipleHyperlinks tells whether the caller is able to show multiple links
+     *                      to the user.
+     *                      If <code>true</code> {@link IHyperlink#open()} should directly open
+     *                          the link and not show any additional UI to select from a list.
+     *                      If <code>false</code> this method should only return one hyperlink
+     *                          which upon {@link IHyperlink#open()} may allow to select from a list.
+     * @return the hyperlinks or <code>null</code> if no hyperlink was detected
+     */
+    IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, bool canShowMultipleHyperlinks);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/hyperlink/IHyperlinkDetectorExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension;
+
+import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport
+import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlink; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extends {@link IHyperlinkDetector} with ability
+ * to dispose a hyperlink detector.
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ * 
+ * @since 3.3
+ */
+public interface IHyperlinkDetectorExtension {
+
+    /**
+     * Disposes this hyperlink detector.
+     */
+    void dispose();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/hyperlink/IHyperlinkDetectorExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2;
+
+import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport
+import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlink; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extends {@link IHyperlinkDetector} with ability
+ * to specify the state mask of the modifier keys that
+ * need to be pressed for this hyperlink detector.
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ * 
+ * @since 3.3
+ */
+public interface IHyperlinkDetectorExtension2 {
+
+    /**
+     * Returns the state mask of the modifier keys that
+     * need to be pressed for this hyperlink detector.
+     * 
+     * @return the state mask
+     */
+    int getStateMask();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/hyperlink/IHyperlinkPresenter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.hyperlink.IHyperlinkPresenter;
+
+import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport
+import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlink; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * A hyperlink presenter shows hyperlinks on the installed text viewer
+ * and allows to pick one on of the hyperlinks.
+ * <p>
+ * In order to provide backward compatibility for clients of <code>IHyperlinkDetector</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link IHyperlinkPresenterExtension} since version 3.4,
+ *      adds the ability to query  whether the currently shown hyperlinks
+ *      can be hidden.
+ * </li>
+ * </ul></p>
+ * <p>
+ * Clients may implement this interface. A default implementation is provided
+ * through {@link dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter}.
+ * </p>
+ *
+ * @see IHyperlinkPresenterExtension
+ * @since 3.1
+ */
+public interface IHyperlinkPresenter {
+
+    /**
+     * Tells whether this presenter is able to handle
+     * more than one hyperlink.
+     *
+     * @return <code>true</code> if this presenter can handle more than one hyperlink
+     */
+    bool canShowMultipleHyperlinks();
+
+    /**
+     * Tells this hyperlink presenter to show the given
+     * hyperlinks on the installed text viewer.
+     *
+     * @param hyperlinks the hyperlinks to show
+     * @throws IllegalArgumentException if
+     *          <ul>
+     *              <li><code>hyperlinks</code> is empty</li>
+     *              <li>{@link #canShowMultipleHyperlinks()} returns <code>false</code> and <code>hyperlinks</code> contains more than one element</li>
+     *          </ul>
+     */
+    void showHyperlinks(IHyperlink[] hyperlinks) ;
+
+    /**
+     * Tells this hyperlink presenter to hide the hyperlinks
+     * requested to be shown by {@link #showHyperlinks(IHyperlink[])}.
+     */
+    void hideHyperlinks();
+
+    /**
+     * Installs this hyperlink presenter on the given text viewer.
+     *
+     * @param textViewer the text viewer
+     */
+    void install(ITextViewer textViewer);
+
+    /**
+     * Uninstalls this hyperlink presenter.
+     */
+    void uninstall();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/hyperlink/IHyperlinkPresenterExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension;
+
+import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlink; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extends {@link IHyperlinkPresenter} with ability
+ * to query whether the currently shown hyperlinks
+ * can be hidden.
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ * 
+ * @since 3.4
+ */
+public interface IHyperlinkPresenterExtension {
+
+    /**
+     * Tells whether the currently shown hyperlinks
+     * can be hidden.
+     * 
+     * @return <code>true</code> if the hyperlink manager can hide the current hyperlinks
+     */
+    bool canHideHyperlinks();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/hyperlink/MultipleHyperlinkPresenter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,754 @@
+/*******************************************************************************
+ * Copyright (c) 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter;
+
+import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlink; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwt.DWT;
+import dwt.events.KeyAdapter;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.events.MouseAdapter;
+import dwt.events.MouseEvent;
+import dwt.events.MouseMoveListener;
+import dwt.events.SelectionAdapter;
+import dwt.events.SelectionEvent;
+import dwt.events.ShellAdapter;
+import dwt.events.ShellEvent;
+import dwt.graphics.Color;
+import dwt.graphics.Point;
+import dwt.graphics.RGB;
+import dwt.graphics.Rectangle;
+import dwt.layout.GridLayout;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwt.widgets.Shell;
+import dwt.widgets.Table;
+import dwt.widgets.TableItem;
+import dwtx.jface.preference.IPreferenceStore;
+import dwtx.jface.text.AbstractInformationControl;
+import dwtx.jface.text.AbstractInformationControlManager;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.IInformationControlExtension2;
+import dwtx.jface.text.IInformationControlExtension3;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextHover;
+import dwtx.jface.text.ITextHoverExtension;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.IWidgetTokenKeeper;
+import dwtx.jface.text.IWidgetTokenKeeperExtension;
+import dwtx.jface.text.IWidgetTokenOwner;
+import dwtx.jface.text.IWidgetTokenOwnerExtension;
+import dwtx.jface.text.JFaceTextUtil;
+import dwtx.jface.text.Region;
+import dwtx.jface.util.Geometry;
+import dwtx.jface.viewers.ColumnLabelProvider;
+import dwtx.jface.viewers.IStructuredContentProvider;
+import dwtx.jface.viewers.TableViewer;
+import dwtx.jface.viewers.Viewer;
+
+
+/**
+ * A hyperlink presenter capable of showing multiple hyperlinks in a hover.
+ *
+ * @since 3.4
+ */
+public class MultipleHyperlinkPresenter : DefaultHyperlinkPresenter {
+
+    /**
+     * An information control capable of showing a list of hyperlinks. The hyperlinks can be opened.
+     */
+    private static class LinkListInformationControl : AbstractInformationControl , IInformationControlExtension2 {
+
+        private static final class LinkContentProvider : IStructuredContentProvider {
+
+            /*
+             * @see dwtx.jface.viewers.IStructuredContentProvider#getElements(java.lang.Object)
+             */
+            public Object[] getElements(Object inputElement) {
+                return arrayFromObject!(Object)( inputElement);
+            }
+
+            /*
+             * @see dwtx.jface.viewers.IContentProvider#dispose()
+             */
+            public void dispose() {
+            }
+
+            /*
+             * @see dwtx.jface.viewers.IContentProvider#inputChanged(dwtx.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+             */
+            public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+            }
+        }
+
+        private static final class LinkLabelProvider : ColumnLabelProvider {
+            /*
+             * @see dwtx.jface.viewers.ColumnLabelProvider#getText(java.lang.Object)
+             */
+            public String getText(Object element) {
+                IHyperlink link= cast(IHyperlink)element;
+                String text= link.getHyperlinkText();
+                if (text !is null)
+                    return text;
+                return HyperlinkMessages.getString("LinkListInformationControl.unknownLink"); //$NON-NLS-1$
+            }
+        }
+
+        private const MultipleHyperlinkHoverManager fManager;
+
+        private IHyperlink[] fInput;
+        private Composite fParent;
+        private Table fTable;
+
+        private Color fForegroundColor;
+        private Color fBackgroundColor;
+
+
+        /**
+         * Creates a link list information control with the given shell as parent.
+         *
+         * @param parentShell the parent shell
+         * @param manager the hover manager
+         * @param foregroundColor the foreground color, must not be disposed
+         * @param backgroundColor the background color, must not be disposed
+         */
+        public this(Shell parentShell, MultipleHyperlinkHoverManager manager, Color foregroundColor, Color backgroundColor) {
+            super(parentShell, false);
+            fManager= manager;
+            fForegroundColor= foregroundColor;
+            fBackgroundColor= backgroundColor;
+            create();
+        }
+
+        /*
+         * @see dwtx.jface.text.IInformationControl#setInformation(java.lang.String)
+         */
+        public void setInformation(String information) {
+            //replaced by IInformationControlExtension2#setInput(java.lang.Object)
+        }
+
+        /*
+         * @see dwtx.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
+         */
+        public void setInput(Object input) {
+            fInput= arrayFromObject!(IHyperlink)( input);
+            deferredCreateContent(fParent);
+        }
+
+        /*
+         * @see dwtx.jface.text.AbstractInformationControl#createContent(dwt.widgets.Composite)
+         */
+        protected void createContent(Composite parent) {
+            fParent= parent;
+            if ("win32".equals(DWT.getPlatform())) { //$NON-NLS-1$
+                GridLayout layout= new GridLayout();
+                layout.marginWidth= 0;
+                layout.marginRight= 4;
+                fParent.setLayout(layout);
+            }
+            fParent.setForeground(fForegroundColor);
+            fParent.setBackground(fBackgroundColor);
+        }
+
+        /*
+         * @see dwtx.jface.text.AbstractInformationControl#computeSizeHint()
+         */
+        public Point computeSizeHint() {
+            Point preferedSize= getShell().computeSize(DWT.DEFAULT, DWT.DEFAULT, true);
+
+            Point constraints= getSizeConstraints();
+            if (constraints is null)
+                return preferedSize;
+
+            if (fTable.getVerticalBar() is null || fTable.getHorizontalBar() is null)
+                return Geometry.min(constraints, preferedSize);
+
+            int scrollBarWidth= fTable.getVerticalBar().getSize().x;
+            int scrollBarHeight= fTable.getHorizontalBar().getSize().y;
+
+            int width;
+            if (preferedSize.y - scrollBarHeight <= constraints.y) {
+                width= preferedSize.x - scrollBarWidth;
+                fTable.getVerticalBar().setVisible(false);
+            } else {
+                width= Math.min(preferedSize.x, constraints.x);
+            }
+
+            int height;
+            if (preferedSize.x - scrollBarWidth <= constraints.x) {
+                height= preferedSize.y - scrollBarHeight;
+                fTable.getHorizontalBar().setVisible(false);
+            } else {
+                height= Math.min(preferedSize.y, constraints.y);
+            }
+
+            return new Point(width, height);
+        }
+
+        private void deferredCreateContent(Composite parent) {
+            fTable= new Table(parent, DWT.SINGLE | DWT.FULL_SELECTION);
+            fTable.setLinesVisible(false);
+            fTable.setHeaderVisible(false);
+            fTable.setForeground(fForegroundColor);
+            fTable.setBackground(fBackgroundColor);
+
+            final TableViewer viewer= new TableViewer(fTable);
+            viewer.setContentProvider(new LinkContentProvider());
+            viewer.setLabelProvider(new LinkLabelProvider());
+            viewer.setInput(new ArrayWrapperObject( arraycast!(Object)(fInput)));
+            fTable.setSelection(0);
+
+            registerTableListeners();
+
+            getShell().addShellListener(new class()  ShellAdapter {
+
+                /*
+                 * @see dwt.events.ShellAdapter#shellActivated(dwt.events.ShellEvent)
+                 */
+                public void shellActivated(ShellEvent e) {
+                    if (viewer.getTable().getSelectionCount() is 0) {
+                        viewer.getTable().setSelection(0);
+                    }
+
+                    viewer.getTable().setFocus();
+                }
+            });
+        }
+
+        private void registerTableListeners() {
+
+            fTable.addMouseMoveListener(new class()  MouseMoveListener {
+                TableItem fLastItem= null;
+
+                public void mouseMove(MouseEvent e) {
+                    if (fTable.opEquals(e.getSource())) {
+                        Object o= fTable.getItem(new Point(e.x, e.y));
+                        if ( cast(TableItem)o ) {
+                            TableItem item= cast(TableItem) o;
+                            if (!o.opEquals(fLastItem)) {
+                                fLastItem= cast(TableItem) o;
+                                fTable.setSelection([ fLastItem ]);
+                            } else if (e.y < fTable.getItemHeight() / 4) {
+                                // Scroll up
+                                int index= fTable.indexOf(item);
+                                if (index > 0) {
+                                    fLastItem= fTable.getItem(index - 1);
+                                    fTable.setSelection([ fLastItem ]);
+                                }
+                            } else if (e.y > fTable.getBounds().height - fTable.getItemHeight() / 4) {
+                                // Scroll down
+                                int index= fTable.indexOf(item);
+                                if (index < fTable.getItemCount() - 1) {
+                                    fLastItem= fTable.getItem(index + 1);
+                                    fTable.setSelection([ fLastItem ]);
+                                }
+                            }
+                        }
+                    }
+                }
+            });
+
+            fTable.addSelectionListener(new class()  SelectionAdapter {
+                public void widgetSelected(SelectionEvent e) {
+                    openSelectedLink();
+                }
+            });
+
+            fTable.addMouseListener(new class()  MouseAdapter {
+                public void mouseUp(MouseEvent e) {
+                    if (fTable.getSelectionCount() < 1)
+                        return;
+
+                    if (e.button !is 1)
+                        return;
+
+                    if (fTable.opEquals(e.getSource())) {
+                        Object o= fTable.getItem(new Point(e.x, e.y));
+                        TableItem selection= fTable.getSelection()[0];
+                        if (selection.opEquals(o))
+                            openSelectedLink();
+                    }
+                }
+            });
+
+            fTable.addKeyListener(new class()  KeyAdapter {
+                public void keyPressed(KeyEvent e) {
+                    if (e.keyCode is 0x0D) // return
+                        openSelectedLink();
+                }
+            });
+        }
+
+        /*
+         * @see dwtx.jface.text.IInformationControlExtension#hasContents()
+         */
+        public bool hasContents() {
+            return true;
+        }
+
+        /**
+         * Opens the currently selected link.
+         */
+        private void openSelectedLink() {
+            TableItem selection= fTable.getSelection()[0];
+            IHyperlink link= cast(IHyperlink)selection.getData();
+            fManager.hideInformationControl();
+            link.open();
+        }
+    }
+
+    private class MultipleHyperlinkHover : ITextHover, ITextHoverExtension {
+
+        /**
+         * @see dwtx.jface.text.ITextHover#getHoverInfo(dwtx.jface.text.ITextViewer, dwtx.jface.text.IRegion)
+         * @deprecated
+         */
+        public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
+            return null;
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextHover#getHoverRegion(dwtx.jface.text.ITextViewer, int)
+         */
+        public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
+            return fSubjectRegion;
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextHoverExtension2#getHoverInfo2(dwtx.jface.text.ITextViewer, dwtx.jface.text.IRegion)
+         */
+        public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) {
+            return new ArrayWrapperObject( arraycast!(Object)(fHyperlinks));
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextHoverExtension#getHoverControlCreator()
+         */
+        public IInformationControlCreator getHoverControlCreator() {
+            return new class()  IInformationControlCreator {
+                public IInformationControl createInformationControl(Shell parent) {
+                    Color foregroundColor= fTextViewer.getTextWidget().getForeground();
+                    Color backgroundColor= fTextViewer.getTextWidget().getBackground();
+                    return new LinkListInformationControl(parent, fManager, foregroundColor, backgroundColor);
+                }
+            };
+        }
+    }
+
+    private static class MultipleHyperlinkHoverManager : AbstractInformationControlManager , IWidgetTokenKeeper, IWidgetTokenKeeperExtension {
+
+        private class Closer : IInformationControlCloser, Listener, KeyListener {
+
+            private Control fSubjectControl;
+            private Display fDisplay;
+            private IInformationControl fControl;
+            private Rectangle fSubjectArea;
+
+            /*
+             * @see dwtx.jface.text.AbstractInformationControlManager.IInformationControlCloser#setInformationControl(dwtx.jface.text.IInformationControl)
+             */
+            public void setInformationControl(IInformationControl control) {
+                fControl= control;
+            }
+
+            /*
+             * @see dwtx.jface.text.AbstractInformationControlManager.IInformationControlCloser#setSubjectControl(dwt.widgets.Control)
+             */
+            public void setSubjectControl(Control subject) {
+                fSubjectControl= subject;
+            }
+
+            /*
+             * @see dwtx.jface.text.AbstractInformationControlManager.IInformationControlCloser#start(dwt.graphics.Rectangle)
+             */
+            public void start(Rectangle subjectArea) {
+                fSubjectArea= subjectArea;
+
+                fDisplay= fSubjectControl.getDisplay();
+                if (!fDisplay.isDisposed()) {
+                    fDisplay.addFilter(DWT.FocusOut, this);
+                    fDisplay.addFilter(DWT.MouseMove, this);
+                    fTextViewer.getTextWidget().addKeyListener(this);
+                }
+            }
+
+            /*
+             * @see dwtx.jface.text.AbstractInformationControlManager.IInformationControlCloser#stop()
+             */
+            public void stop() {
+                if (fDisplay !is null && !fDisplay.isDisposed()) {
+                    fDisplay.removeFilter(DWT.FocusOut, this);
+                    fDisplay.removeFilter(DWT.MouseMove, this);
+                    fTextViewer.getTextWidget().removeKeyListener(this);
+                }
+
+                fSubjectArea= null;
+            }
+
+            /*
+             * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event)
+             */
+            public void handleEvent(Event event) {
+                switch (event.type) {
+                    case DWT.FocusOut:
+                        if (!fControl.isFocusControl())
+                            disposeInformationControl();
+                        break;
+                    case DWT.MouseMove:
+                        handleMouseMove(event);
+                        break;
+                }
+            }
+
+            /**
+             * Handle mouse movement events.
+             *
+             * @param event the event
+             */
+            private void handleMouseMove(Event event) {
+                if (!(cast(Control)event.widget ))
+                    return;
+
+                if (fControl.isFocusControl())
+                    return;
+
+                Control eventControl= cast(Control) event.widget;
+
+                //transform coordinates to subject control:
+                Point mouseLoc= event.display.map(eventControl, fSubjectControl, event.x, event.y);
+
+                if (fSubjectArea.contains(mouseLoc))
+                    return;
+
+                if (inKeepUpZone(mouseLoc.x, mouseLoc.y, (cast(IInformationControlExtension3) fControl).getBounds()))
+                    return;
+
+                hideInformationControl();
+            }
+
+            /**
+             * Tests whether a given mouse location is within the keep-up zone.
+             * The hover should not be hidden as long as the mouse stays inside this zone.
+             *
+             * @param x the x coordinate, relative to the <em>subject control</em>
+             * @param y the y coordinate, relative to the <em>subject control</em>
+             * @param controlBounds the bounds of the current control
+             *
+             * @return <code>true</code> iff the mouse event occurred in the keep-up zone
+             */
+            private bool inKeepUpZone(int x, int y, Rectangle controlBounds) {
+                //  +-----------+
+                //  |subjectArea|
+                //  +-----------+
+                //  |also keepUp|
+                // ++-----------+-------+
+                // | totalBounds        |
+                // +--------------------+
+                if (fSubjectArea.contains(x, y))
+                    return true;
+
+                Rectangle iControlBounds= fSubjectControl.getDisplay().map(null, fSubjectControl, controlBounds);
+                Rectangle totalBounds= Geometry.copy(iControlBounds);
+                if (totalBounds.contains(x, y))
+                    return true;
+
+                int keepUpY= fSubjectArea.y + fSubjectArea.height;
+                Rectangle alsoKeepUp= new Rectangle(fSubjectArea.x, keepUpY, fSubjectArea.width, totalBounds.y - keepUpY);
+                return alsoKeepUp.contains(x, y);
+            }
+
+            /*
+             * @see dwt.events.KeyListener#keyPressed(dwt.events.KeyEvent)
+             */
+            public void keyPressed(KeyEvent e) {
+            }
+
+            /*
+             * @see dwt.events.KeyListener#keyReleased(dwt.events.KeyEvent)
+             */
+            public void keyReleased(KeyEvent e) {
+                hideInformationControl();
+            }
+
+        }
+
+        /**
+         * Priority of the hover managed by this manager.
+         * Default value: One higher then for the hovers
+         * managed by TextViewerHoverManager.
+         */
+        private static const int WIDGET_TOKEN_PRIORITY= 1;
+
+        private const MultipleHyperlinkHover fHover;
+        private const ITextViewer fTextViewer;
+        private const MultipleHyperlinkPresenter fHyperlinkPresenter;
+        private Closer fCloser;
+        private bool fIsControlVisible;
+
+
+        /**
+         * Create a new MultipleHyperlinkHoverManager. The MHHM can show and hide
+         * the given MultipleHyperlinkHover inside the given ITextViewer.
+         *
+         * @param hover the hover to manage
+         * @param viewer the viewer to show the hover in
+         * @param hyperlinkPresenter the hyperlink presenter using this manager to present hyperlinks
+         */
+        public this(MultipleHyperlinkHover hover, ITextViewer viewer, MultipleHyperlinkPresenter hyperlinkPresenter) {
+            super(hover.getHoverControlCreator());
+
+            fHover= hover;
+            fTextViewer= viewer;
+            fHyperlinkPresenter= hyperlinkPresenter;
+
+            fCloser= new Closer();
+            setCloser(fCloser);
+            fIsControlVisible= false;
+        }
+
+        /*
+         * @see dwtx.jface.text.AbstractInformationControlManager#computeInformation()
+         */
+        protected void computeInformation() {
+            IRegion region= fHover.getHoverRegion(fTextViewer, -1);
+            if (region is null) {
+                setInformation(cast(Object)null, cast(Rectangle)null);
+                return;
+            }
+
+            Rectangle area= JFaceTextUtil.computeArea(region, fTextViewer);
+            if (area is null || area.isEmpty()) {
+                setInformation(cast(Object)null, cast(Rectangle)null);
+                return;
+            }
+
+            Object information= fHover.getHoverInfo2(fTextViewer, region);
+            setCustomInformationControlCreator(fHover.getHoverControlCreator());
+            setInformation(information, area);
+        }
+
+        /*
+         * @see dwtx.jface.text.AbstractInformationControlManager#computeInformationControlLocation(dwt.graphics.Rectangle, dwt.graphics.Point)
+         */
+        protected Point computeInformationControlLocation(Rectangle subjectArea, Point controlSize) {
+            Point result= super.computeInformationControlLocation(subjectArea, controlSize);
+
+            Point cursorLocation= fTextViewer.getTextWidget().getDisplay().getCursorLocation();
+            if (cursorLocation.x <= result.x + controlSize.x)
+                return result;
+
+            result.x= cursorLocation.x + 20 - controlSize.x;
+            return result;
+        }
+
+        /*
+         * @see dwtx.jface.text.AbstractInformationControlManager#showInformationControl(dwt.graphics.Rectangle)
+         */
+        protected void showInformationControl(Rectangle subjectArea) {
+            if ( cast(IWidgetTokenOwnerExtension)fTextViewer ) {
+                if ((cast(IWidgetTokenOwnerExtension) fTextViewer).requestWidgetToken(this, WIDGET_TOKEN_PRIORITY))
+                    super.showInformationControl(subjectArea);
+            } else if ( cast(IWidgetTokenOwner)fTextViewer ) {
+                if ((cast(IWidgetTokenOwner) fTextViewer).requestWidgetToken(this))
+                    super.showInformationControl(subjectArea);
+            } else {
+                super.showInformationControl(subjectArea);
+            }
+
+            fIsControlVisible= true;
+        }
+
+        /*
+         * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl()
+         */
+        protected void hideInformationControl() {
+            super.hideInformationControl();
+
+            if ( cast(IWidgetTokenOwner)fTextViewer ) {
+                (cast(IWidgetTokenOwner) fTextViewer).releaseWidgetToken(this);
+            }
+
+            fIsControlVisible= false;
+            fHyperlinkPresenter.hideHyperlinks();
+        }
+
+        /*
+         * @see dwtx.jface.text.AbstractInformationControlManager#disposeInformationControl()
+         */
+        public void disposeInformationControl() {
+            super.disposeInformationControl();
+
+            if ( cast(IWidgetTokenOwner)fTextViewer ) {
+                (cast(IWidgetTokenOwner) fTextViewer).releaseWidgetToken(this);
+            }
+
+            fIsControlVisible= false;
+            fHyperlinkPresenter.hideHyperlinks();
+        }
+
+        /*
+         * @see dwtx.jface.text.IWidgetTokenKeeper#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner)
+         */
+        public bool requestWidgetToken(IWidgetTokenOwner owner) {
+            hideInformationControl();
+            return true;
+        }
+
+        /*
+         * @see dwtx.jface.text.IWidgetTokenKeeperExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner, int)
+         */
+        public bool requestWidgetToken(IWidgetTokenOwner owner, int priority) {
+            if (priority < WIDGET_TOKEN_PRIORITY)
+                return false;
+
+            hideInformationControl();
+            return true;
+        }
+
+        /*
+         * @see dwtx.jface.text.IWidgetTokenKeeperExtension#setFocus(dwtx.jface.text.IWidgetTokenOwner)
+         */
+        public bool setFocus(IWidgetTokenOwner owner) {
+            return false;
+        }
+
+        /**
+         * Returns <code>true</code> if the information control managed by
+         * this manager is visible, <code>false</code> otherwise.
+         *
+         * @return <code>true</code> if information control is visible
+         */
+        public bool isInformationControlVisible() {
+            return fIsControlVisible;
+        }
+    }
+
+    private ITextViewer fTextViewer;
+
+    private IHyperlink[] fHyperlinks;
+    private Region fSubjectRegion;
+    private MultipleHyperlinkHoverManager fManager;
+
+    /**
+     * Creates a new multiple hyperlink presenter which uses
+     * {@link #HYPERLINK_COLOR} to read the color from the given preference store.
+     *
+     * @param store the preference store
+     */
+    public this(IPreferenceStore store) {
+        super(store);
+    }
+
+    /**
+     * Creates a new multiple hyperlink presenter.
+     *
+     * @param color the hyperlink color, to be disposed by the caller
+     */
+    public this(RGB color) {
+        super(color);
+    }
+
+    /*
+     * @see dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter#install(dwtx.jface.text.ITextViewer)
+     */
+    public void install(ITextViewer viewer) {
+        super.install(viewer);
+        fTextViewer= viewer;
+
+        fManager= new MultipleHyperlinkHoverManager(new MultipleHyperlinkHover(), fTextViewer, this);
+        fManager.install(viewer.getTextWidget());
+        fManager.setSizeConstraints(100, 12, false, true);
+    }
+
+    /*
+     * @see dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter#uninstall()
+     */
+    public void uninstall() {
+        super.uninstall();
+
+        if (fTextViewer !is null) {
+            fManager.dispose();
+
+            fTextViewer= null;
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter#canShowMultipleHyperlinks()
+     */
+    public bool canShowMultipleHyperlinks() {
+        return true;
+    }
+
+    /*
+     * @see dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter#canHideHyperlinks()
+     */
+    public bool canHideHyperlinks() {
+        return !fManager.isInformationControlVisible();
+    }
+
+    /*
+     * @see dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter#hideHyperlinks()
+     */
+    public void hideHyperlinks() {
+        super.hideHyperlinks();
+
+        fHyperlinks= null;
+    }
+
+    /*
+     * @see dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter#showHyperlinks(dwtx.jface.text.hyperlink.IHyperlink[])
+     */
+    public void showHyperlinks(IHyperlink[] hyperlinks) {
+        super.showHyperlinks([ hyperlinks[0] ]);
+
+        fSubjectRegion= null;
+        fHyperlinks= hyperlinks;
+
+        if (hyperlinks.length is 1)
+            return;
+
+        int start= hyperlinks[0].getHyperlinkRegion().getOffset();
+        int end= start + hyperlinks[0].getHyperlinkRegion().getLength();
+
+        for (int i= 1; i < hyperlinks.length; i++) {
+            int hstart= hyperlinks[i].getHyperlinkRegion().getOffset();
+            int hend= hstart + hyperlinks[i].getHyperlinkRegion().getLength();
+
+            start= Math.min(start, hstart);
+            end= Math.max(end, hend);
+        }
+
+        fSubjectRegion= new Region(start, end - start);
+
+        fManager.showInformation();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/hyperlink/URLHyperlink.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.hyperlink.URLHyperlink;
+
+import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport
+import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlink; // packageimport
+
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.MessageFormat;
+
+import dwt.program.Program;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.IRegion;
+
+
+
+
+
+/**
+ * URL hyperlink.
+ *
+ * @since 3.1
+ */
+public class URLHyperlink : IHyperlink {
+
+    private String fURLString;
+    private IRegion fRegion;
+
+    /**
+     * Creates a new URL hyperlink.
+     *
+     * @param region
+     * @param urlString
+     */
+    public this(IRegion region, String urlString) {
+        Assert.isNotNull(urlString);
+        Assert.isNotNull(cast(Object)region);
+
+        fRegion= region;
+        fURLString= urlString;
+    }
+
+    /*
+     * @see dwtx.jdt.internal.ui.javaeditor.IHyperlink#getHyperlinkRegion()
+     */
+    public IRegion getHyperlinkRegion() {
+        return fRegion;
+    }
+
+    /*
+     * @see dwtx.jdt.internal.ui.javaeditor.IHyperlink#open()
+     */
+    public void open() {
+        if (fURLString !is null) {
+            Program.launch(fURLString);
+            fURLString= null;
+            return;
+        }
+    }
+
+    /*
+     * @see dwtx.jdt.internal.ui.javaeditor.IHyperlink#getTypeLabel()
+     */
+    public String getTypeLabel() {
+        return null;
+    }
+
+    /*
+     * @see dwtx.jdt.internal.ui.javaeditor.IHyperlink#getHyperlinkText()
+     */
+    public String getHyperlinkText() {
+        return MessageFormat.format(HyperlinkMessages.getString("URLHyperlink.hyperlinkText"), stringcast(fURLString) ); //$NON-NLS-1$
+    }
+
+    /**
+     * Returns the URL string of this hyperlink.
+     *
+     * @return the URL string
+     * @since 3.2
+     */
+    public String getURLString() {
+        return fURLString;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/hyperlink/URLHyperlinkDetector.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Benjamin Muskalla <b.muskalla@gmx.net> - https://bugs.eclipse.org/bugs/show_bug.cgi?id=156433
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.hyperlink.URLHyperlinkDetector;
+
+import dwtx.jface.text.hyperlink.IHyperlinkPresenterExtension; // packageimport
+import dwtx.jface.text.hyperlink.MultipleHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkManager; // packageimport
+import dwtx.jface.text.hyperlink.URLHyperlink; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension2; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter; // packageimport
+import dwtx.jface.text.hyperlink.AbstractHyperlinkDetector; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlinkDetectorExtension; // packageimport
+import dwtx.jface.text.hyperlink.HyperlinkMessages; // packageimport
+import dwtx.jface.text.hyperlink.IHyperlink; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.MalformedURLException;
+import dwtx.dwtxhelper.URL;
+import dwtx.dwtxhelper.StringTokenizer;
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.Region;
+
+
+/**
+ * URL hyperlink detector.
+ *
+ * @since 3.1
+ */
+public class URLHyperlinkDetector : AbstractHyperlinkDetector {
+
+
+    /**
+     * Creates a new URL hyperlink detector.
+     *
+     * @since 3.2
+     */
+    public this() {
+    }
+
+    /**
+     * Creates a new URL hyperlink detector.
+     *
+     * @param textViewer the text viewer in which to detect the hyperlink
+     * @deprecated As of 3.2, replaced by {@link URLHyperlinkDetector}
+     */
+    public this(ITextViewer textViewer) {
+    }
+
+    /*
+     * @see dwtx.jface.text.hyperlink.IHyperlinkDetector#detectHyperlinks(dwtx.jface.text.ITextViewer, dwtx.jface.text.IRegion, bool)
+     */
+    public IHyperlink[] detectHyperlinks(ITextViewer textViewer, IRegion region, bool canShowMultipleHyperlinks) {
+        if (region is null || textViewer is null)
+            return null;
+
+        IDocument document= textViewer.getDocument();
+
+        int offset= region.getOffset();
+
+        String urlString= null;
+        if (document is null)
+            return null;
+
+        IRegion lineInfo;
+        String line;
+        try {
+            lineInfo= document.getLineInformationOfOffset(offset);
+            line= document.get(lineInfo.getOffset(), lineInfo.getLength());
+        } catch (BadLocationException ex) {
+            return null;
+        }
+
+        int offsetInLine= offset - lineInfo.getOffset();
+
+        bool startDoubleQuote= false;
+        int urlOffsetInLine= 0;
+        int urlLength= 0;
+
+        int urlSeparatorOffset= line.indexOf("://"); //$NON-NLS-1$
+        while (urlSeparatorOffset >= 0) {
+
+            // URL protocol (left to "://")
+            urlOffsetInLine= urlSeparatorOffset;
+            char ch;
+            do {
+                urlOffsetInLine--;
+                ch= ' ';
+                if (urlOffsetInLine > -1)
+                    ch= line.charAt(urlOffsetInLine);
+                startDoubleQuote= ch is '"';
+            } while (Character.isUnicodeIdentifierStart(ch));
+            urlOffsetInLine++;
+
+            // Right to "://"
+            StringTokenizer tokenizer= new StringTokenizer(line.substring(urlSeparatorOffset + 3), " \t\n\r\f<>", false); //$NON-NLS-1$
+            if (!tokenizer.hasMoreTokens())
+                return null;
+
+            urlLength= tokenizer.nextToken().length() + 3 + urlSeparatorOffset - urlOffsetInLine;
+            if (offsetInLine >= urlOffsetInLine && offsetInLine <= urlOffsetInLine + urlLength)
+                break;
+
+            urlSeparatorOffset= line.indexOf("://", urlSeparatorOffset + 1); //$NON-NLS-1$
+        }
+
+        if (urlSeparatorOffset < 0)
+            return null;
+
+        if (startDoubleQuote) {
+            int endOffset= -1;
+            int nextDoubleQuote= line.indexOf('"', urlOffsetInLine);
+            int nextWhitespace= line.indexOf(' ', urlOffsetInLine);
+            if (nextDoubleQuote !is -1 && nextWhitespace !is -1)
+                endOffset= Math.min(nextDoubleQuote, nextWhitespace);
+            else if (nextDoubleQuote !is -1)
+                endOffset= nextDoubleQuote;
+            else if (nextWhitespace !is -1)
+                endOffset= nextWhitespace;
+            if (endOffset !is -1)
+                urlLength= endOffset - urlOffsetInLine;
+        }
+
+        // Set and validate URL string
+        try {
+            urlString= line.substring(urlOffsetInLine, urlOffsetInLine + urlLength);
+            new URL(urlString);
+        } catch (MalformedURLException ex) {
+            urlString= null;
+            return null;
+        }
+
+        IRegion urlRegion= new Region(lineInfo.getOffset() + urlOffsetInLine, urlLength);
+        return [new URLHyperlink(urlRegion, urlString)];
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/information/IInformationPresenter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.information.IInformationPresenter;
+
+import dwtx.jface.text.information.InformationPresenter; // packageimport
+import dwtx.jface.text.information.IInformationProvider; // packageimport
+import dwtx.jface.text.information.IInformationProviderExtension; // packageimport
+import dwtx.jface.text.information.IInformationPresenterExtension; // packageimport
+import dwtx.jface.text.information.IInformationProviderExtension2; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * An information presenter shows information available at the text viewer's
+ * current document position. An <code>IInformationPresenter</code> is a
+ * {@link dwtx.jface.text.ITextViewer} add-on.
+ * <p>
+ * An information presenters has a list of  {@link dwtx.jface.text.information.IInformationProvider} objects
+ * each of which is registered for a  particular document content type.
+ * The presenter uses the strategy objects to retrieve the information to present.
+ * </p>
+ * <p>
+ * In order to provide backward compatibility for clients of <code>IInformationPresenter</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link IInformationPresenterExtension} since version 3.0 introducing
+ *      the ability to handle documents with multiple partitions</li>
+ * </ul>
+ * </p>
+ * <p>
+ * The interface can be implemented by clients. By default, clients use
+ * {@link dwtx.jface.text.information.InformationPresenter} as the standard implementer of this interface.
+ * </p>
+ *
+ * @see dwtx.jface.text.information.IInformationPresenterExtension
+ * @see dwtx.jface.text.ITextViewer
+ * @see dwtx.jface.text.information.IInformationProvider
+ * @since 2.0
+ */
+public interface IInformationPresenter {
+
+    /**
+     * Installs the information presenter on the given text viewer. After this method has been
+     * finished, the presenter is operational, i.e. the method {@link #showInformation()}
+     * can be called until {@link #uninstall()} is called.
+     *
+     * @param textViewer the viewer on which the presenter is installed
+     */
+    void install(ITextViewer textViewer);
+
+    /**
+     * Removes the information presenter from the text viewer it has previously been
+     * installed on.
+     */
+    void uninstall();
+
+    /**
+     * Shows information related to the cursor position of the text viewer
+     * this information presenter is installed on.
+     */
+    void showInformation();
+
+    /**
+     * Returns the information provider to be used for the given content type.
+     *
+     * @param contentType the type of the content for which information will be requested
+     * @return an information provider or <code>null</code> if none exists for the specified content type
+     */
+    IInformationProvider getInformationProvider(String contentType);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/information/IInformationPresenterExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.information.IInformationPresenterExtension;
+
+import dwtx.jface.text.information.InformationPresenter; // packageimport
+import dwtx.jface.text.information.IInformationProvider; // packageimport
+import dwtx.jface.text.information.IInformationProviderExtension; // packageimport
+import dwtx.jface.text.information.IInformationProviderExtension2; // packageimport
+import dwtx.jface.text.information.IInformationPresenter; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extends {@link dwtx.jface.text.information.IInformationPresenter} with
+ * the ability to handle documents with multiple partitions.
+ *
+ * @see dwtx.jface.text.information.IInformationPresenter
+ * 
+ * @since 3.0
+ */
+public interface IInformationPresenterExtension {
+
+    /**
+     * Returns the document partitioning this information presenter is using.
+     *
+     * @return the document partitioning this information presenter is using
+     */
+    String getDocumentPartitioning();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/information/IInformationProvider.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.information.IInformationProvider;
+
+import dwtx.jface.text.information.InformationPresenter; // packageimport
+import dwtx.jface.text.information.IInformationProviderExtension; // packageimport
+import dwtx.jface.text.information.IInformationPresenterExtension; // packageimport
+import dwtx.jface.text.information.IInformationProviderExtension2; // packageimport
+import dwtx.jface.text.information.IInformationPresenter; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * Provides information related to the content of a text viewer.
+ * <p>
+ * In order to provide backward compatibility for clients of <code>IInformationProvider</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link IInformationProviderExtension} since version 2.1 introducing
+ *      the ability to provide the element for a given subject</li>
+ * <li>{@link IInformationProviderExtension2} since version 3.0 introducing
+ *      the ability to provide its own information control creator</li>
+ * </ul>
+ * </p>
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ *
+ * @see dwtx.jface.text.information.IInformationProviderExtension
+ * @see dwtx.jface.text.information.IInformationProviderExtension2
+ * @see dwtx.jface.text.information.IInformationPresenter
+ * @see dwtx.jface.text.ITextViewer
+ * @since 2.0
+ */
+public interface IInformationProvider {
+
+    /**
+     * Returns the region of the text viewer's document close to the given
+     * offset that contains a subject about which information can be provided.<p>
+     * For example, if information can be provided on a per code block basis,
+     * the offset should be used to find the enclosing code block and the source
+     * range of the block should be returned.
+     *
+     * @param textViewer the text viewer in which information has been requested
+     * @param offset the offset at which information has been requested
+     * @return the region of the text viewer's document containing the information subject
+     */
+    IRegion getSubject(ITextViewer textViewer, int offset);
+
+    /**
+     * Returns the information about the given subject or <code>null</code> if
+     * no information is available. It depends on the concrete configuration in which
+     * format the information is to be provided. For example, information presented
+     * in an information control displaying HTML, should be provided in HTML.
+     *
+     * @param textViewer the viewer in whose document the subject is contained
+     * @param subject the text region constituting the information subject
+     * @return the information about the subject
+     * @see IInformationPresenter
+     * @deprecated As of 2.1, replaced by {@link IInformationProviderExtension#getInformation2(ITextViewer, IRegion)}
+     */
+    String getInformation(ITextViewer textViewer, IRegion subject);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/information/IInformationProviderExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.information.IInformationProviderExtension;
+
+import dwtx.jface.text.information.InformationPresenter; // packageimport
+import dwtx.jface.text.information.IInformationProvider; // packageimport
+import dwtx.jface.text.information.IInformationPresenterExtension; // packageimport
+import dwtx.jface.text.information.IInformationProviderExtension2; // packageimport
+import dwtx.jface.text.information.IInformationPresenter; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * Extends {@link dwtx.jface.text.information.IInformationProvider} with
+ * the ability to provide the element for a given subject.
+ *
+ * @see dwtx.jface.text.information.IInformationProvider
+ * @since 2.1
+ */
+public interface IInformationProviderExtension {
+
+    /**
+     * Returns the element for the given subject or <code>null</code> if
+     * no element is available.
+     * <p>
+     * Implementers should ignore the text returned by {@link IInformationProvider#getInformation(ITextViewer, IRegion)}.
+     * </p>
+     *
+     * @param textViewer the viewer in whose document the subject is contained
+     * @param subject the text region constituting the information subject
+     * @return the element for the subject
+     *
+     * @see IInformationProvider#getInformation(ITextViewer, IRegion)
+     * @see dwtx.jface.text.ITextViewer
+     */
+    Object getInformation2(ITextViewer textViewer, IRegion subject);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/information/IInformationProviderExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.information.IInformationProviderExtension2;
+
+import dwtx.jface.text.information.InformationPresenter; // packageimport
+import dwtx.jface.text.information.IInformationProvider; // packageimport
+import dwtx.jface.text.information.IInformationProviderExtension; // packageimport
+import dwtx.jface.text.information.IInformationPresenterExtension; // packageimport
+import dwtx.jface.text.information.IInformationPresenter; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.IInformationControlCreator;
+
+/**
+ * Extends {@link dwtx.jface.text.information.IInformationProvider} with
+ * the ability to provide its own information presenter control creator.
+ *
+ * @see dwtx.jface.text.IInformationControlCreator
+ * @see dwtx.jface.text.information.IInformationProvider
+ * @since 3.0
+ */
+public interface IInformationProviderExtension2 {
+
+    /**
+     * Returns the information control creator of this information provider.
+     *
+     * @return the information control creator or <code>null</code> if none is available
+     */
+    IInformationControlCreator getInformationPresenterControlCreator();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/information/InformationPresenter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,504 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.information.InformationPresenter;
+
+import dwtx.jface.text.information.IInformationProvider; // packageimport
+import dwtx.jface.text.information.IInformationProviderExtension; // packageimport
+import dwtx.jface.text.information.IInformationPresenterExtension; // packageimport
+import dwtx.jface.text.information.IInformationProviderExtension2; // packageimport
+import dwtx.jface.text.information.IInformationPresenter; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwt.custom.StyledText;
+import dwt.events.ControlEvent;
+import dwt.events.ControlListener;
+import dwt.events.FocusEvent;
+import dwt.events.FocusListener;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.AbstractInformationControlManager;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocumentExtension3;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.IViewportListener;
+import dwtx.jface.text.IWidgetTokenKeeper;
+import dwtx.jface.text.IWidgetTokenKeeperExtension;
+import dwtx.jface.text.IWidgetTokenOwner;
+import dwtx.jface.text.IWidgetTokenOwnerExtension;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextUtilities;
+
+
+/**
+ * Standard implementation of <code>IInformationPresenter</code>.
+ * This implementation extends <code>AbstractInformationControlManager</code>.
+ * The information control is made visible on request by calling
+ * {@link #showInformationControl(Rectangle)}.
+ * <p>
+ * Usually, clients instantiate this class and configure it before using it. The configuration
+ * must be consistent: This means the used {@link dwtx.jface.text.IInformationControlCreator}
+ * must create an information control expecting information in the same format the configured
+ * {@link dwtx.jface.text.information.IInformationProvider}s  use to encode the information they provide.
+ * </p>
+ *
+ * @since 2.0
+ */
+public class InformationPresenter : AbstractInformationControlManager , IInformationPresenter, IInformationPresenterExtension, IWidgetTokenKeeper, IWidgetTokenKeeperExtension {
+
+    alias AbstractInformationControlManager.install install;
+    public override void showInformation(){
+        super.showInformation();
+    }
+
+    /**
+     * Priority of the info controls managed by this information presenter.
+     * Default value: <code>5</code>.
+     *
+     * @since 3.0
+     */
+    /*
+     * 5 as value has been chosen in order to beat the hovers of {@link dwtx.jface.text.TextViewerHoverManager}
+     */
+    public static const int WIDGET_PRIORITY= 5;
+
+
+    /**
+     * Internal information control closer. Listens to several events issued by its subject control
+     * and closes the information control when necessary.
+     */
+    class Closer : IInformationControlCloser, ControlListener, MouseListener, FocusListener, IViewportListener, KeyListener {
+
+        /** The subject control. */
+        private Control fSubjectControl;
+        /** The information control. */
+        private IInformationControl fInformationControlToClose;
+        /** Indicates whether this closer is active. */
+        private bool fIsActive= false;
+
+        /*
+         * @see IInformationControlCloser#setSubjectControl(Control)
+         */
+        public void setSubjectControl(Control control) {
+            fSubjectControl= control;
+        }
+
+        /*
+         * @see IInformationControlCloser#setInformationControl(IInformationControl)
+         */
+        public void setInformationControl(IInformationControl control) {
+            fInformationControlToClose= control;
+        }
+
+        /*
+         * @see IInformationControlCloser#start(Rectangle)
+         */
+        public void start(Rectangle informationArea) {
+
+            if (fIsActive)
+                return;
+            fIsActive= true;
+
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
+                fSubjectControl.addControlListener(this);
+                fSubjectControl.addMouseListener(this);
+                fSubjectControl.addFocusListener(this);
+                fSubjectControl.addKeyListener(this);
+            }
+
+            if (fInformationControlToClose !is null)
+                fInformationControlToClose.addFocusListener(this);
+
+            fTextViewer.addViewportListener(this);
+        }
+
+        /*
+         * @see IInformationControlCloser#stop()
+         */
+        public void stop() {
+
+            if (!fIsActive)
+                return;
+            fIsActive= false;
+
+            fTextViewer.removeViewportListener(this);
+
+            if (fInformationControlToClose !is null)
+                fInformationControlToClose.removeFocusListener(this);
+
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
+                fSubjectControl.removeControlListener(this);
+                fSubjectControl.removeMouseListener(this);
+                fSubjectControl.removeFocusListener(this);
+                fSubjectControl.removeKeyListener(this);
+            }
+        }
+
+        /*
+         * @see ControlListener#controlResized(ControlEvent)
+         */
+         public void controlResized(ControlEvent e) {
+             hideInformationControl();
+        }
+
+        /*
+         * @see ControlListener#controlMoved(ControlEvent)
+         */
+         public void controlMoved(ControlEvent e) {
+             hideInformationControl();
+        }
+
+        /*
+         * @see MouseListener#mouseDown(MouseEvent)
+         */
+         public void mouseDown(MouseEvent e) {
+             hideInformationControl();
+        }
+
+        /*
+         * @see MouseListener#mouseUp(MouseEvent)
+         */
+        public void mouseUp(MouseEvent e) {
+        }
+
+        /*
+         * @see MouseListener#mouseDoubleClick(MouseEvent)
+         */
+        public void mouseDoubleClick(MouseEvent e) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see FocusListener#focusGained(FocusEvent)
+         */
+        public void focusGained(FocusEvent e) {
+        }
+
+        /*
+         * @see FocusListener#focusLost(FocusEvent)
+         */
+         public void focusLost(FocusEvent e) {
+            Display d= fSubjectControl.getDisplay();
+            d.asyncExec(new class()  Runnable {
+                // Without the asyncExec, mouse clicks to the workbench window are swallowed.
+                public void run() {
+                    if (fInformationControlToClose is null || !fInformationControlToClose.isFocusControl())
+                        hideInformationControl();
+                }
+            });
+        }
+
+        /*
+         * @see IViewportListenerListener#viewportChanged(int)
+         */
+        public void viewportChanged(int topIndex) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see KeyListener#keyPressed(KeyEvent)
+         */
+        public void keyPressed(KeyEvent e) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see KeyListener#keyReleased(KeyEvent)
+         */
+        public void keyReleased(KeyEvent e) {
+        }
+    }
+
+
+    /** The text viewer this information presenter works on */
+    private ITextViewer fTextViewer;
+    /** The map of <code>IInformationProvider</code> objects */
+    private Map fProviders;
+    /** The offset to override selection. */
+    private int fOffset= -1;
+    /**
+     * The document partitioning for this information presenter.
+     * @since 3.0
+     */
+    private String fPartitioning;
+
+    /**
+     * Creates a new information presenter that uses the given information control creator.
+     * The presenter is not installed on any text viewer yet. By default, an information
+     * control closer is set that closes the information control in the event of key strokes,
+     * resizing, moves, focus changes, mouse clicks, and disposal - all of those applied to
+     * the information control's parent control. Also, the setup ensures that the information
+     * control when made visible will request the focus. By default, the default document
+     * partitioning {@link IDocumentExtension3#DEFAULT_PARTITIONING} is used.
+     *
+     * @param creator the information control creator to be used
+     */
+    public this(IInformationControlCreator creator) {
+        super(creator);
+        setCloser(new Closer());
+        takesFocusWhenVisible(true);
+        fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING;
+    }
+
+    /**
+     * Sets the document partitioning to be used by this information presenter.
+     *
+     * @param partitioning the document partitioning to be used by this information presenter
+     * @since 3.0
+     */
+    public void setDocumentPartitioning(String partitioning) {
+        Assert.isNotNull(partitioning);
+        fPartitioning= partitioning;
+    }
+
+    /*
+     * @see dwtx.jface.text.information.IInformationPresenterExtension#getDocumentPartitioning()
+     * @since 3.0
+     */
+    public String getDocumentPartitioning() {
+        return fPartitioning;
+    }
+
+    /**
+     * Registers a given information provider for a particular content type.
+     * If there is already a provider registered for this type, the new provider
+     * is registered instead of the old one.
+     *
+     * @param provider the information provider to register, or <code>null</code> to remove an existing one
+     * @param contentType the content type under which to register
+     */
+     public void setInformationProvider(IInformationProvider provider, String contentType) {
+
+        Assert.isNotNull(contentType);
+
+        if (fProviders is null)
+            fProviders= new HashMap();
+
+        if (provider is null)
+            fProviders.remove(contentType);
+        else
+            fProviders.put(contentType, cast(Object)provider);
+    }
+
+    /*
+     * @see IInformationPresenter#getInformationProvider(String)
+     */
+    public IInformationProvider getInformationProvider(String contentType) {
+        if (fProviders is null)
+            return null;
+
+        return cast(IInformationProvider) fProviders.get(contentType);
+    }
+
+    /**
+     * Sets a offset to override the selection. Setting the value to <code>-1</code> will disable
+     * overriding.
+     *
+     * @param offset the offset to override selection or <code>-1</code>
+     */
+    public void setOffset(int offset) {
+        fOffset= offset;
+    }
+
+    /*
+     * @see AbstractInformationControlManager#computeInformation()
+     */
+    protected void computeInformation() {
+
+        int offset= fOffset < 0 ? fTextViewer.getSelectedRange().x : fOffset;
+        if (offset is -1)
+            return;
+
+        fOffset= -1;
+
+        IInformationProvider provider= null;
+        try {
+            String contentType= TextUtilities.getContentType(fTextViewer.getDocument(), getDocumentPartitioning(), offset, true);
+            provider= getInformationProvider(contentType);
+        } catch (BadLocationException x) {
+        }
+        if (provider is null)
+            return;
+
+        IRegion subject= provider.getSubject(fTextViewer, offset);
+        if (subject is null)
+            return;
+
+        Object info;
+        if ( cast(IInformationProviderExtension)provider ) {
+            IInformationProviderExtension extension= cast(IInformationProviderExtension) provider;
+            info= extension.getInformation2(fTextViewer, subject);
+        } else {
+            // backward compatibility code
+            info= stringcast(provider.getInformation(fTextViewer, subject));
+        }
+
+        if ( cast(IInformationProviderExtension2)provider )
+            setCustomInformationControlCreator((cast(IInformationProviderExtension2) provider).getInformationPresenterControlCreator());
+        else
+            setCustomInformationControlCreator(null);
+
+        setInformation(info, computeArea(subject));
+    }
+
+    /**
+     * Determines the graphical area covered by the given text region.
+     *
+     * @param region the region whose graphical extend must be computed
+     * @return the graphical extend of the given region
+     */
+    private Rectangle computeArea(IRegion region) {
+
+        int start= 0;
+        int end= 0;
+
+        IRegion widgetRegion= modelRange2WidgetRange(region);
+        if (widgetRegion !is null) {
+            start= widgetRegion.getOffset();
+            end= widgetRegion.getOffset() + widgetRegion.getLength();
+        }
+
+        StyledText styledText= fTextViewer.getTextWidget();
+        Rectangle bounds;
+        if (end > 0 && start < end)
+            bounds= styledText.getTextBounds(start, end - 1);
+        else {
+            Point loc= styledText.getLocationAtOffset(start);
+            bounds= new Rectangle(loc.x, loc.y, 0, styledText.getLineHeight(start));
+        }
+
+        return bounds;
+    }
+
+    /**
+     * Translated the given range in the viewer's document into the corresponding
+     * range of the viewer's widget.
+     *
+     * @param region the range in the viewer's document
+     * @return the corresponding widget range
+     * @since 2.1
+     */
+    private IRegion modelRange2WidgetRange(IRegion region) {
+        if ( cast(ITextViewerExtension5)fTextViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer;
+            return extension.modelRange2WidgetRange(region);
+        }
+
+        IRegion visibleRegion= fTextViewer.getVisibleRegion();
+        int start= region.getOffset() - visibleRegion.getOffset();
+        int end= start + region.getLength();
+        if (end > visibleRegion.getLength())
+            end= visibleRegion.getLength();
+
+        return new Region(start, end - start);
+    }
+
+    /*
+     * @see IInformationPresenter#install(ITextViewer)
+     */
+    public void install(ITextViewer textViewer) {
+        fTextViewer= textViewer;
+        install(fTextViewer.getTextWidget());
+    }
+
+    /*
+     * @see IInformationPresenter#uninstall()
+     */
+    public void uninstall() {
+        dispose();
+    }
+
+    /*
+     * @see AbstractInformationControlManager#showInformationControl(Rectangle)
+     */
+    protected void showInformationControl(Rectangle subjectArea) {
+        if ( cast(IWidgetTokenOwnerExtension)fTextViewer  && cast(IWidgetTokenOwner)fTextViewer ) {
+            IWidgetTokenOwnerExtension extension= cast(IWidgetTokenOwnerExtension) fTextViewer;
+            if (extension.requestWidgetToken(this, WIDGET_PRIORITY))
+                super.showInformationControl(subjectArea);
+        } else if ( cast(IWidgetTokenOwner)fTextViewer ) {
+            IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fTextViewer;
+            if (owner.requestWidgetToken(this))
+                super.showInformationControl(subjectArea);
+
+        } else
+            super.showInformationControl(subjectArea);
+    }
+
+    /*
+     * @see AbstractInformationControlManager#hideInformationControl()
+     */
+    protected void hideInformationControl() {
+        try {
+            super.hideInformationControl();
+        } finally {
+            if ( cast(IWidgetTokenOwner)fTextViewer ) {
+                IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fTextViewer;
+                owner.releaseWidgetToken(this);
+            }
+        }
+    }
+
+    /*
+     * @see AbstractInformationControlManager#handleInformationControlDisposed()
+     */
+    protected void handleInformationControlDisposed() {
+        try {
+            super.handleInformationControlDisposed();
+        } finally {
+            if ( cast(IWidgetTokenOwner)fTextViewer ) {
+                IWidgetTokenOwner owner= cast(IWidgetTokenOwner) fTextViewer;
+                owner.releaseWidgetToken(this);
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeper#requestWidgetToken(IWidgetTokenOwner)
+     */
+    public bool requestWidgetToken(IWidgetTokenOwner owner) {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeperExtension#requestWidgetToken(dwtx.jface.text.IWidgetTokenOwner, int)
+     * @since 3.0
+     */
+    public bool requestWidgetToken(IWidgetTokenOwner owner, int priority) {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IWidgetTokenKeeperExtension#setFocus(dwtx.jface.text.IWidgetTokenOwner)
+     * @since 3.0
+     */
+    public bool setFocus(IWidgetTokenOwner owner) {
+        return false;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/link/ILinkedModeListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.link.ILinkedModeListener;
+
+import dwtx.jface.text.link.LinkedModeModel; // packageimport
+import dwtx.jface.text.link.LinkedPosition; // packageimport
+import dwtx.jface.text.link.TabStopIterator; // packageimport
+import dwtx.jface.text.link.LinkedModeUI; // packageimport
+import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.link.LinkedPositionGroup; // packageimport
+import dwtx.jface.text.link.LinkedModeManager; // packageimport
+import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport
+import dwtx.jface.text.link.ProposalPosition; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Protocol used by {@link LinkedModeModel}s to communicate state changes, such
+ * as leaving linked mode, suspending it due to a child mode coming up, and
+ * resuming after a child mode has left.
+ * <p>
+ * This interface may implemented by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public interface ILinkedModeListener {
+
+    /** Flag to <code>leave</code> specifying no special action. */
+    static const int NONE= 0;
+    /**
+     * Flag to <code>leave</code> specifying that all nested modes should
+     * exit.
+     */
+    static const int EXIT_ALL= 1 << 0;
+    /**
+     * Flag to <code>leave</code> specifying that the caret should be moved to
+     * the exit position.
+     */
+    static const int UPDATE_CARET= 1 << 1;
+    /**
+     * Flag to <code>leave</code> specifying that a UI of a parent mode should
+     * select the current position.
+     */
+    static const int SELECT= 1 << 2;
+    /**
+     * Flag to <code>leave</code> specifying that document content outside of
+     * a linked position was modified.
+     */
+    static const int EXTERNAL_MODIFICATION= 1 << 3;
+
+    /**
+     * The leave event occurs when linked is left.
+     *
+     * @param model the model being left
+     * @param flags the reason and commands for leaving linked mode
+     */
+    void left(LinkedModeModel model, int flags);
+
+    /**
+     * The suspend event occurs when a nested linked mode is installed within
+     * <code>model</code>.
+     *
+     * @param model the model being suspended due to a nested model being
+     *        installed
+     */
+    void suspend(LinkedModeModel model);
+
+    /**
+     * The resume event occurs when a nested linked mode exits.
+     *
+     * @param model the linked mode model being resumed due to a nested mode
+     *        exiting
+     * @param flags the commands to execute when resuming after suspend
+     */
+    void resume(LinkedModeModel model, int flags);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/link/InclusivePositionUpdater.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.link.InclusivePositionUpdater;
+
+import dwtx.jface.text.link.LinkedModeModel; // packageimport
+import dwtx.jface.text.link.LinkedPosition; // packageimport
+import dwtx.jface.text.link.ILinkedModeListener; // packageimport
+import dwtx.jface.text.link.TabStopIterator; // packageimport
+import dwtx.jface.text.link.LinkedModeUI; // packageimport
+import dwtx.jface.text.link.LinkedPositionGroup; // packageimport
+import dwtx.jface.text.link.LinkedModeManager; // packageimport
+import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport
+import dwtx.jface.text.link.ProposalPosition; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IPositionUpdater;
+import dwtx.jface.text.Position;
+
+
+/**
+ * Position updater that considers any change in
+ * <code>[p.offset,&nbsp;p.offset&nbsp;+&nbsp;p.length]</code> of a {@link Position}
+ * <code>p</code> as belonging to the position.
+ * <p>
+ * Internal class. Do not use. Public for testing purposes only.
+ * </p>
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class InclusivePositionUpdater : IPositionUpdater {
+
+    /** The position category. */
+    private const String fCategory;
+
+    /**
+     * Creates a new updater for the given <code>category</code>.
+     *
+     * @param category the new category.
+     */
+    public this(String category) {
+        fCategory= category;
+    }
+
+    /*
+     * @see dwtx.jface.text.IPositionUpdater#update(dwtx.jface.text.DocumentEvent)
+     */
+    public void update(DocumentEvent event) {
+
+        int eventOffset= event.getOffset();
+        int eventOldLength= event.getLength();
+        int eventNewLength= event.getText() is null ? 0 : event.getText().length();
+        int deltaLength= eventNewLength - eventOldLength;
+
+        try {
+            Position[] positions= event.getDocument().getPositions(fCategory);
+
+            for (int i= 0; i !is positions.length; i++) {
+
+                Position position= positions[i];
+
+                if (position.isDeleted())
+                    continue;
+
+                int offset= position.getOffset();
+                int length= position.getLength();
+                int end= offset + length;
+
+                if (offset > eventOffset + eventOldLength)
+                    // position comes way
+                    // after change - shift
+                    position.setOffset(offset + deltaLength);
+                else if (end < eventOffset) {
+                    // position comes way before change -
+                    // leave alone
+                } else if (offset <= eventOffset && end >= eventOffset + eventOldLength) {
+                    // event completely internal to the position - adjust length
+                    position.setLength(length + deltaLength);
+                } else if (offset < eventOffset) {
+                    // event extends over end of position - adjust length
+                    int newEnd= eventOffset + eventNewLength;
+                    position.setLength(newEnd - offset);
+                } else if (end > eventOffset + eventOldLength) {
+                    // event extends from before position into it - adjust offset
+                    // and length
+                    // offset becomes end of event, length adjusted accordingly
+                    // we want to recycle the overlapping part
+                    position.setOffset(eventOffset);
+                    int deleted= eventOffset + eventOldLength - offset;
+                    position.setLength(length - deleted + eventNewLength);
+                } else {
+                    // event consumes the position - delete it
+                    position.delete_();
+                }
+            }
+        } catch (BadPositionCategoryException e) {
+            // ignore and return
+        }
+    }
+
+    /**
+     * Returns the position category.
+     *
+     * @return the position category
+     */
+    public String getCategory() {
+        return fCategory;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/link/LinkedModeManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,262 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.link.LinkedModeManager;
+
+import dwtx.jface.text.link.LinkedModeModel; // packageimport
+import dwtx.jface.text.link.LinkedPosition; // packageimport
+import dwtx.jface.text.link.ILinkedModeListener; // packageimport
+import dwtx.jface.text.link.TabStopIterator; // packageimport
+import dwtx.jface.text.link.LinkedModeUI; // packageimport
+import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.link.LinkedPositionGroup; // packageimport
+import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport
+import dwtx.jface.text.link.ProposalPosition; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.IDocument;
+
+
+/**
+ * A linked mode manager ensures exclusive access of linked position infrastructures to documents. There
+ * is at most one <code>LinkedModeManager</code> installed on the same document. The <code>getManager</code>
+ * methods will return the existing instance if any of the specified documents already have an installed
+ * manager.
+ *
+ * @since 3.0
+ */
+class LinkedModeManager {
+
+    /**
+     * Our implementation of <code>ILinkedModeListener</code>.
+     */
+    private class Listener : ILinkedModeListener {
+
+        /*
+         * @see dwtx.jdt.internal.ui.text.link2.LinkedModeModel.ILinkedModeListener#left(dwtx.jdt.internal.ui.text.link2.LinkedModeModel, int)
+         */
+        public void left(LinkedModeModel model, int flags) {
+            this.outer.left(model, flags);
+        }
+
+        /*
+         * @see dwtx.jdt.internal.ui.text.link2.LinkedModeModel.ILinkedModeListener#suspend(dwtx.jdt.internal.ui.text.link2.LinkedModeModel)
+         */
+        public void suspend(LinkedModeModel model) {
+            // not interested
+        }
+
+        /*
+         * @see dwtx.jdt.internal.ui.text.link2.LinkedModeModel.ILinkedModeListener#resume(dwtx.jdt.internal.ui.text.link2.LinkedModeModel, int)
+         */
+        public void resume(LinkedModeModel model, int flags) {
+            // not interested
+        }
+
+    }
+
+    /** Global map from documents to managers. */
+    private static Map fgManagers_;
+    private static Map fgManagers(){
+        if( fgManagers_ is null ){
+            synchronized( LinkedModeManager.classinfo ){
+                if( fgManagers_ is null ){
+                    fgManagers_= new HashMap();
+                }
+            }
+        }
+        return fgManagers_;
+    }
+    /**
+     * Returns whether there exists a <code>LinkedModeManager</code> on <code>document</code>.
+     *
+     * @param document the document of interest
+     * @return <code>true</code> if there exists a <code>LinkedModeManager</code> on <code>document</code>, <code>false</code> otherwise
+     */
+    public static bool hasManager(IDocument document) {
+        return fgManagers.get(cast(Object)document) !is null;
+    }
+
+    /**
+     * Returns whether there exists a <code>LinkedModeManager</code> on any of the <code>documents</code>.
+     *
+     * @param documents the documents of interest
+     * @return <code>true</code> if there exists a <code>LinkedModeManager</code> on any of the <code>documents</code>, <code>false</code> otherwise
+     */
+    public static bool hasManager(IDocument[] documents) {
+        for (int i= 0; i < documents.length; i++) {
+            if (hasManager(documents[i]))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the manager for the given documents. If <code>force</code> is
+     * <code>true</code>, any existing conflicting managers are canceled, otherwise,
+     * the method may return <code>null</code> if there are conflicts.
+     *
+     * @param documents the documents of interest
+     * @param force whether to kill any conflicting managers
+     * @return a manager able to cover the requested documents, or <code>null</code> if there is a conflict and <code>force</code> was set to <code>false</code>
+     */
+    public static LinkedModeManager getLinkedManager(IDocument[] documents, bool force) {
+        if (documents is null || documents.length is 0)
+            return null;
+
+        Set mgrs= new HashSet();
+        LinkedModeManager mgr= null;
+        for (int i= 0; i < documents.length; i++) {
+            mgr= cast(LinkedModeManager) fgManagers.get(cast(Object)documents[i]);
+            if (mgr !is null)
+                mgrs.add(mgr);
+        }
+        if (mgrs.size() > 1)
+            if (force) {
+                for (Iterator it= mgrs.iterator(); it.hasNext(); ) {
+                    LinkedModeManager m= cast(LinkedModeManager) it.next();
+                    m.closeAllEnvironments();
+                }
+            } else {
+                return null;
+            }
+
+        if (mgrs.size() is 0)
+            mgr= new LinkedModeManager();
+
+        for (int i= 0; i < documents.length; i++)
+            fgManagers.put(cast(Object)documents[i], mgr);
+
+        return mgr;
+    }
+
+    /**
+     * Cancels any linked mode manager for the specified document.
+     *
+     * @param document the document whose <code>LinkedModeManager</code> should be canceled
+     */
+    public static void cancelManager(IDocument document) {
+        LinkedModeManager mgr= cast(LinkedModeManager) fgManagers.get(cast(Object)document);
+        if (mgr !is null)
+            mgr.closeAllEnvironments();
+    }
+
+    /** The hierarchy of environments managed by this manager. */
+    private Stack fEnvironments;
+    private Listener fListener;
+
+    this(){
+        fEnvironments= new Stack();
+        fListener= new Listener();
+    }
+
+    /**
+     * Notify the manager about a leaving model.
+     *
+     * @param model
+     * @param flags
+     */
+    private void left(LinkedModeModel model, int flags) {
+        if (!fEnvironments.contains(model))
+            return;
+
+        while (!fEnvironments.isEmpty()) {
+            LinkedModeModel env= cast(LinkedModeModel) fEnvironments.pop();
+            if (env is model)
+                break;
+            env.exit(ILinkedModeListener.NONE);
+        }
+
+        if (fEnvironments.isEmpty()) {
+            removeManager();
+        }
+    }
+
+    private void closeAllEnvironments() {
+        while (!fEnvironments.isEmpty()) {
+            LinkedModeModel env= cast(LinkedModeModel) fEnvironments.pop();
+            env.exit(ILinkedModeListener.NONE);
+        }
+
+        removeManager();
+    }
+
+    private void removeManager() {
+        for (Iterator it= fgManagers.keySet().iterator(); it.hasNext();) {
+            IDocument doc= cast(IDocument) it.next();
+            if (fgManagers.get(cast(Object)doc) is this)
+                it.remove();
+        }
+    }
+
+    /**
+     * Tries to nest the given <code>LinkedModeModel</code> onto the top of
+     * the stack of environments managed by the receiver. If <code>force</code>
+     * is <code>true</code>, any environments on the stack that create a conflict
+     * are killed.
+     *
+     * @param model the model to nest
+     * @param force whether to force the addition of the model
+     * @return <code>true</code> if nesting was successful, <code>false</code> otherwise (only possible if <code>force</code> is <code>false</code>
+     */
+    public bool nestEnvironment(LinkedModeModel model, bool force) {
+        Assert.isNotNull(model);
+
+        try {
+            while (true) {
+                if (fEnvironments.isEmpty()) {
+                    model.addLinkingListener(fListener);
+                    fEnvironments.push(model);
+                    return true;
+                }
+
+                LinkedModeModel top= cast(LinkedModeModel) fEnvironments.peek();
+                if (model.canNestInto(top)) {
+                    model.addLinkingListener(fListener);
+                    fEnvironments.push(model);
+                    return true;
+                } else if (!force) {
+                    return false;
+                } else { // force
+                    fEnvironments.pop();
+                    top.exit(ILinkedModeListener.NONE);
+                    // continue;
+                }
+            }
+        } finally {
+            // if we remove any, make sure the new one got inserted
+            Assert.isTrue(fEnvironments.size() > 0);
+        }
+    }
+
+    /**
+     * Returns the <code>LinkedModeModel</code> that is on top of the stack of
+     * environments managed by the receiver.
+     *
+     * @return the topmost <code>LinkedModeModel</code>
+     */
+    public LinkedModeModel getTopEnvironment() {
+        if (fEnvironments.isEmpty())
+            return null;
+        return cast(LinkedModeModel) fEnvironments.peek();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/link/LinkedModeModel.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,791 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.link.LinkedModeModel;
+
+import dwtx.jface.text.link.LinkedPosition; // packageimport
+import dwtx.jface.text.link.ILinkedModeListener; // packageimport
+import dwtx.jface.text.link.TabStopIterator; // packageimport
+import dwtx.jface.text.link.LinkedModeUI; // packageimport
+import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.link.LinkedPositionGroup; // packageimport
+import dwtx.jface.text.link.LinkedModeManager; // packageimport
+import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport
+import dwtx.jface.text.link.ProposalPosition; // packageimport
+
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentExtension;
+import dwtx.jface.text.IDocumentListener;
+import dwtx.jface.text.IPositionUpdater;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.IDocumentExtension;
+import dwtx.text.edits.MalformedTreeException;
+import dwtx.text.edits.TextEdit;
+
+
+/**
+ * The model for linked mode, umbrellas several
+ * {@link LinkedPositionGroup}s. Once installed, the model
+ * propagates any changes to a position to all its siblings in the same position
+ * group.
+ * <p>
+ * Setting up a model consists of first adding
+ * <code>LinkedPositionGroup</code>s to it, and then installing the
+ * model by either calling {@link #forceInstall()} or
+ * {@link #tryInstall()}. After installing the model, it becomes
+ * <em>sealed</em> and no more groups may be added.
+ * </p>
+ * <p>
+ * If a document change occurs that would modify more than one position
+ * group or that would invalidate the disjointness requirement of the positions,
+ * the model is torn down and all positions are deleted. The same happens
+ * upon calling {@link #exit(int)}.
+ * </p>
+ * <h4>Nesting</h4>
+ * <p>
+ * A <code>LinkedModeModel</code> may be nested into another model. This
+ * happens when installing a model the positions of which all fit into a
+ * single position in a parent model that has previously been installed on
+ * the same document(s).
+ * </p>
+ * <p>
+ * Clients may instantiate instances of this class.
+ * </p>
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class LinkedModeModel {
+
+    /**
+     * Checks whether there is already a model installed on <code>document</code>.
+     *
+     * @param document the <code>IDocument</code> of interest
+     * @return <code>true</code> if there is an existing model, <code>false</code>
+     *         otherwise
+     */
+    public static bool hasInstalledModel(IDocument document) {
+        // if there is a manager, there also is a model
+        return LinkedModeManager.hasManager(document);
+    }
+
+    /**
+     * Checks whether there is already a linked mode model installed on any of
+     * the <code>documents</code>.
+     *
+     * @param documents the <code>IDocument</code>s of interest
+     * @return <code>true</code> if there is an existing model, <code>false</code>
+     *         otherwise
+     */
+    public static bool hasInstalledModel(IDocument[] documents) {
+        // if there is a manager, there also is a model
+        return LinkedModeManager.hasManager(documents);
+    }
+
+    /**
+     * Cancels any linked mode model on the specified document. If there is no
+     * model, nothing happens.
+     *
+     * @param document the document whose <code>LinkedModeModel</code> should
+     *        be canceled
+     */
+    public static void closeAllModels(IDocument document) {
+        LinkedModeManager.cancelManager(document);
+    }
+
+    /**
+     * Returns the model currently active on <code>document</code> at
+     * <code>offset</code>, or <code>null</code> if there is none.
+     *
+     * @param document the document for which the caller asks for a
+     *        model
+     * @param offset the offset into <code>document</code>, as there may be
+     *        several models on a document
+     * @return the model currently active on <code>document</code>, or
+     *         <code>null</code>
+     */
+    public static LinkedModeModel getModel(IDocument document, int offset) {
+        if (!hasInstalledModel(document))
+            return null;
+
+        LinkedModeManager mgr= LinkedModeManager.getLinkedManager([document], false);
+        if (mgr !is null)
+            return mgr.getTopEnvironment();
+        return null;
+    }
+
+    /**
+     * Encapsulates the edition triggered by a change to a linking position. Can
+     * be applied to a document as a whole.
+     */
+    private class Replace : IDocumentExtension.IReplace {
+
+        /** The edition to apply on a document. */
+        private TextEdit fEdit;
+
+        /**
+         * Creates a new instance.
+         *
+         * @param edit the edition to apply to a document.
+         */
+        public this(TextEdit edit) {
+            fEdit= edit;
+        }
+
+        /*
+         * @see dwtx.jface.text.IDocumentExtension.IReplace#perform(dwtx.jface.text.IDocument, dwtx.jface.text.IDocumentListener)
+         */
+        public void perform(IDocument document, IDocumentListener owner)  {
+            document.removeDocumentListener(owner);
+            fIsChanging= true;
+            try {
+                fEdit.apply(document, TextEdit.UPDATE_REGIONS | TextEdit.CREATE_UNDO);
+            } catch (BadLocationException e) {
+                /* XXX: perform should really throw a BadLocationException
+                 *      see https://bugs.eclipse.org/bugs/show_bug.cgi?id=52950
+                 */
+                throw new RuntimeException(e);
+            } finally {
+                document.addDocumentListener(owner);
+                fIsChanging= false;
+            }
+        }
+
+    }
+
+    /**
+     * The document listener triggering the linked updating of positions
+     * managed by this model.
+     */
+    private class DocumentListener : IDocumentListener {
+
+        private bool fExit= false;
+
+        /**
+         * Checks whether <code>event</code> occurs within any of the positions
+         * managed by this model. If not, the linked mode is left.
+         *
+         * @param event {@inheritDoc}
+         */
+        public void documentAboutToBeChanged(DocumentEvent event) {
+            // don't react on changes executed by the parent model
+            if (fParentEnvironment !is null && fParentEnvironment.isChanging())
+                return;
+
+            for (Iterator it= fGroups.iterator(); it.hasNext(); ) {
+                LinkedPositionGroup group= cast(LinkedPositionGroup) it.next();
+                if (!group.isLegalEvent(event)) {
+                    fExit= true;
+                    return;
+                }
+            }
+        }
+
+        /**
+         * Propagates a change to a linked position to all its sibling positions.
+         *
+         * @param event {@inheritDoc}
+         */
+        public void documentChanged(DocumentEvent event) {
+            if (fExit) {
+                this.outer.exit(ILinkedModeListener.EXTERNAL_MODIFICATION);
+                return;
+            }
+            fExit= false;
+
+            // don't react on changes executed by the parent model
+            if (fParentEnvironment !is null && fParentEnvironment.isChanging())
+                return;
+
+            // collect all results
+            Map result= null;
+            for (Iterator it= fGroups.iterator(); it.hasNext();) {
+                LinkedPositionGroup group= cast(LinkedPositionGroup) it.next();
+
+                Map map= group.handleEvent(event);
+                if (result !is null && map !is null) {
+                    // exit if more than one position was changed
+                    this.outer.exit(ILinkedModeListener.EXTERNAL_MODIFICATION);
+                    return;
+                }
+                if (map !is null)
+                    result= map;
+            }
+
+            if (result !is null) {
+                // edit all documents
+                for (Iterator it2= result.keySet().iterator(); it2.hasNext(); ) {
+                    IDocument doc= cast(IDocument) it2.next();
+                    TextEdit edit= cast(TextEdit) result.get(cast(Object)doc);
+                    Replace replace= new Replace(edit);
+
+                    // apply the edition, either as post notification replace
+                    // on the calling document or directly on any other
+                    // document
+                    if (doc is event.getDocument()) {
+                        if ( cast(IDocumentExtension)doc ) {
+                            (cast(IDocumentExtension) doc).registerPostNotificationReplace(this, replace);
+                        } else {
+                            // ignore - there is no way we can log from JFace text...
+                        }
+                    } else {
+                        replace.perform(doc, this);
+                    }
+                }
+            }
+        }
+
+    }
+
+    /** The set of linked position groups. */
+    private const List fGroups;
+    /** The set of documents spanned by this group. */
+    private const Set fDocuments;
+    /** The position updater for linked positions. */
+    private const IPositionUpdater fUpdater;
+    /** The document listener on the documents affected by this model. */
+    private const DocumentListener fDocumentListener;
+    /** The parent model for a hierarchical set up, or <code>null</code>. */
+    private LinkedModeModel fParentEnvironment;
+    /**
+     * The position in <code>fParentEnvironment</code> that includes all
+     * positions in this object, or <code>null</code> if there is no parent
+     * model.
+     */
+    private LinkedPosition fParentPosition= null;
+    /**
+     * A model is sealed once it has children - no more positions can be
+     * added.
+     */
+    private bool fIsSealed= false;
+    /** <code>true</code> when this model is changing documents. */
+    private bool fIsChanging= false;
+    /** The linked listeners. */
+    private const List fListeners;
+    /** Flag telling whether we have exited: */
+    private bool fIsActive= true;
+    /**
+     * The sequence of document positions as we are going to iterate through
+     * them.
+     */
+    private List fPositionSequence;
+
+    /**
+     * Whether we are in the process of editing documents (set by <code>Replace</code>,
+     * read by <code>DocumentListener</code>.
+     *
+     * @return <code>true</code> if we are in the process of editing a
+     *         document, <code>false</code> otherwise
+     */
+    private bool isChanging() {
+        return fIsChanging || fParentEnvironment !is null && fParentEnvironment.isChanging();
+    }
+
+    /**
+     * Throws a <code>BadLocationException</code> if <code>group</code>
+     * conflicts with this model's groups.
+     *
+     * @param group the group being checked
+     * @throws BadLocationException if <code>group</code> conflicts with this
+     *         model's groups
+     */
+    private void enforceDisjoint(LinkedPositionGroup group)  {
+        for (Iterator it= fGroups.iterator(); it.hasNext(); ) {
+            LinkedPositionGroup g= cast(LinkedPositionGroup) it.next();
+            g.enforceDisjoint(group);
+        }
+    }
+
+    /**
+     * Causes this model to exit. Called either if an illegal document change
+     * is detected, or by the UI.
+     *
+     * @param flags the exit flags as defined in {@link ILinkedModeListener}
+     */
+    public void exit(int flags) {
+        if (!fIsActive)
+            return;
+
+        fIsActive= false;
+
+        for (Iterator it= fDocuments.iterator(); it.hasNext(); ) {
+            IDocument doc= cast(IDocument) it.next();
+            try {
+                doc.removePositionCategory(getCategory());
+            } catch (BadPositionCategoryException e) {
+                // won't happen
+                Assert.isTrue(false);
+            }
+            doc.removePositionUpdater(fUpdater);
+            doc.removeDocumentListener(fDocumentListener);
+        }
+
+        fDocuments.clear();
+        fGroups.clear();
+
+        List listeners= new ArrayList(fListeners);
+        fListeners.clear();
+        for (Iterator it= listeners.iterator(); it.hasNext(); ) {
+            ILinkedModeListener listener= cast(ILinkedModeListener) it.next();
+            listener.left(this, flags);
+        }
+
+
+        if (fParentEnvironment !is null)
+            fParentEnvironment.resume(flags);
+    }
+
+    /**
+     * Causes this model to stop forwarding updates. The positions are not
+     * unregistered however, which will only happen when <code>exit</code>
+     * is called, or after the next document change.
+     *
+     * @param flags the exit flags as defined in {@link ILinkedModeListener}
+     * @since 3.1
+     */
+    public void stopForwarding(int flags) {
+        fDocumentListener.fExit= true;
+    }
+
+    /**
+     * Puts <code>document</code> into the set of managed documents. This
+     * involves registering the document listener and adding our position
+     * category.
+     *
+     * @param document the new document
+     */
+    private void manageDocument(IDocument document) {
+        if (!fDocuments.contains(cast(Object)document)) {
+            fDocuments.add(cast(Object)document);
+            document.addPositionCategory(getCategory());
+            document.addPositionUpdater(fUpdater);
+            document.addDocumentListener(fDocumentListener);
+        }
+
+    }
+
+    /**
+     * Returns the position category used by this model.
+     *
+     * @return the position category used by this model
+     */
+    private String getCategory() {
+        return toString();
+    }
+
+    /**
+     * Adds a position group to this <code>LinkedModeModel</code>. This
+     * method may not be called if the model has been installed. Also, if
+     * a UI has been set up for this model, it may not pick up groups
+     * added afterwards.
+     * <p>
+     * If the positions in <code>group</code> conflict with any other group in
+     * this model, a <code>BadLocationException</code> is thrown. Also,
+     * if this model is nested inside another one, all positions in all
+     * groups of the child model have to reside within a single position in the
+     * parent model, otherwise a <code>BadLocationException</code> is thrown.
+     * </p>
+     * <p>
+     * If <code>group</code> already exists, nothing happens.
+     * </p>
+     *
+     * @param group the group to be added to this model
+     * @throws BadLocationException if the group conflicts with the other groups
+     *         in this model or violates the nesting requirements.
+     * @throws IllegalStateException if the method is called when the
+     *         model is already sealed
+     */
+    public void addGroup(LinkedPositionGroup group)  {
+        if (group is null)
+            throw new IllegalArgumentException("group may not be null"); //$NON-NLS-1$
+        if (fIsSealed)
+            throw new IllegalStateException("model is already installed"); //$NON-NLS-1$
+        if (fGroups.contains(group))
+            // nothing happens
+            return;
+
+        enforceDisjoint(group);
+        group.seal();
+        fGroups.add(group);
+    }
+
+    /**
+     * Creates a new model.
+     * @since 3.1
+     */
+    public this() {
+        // DWT inst init
+        fGroups= new ArrayList();
+        fDocuments= new HashSet();
+        fUpdater= new InclusivePositionUpdater(getCategory());
+        fDocumentListener= new DocumentListener();
+        fListeners= new ArrayList();
+        fPositionSequence= new ArrayList();
+
+    }
+
+    /**
+     * Installs this model, which includes registering as document
+     * listener on all involved documents and storing global information about
+     * this model. Any conflicting model already present will be
+     * closed.
+     * <p>
+     * If an exception is thrown, the installation failed and
+     * the model is unusable.
+     * </p>
+     *
+     * @throws BadLocationException if some of the positions of this model
+     *         were not valid positions on their respective documents
+     */
+    public void forceInstall()  {
+        if (!install(true))
+            Assert.isTrue(false);
+    }
+
+    /**
+     * Installs this model, which includes registering as document
+     * listener on all involved documents and storing global information about
+     * this model. If there is another model installed on the
+     * document(s) targeted by the receiver that conflicts with it, installation
+     * may fail.
+     * <p>
+     * The return value states whether installation was
+     * successful; if not, the model is not installed and will not work.
+     * </p>
+     *
+     * @return <code>true</code> if installation was successful,
+     *         <code>false</code> otherwise
+     * @throws BadLocationException if some of the positions of this model
+     *         were not valid positions on their respective documents
+     */
+    public bool tryInstall()  {
+        return install(false);
+    }
+
+    /**
+     * Installs this model, which includes registering as document
+     * listener on all involved documents and storing global information about
+     * this model. The return value states whether installation was
+     * successful; if not, the model is not installed and will not work.
+     * The return value can only then become <code>false</code> if
+     * <code>force</code> was set to <code>false</code> as well.
+     *
+     * @param force if <code>true</code>, any other model that cannot
+     *        coexist with this one is canceled; if <code>false</code>,
+     *        install will fail when conflicts occur and return false
+     * @return <code>true</code> if installation was successful,
+     *         <code>false</code> otherwise
+     * @throws BadLocationException if some of the positions of this model
+     *         were not valid positions on their respective documents
+     */
+    private bool install(bool force)  {
+        if (fIsSealed)
+            throw new IllegalStateException("model is already installed"); //$NON-NLS-1$
+        enforceNotEmpty();
+
+        IDocument[] documents= getDocuments();
+        LinkedModeManager manager= LinkedModeManager.getLinkedManager(documents, force);
+        // if we force creation, we require a valid manager
+        Assert.isTrue(!(force && manager is null));
+        if (manager is null)
+            return false;
+
+        if (!manager.nestEnvironment(this, force))
+            if (force)
+                Assert.isTrue(false);
+            else
+                return false;
+
+        // we set up successfully. After this point, exit has to be called to
+        // remove registered listeners...
+        fIsSealed= true;
+        if (fParentEnvironment !is null)
+            fParentEnvironment.suspend();
+
+        // register positions
+        try {
+            for (Iterator it= fGroups.iterator(); it.hasNext(); ) {
+                LinkedPositionGroup group= cast(LinkedPositionGroup) it.next();
+                group.register(this);
+            }
+            return true;
+        } catch (BadLocationException e){
+            // if we fail to add, make sure to release all listeners again
+            exit(ILinkedModeListener.NONE);
+            throw e;
+        }
+    }
+
+    /**
+     * Asserts that there is at least one linked position in this linked mode
+     * model, throws an IllegalStateException otherwise.
+     */
+    private void enforceNotEmpty() {
+        bool hasPosition= false;
+        for (Iterator it= fGroups.iterator(); it.hasNext(); )
+            if (!(cast(LinkedPositionGroup) it.next()).isEmpty()) {
+                hasPosition= true;
+                break;
+            }
+        if (!hasPosition)
+            throw new IllegalStateException("must specify at least one linked position"); //$NON-NLS-1$
+
+    }
+
+    /**
+     * Collects all the documents that contained positions are set upon.
+     * @return the set of documents affected by this model
+     */
+    private IDocument[] getDocuments() {
+        Set docs= new HashSet();
+        for (Iterator it= fGroups.iterator(); it.hasNext(); ) {
+            LinkedPositionGroup group= cast(LinkedPositionGroup) it.next();
+            docs.addAll(Arrays.asList(arraycast!(Object)(group.getDocuments())));
+        }
+        return arraycast!(IDocument)( docs.toArray());
+    }
+
+    /**
+     * Returns whether the receiver can be nested into the given <code>parent</code>
+     * model. If yes, the parent model and its position that the receiver
+     * fits in are remembered.
+     *
+     * @param parent the parent model candidate
+     * @return <code>true</code> if the receiver can be nested into <code>parent</code>, <code>false</code> otherwise
+     */
+    bool canNestInto(LinkedModeModel parent) {
+        for (Iterator it= fGroups.iterator(); it.hasNext(); ) {
+            LinkedPositionGroup group= cast(LinkedPositionGroup) it.next();
+            if (!enforceNestability(group, parent)) {
+                fParentPosition= null;
+                return false;
+            }
+        }
+
+        Assert.isNotNull(fParentPosition);
+        fParentEnvironment= parent;
+        return true;
+    }
+
+    /**
+     * Called by nested models when a group is added to them. All
+     * positions in all groups of a nested model have to fit inside a
+     * single position in the parent model.
+     *
+     * @param group the group of the nested model to be adopted.
+     * @param model the model to check against
+     * @return <code>false</code> if it failed to enforce nestability
+     */
+    private bool enforceNestability(LinkedPositionGroup group, LinkedModeModel model) {
+        Assert.isNotNull(model);
+        Assert.isNotNull(group);
+
+        try {
+            for (Iterator it= model.fGroups.iterator(); it.hasNext(); ) {
+                LinkedPositionGroup pg= cast(LinkedPositionGroup) it.next();
+                LinkedPosition pos;
+                pos= pg.adopt(group);
+                if (pos !is null && fParentPosition !is null && fParentPosition !is pos)
+                    return false; // group does not fit into one parent position, which is illegal
+                else if (fParentPosition is null && pos !is null)
+                    fParentPosition= pos;
+            }
+        } catch (BadLocationException e) {
+            return false;
+        }
+
+        // group must fit into exactly one of the parent's positions
+        return fParentPosition !is null;
+    }
+
+    /**
+     * Returns whether this model is nested.
+     *
+     * <p>
+     * This method is part of the private protocol between
+     * <code>LinkedModeUI</code> and <code>LinkedModeModel</code>.
+     * </p>
+     *
+     * @return <code>true</code> if this model is nested,
+     *         <code>false</code> otherwise
+     */
+    public bool isNested() {
+        return fParentEnvironment !is null;
+    }
+
+    /**
+     * Returns the positions in this model that have a tab stop, in the
+     * order they were added.
+     *
+     * <p>
+     * This method is part of the private protocol between
+     * <code>LinkedModeUI</code> and <code>LinkedModeModel</code>.
+     * </p>
+     *
+     * @return the positions in this model that have a tab stop, in the
+     *         order they were added
+     */
+    public List getTabStopSequence() {
+        return fPositionSequence;
+    }
+
+    /**
+     * Adds <code>listener</code> to the set of listeners that are informed
+     * upon state changes.
+     *
+     * @param listener the new listener
+     */
+    public void addLinkingListener(ILinkedModeListener listener) {
+        Assert.isNotNull(cast(Object)listener);
+        if (!fListeners.contains(cast(Object)listener))
+            fListeners.add(cast(Object)listener);
+    }
+
+    /**
+     * Removes <code>listener</code> from the set of listeners that are
+     * informed upon state changes.
+     *
+     * @param listener the new listener
+     */
+    public void removeLinkingListener(ILinkedModeListener listener) {
+        fListeners.remove(cast(Object)listener);
+    }
+
+    /**
+     * Finds the position in this model that is closest after
+     * <code>toFind</code>. <code>toFind</code> needs not be a position in
+     * this model and serves merely as an offset.
+     *
+     * <p>
+     * This method part of the private protocol between
+     * <code>LinkedModeUI</code> and <code>LinkedModeModel</code>.
+     * </p>
+     *
+     * @param toFind the position to search from
+     * @return the closest position in the same document as <code>toFind</code>
+     *         after the offset of <code>toFind</code>, or <code>null</code>
+     */
+    public LinkedPosition findPosition(LinkedPosition toFind) {
+        LinkedPosition position= null;
+        for (Iterator it= fGroups.iterator(); it.hasNext(); ) {
+            LinkedPositionGroup group= cast(LinkedPositionGroup) it.next();
+            position= group.getPosition(toFind);
+            if (position !is null)
+                break;
+        }
+        return position;
+    }
+
+    /**
+     * Registers a <code>LinkedPosition</code> with this model. Called
+     * by <code>PositionGroup</code>.
+     *
+     * @param position the position to register
+     * @throws BadLocationException if the position cannot be added to its
+     *         document
+     */
+    void register(LinkedPosition position)  {
+        Assert.isNotNull(position);
+
+        IDocument document= position.getDocument();
+        manageDocument(document);
+        try {
+            document.addPosition(getCategory(), position);
+        } catch (BadPositionCategoryException e) {
+            // won't happen as the category has been added by manageDocument()
+            Assert.isTrue(false);
+        }
+        int seqNr= position.getSequenceNumber();
+        if (seqNr !is LinkedPositionGroup.NO_STOP) {
+            fPositionSequence.add(position);
+        }
+    }
+
+    /**
+     * Suspends this model.
+     */
+    private void suspend() {
+        List l= new ArrayList(fListeners);
+        for (Iterator it= l.iterator(); it.hasNext(); ) {
+            ILinkedModeListener listener= cast(ILinkedModeListener) it.next();
+            listener.suspend(this);
+        }
+    }
+
+    /**
+     * Resumes this model. <code>flags</code> can be <code>NONE</code>
+     * or <code>SELECT</code>.
+     *
+     * @param flags <code>NONE</code> or <code>SELECT</code>
+     */
+    private void resume(int flags) {
+        List l= new ArrayList(fListeners);
+        for (Iterator it= l.iterator(); it.hasNext(); ) {
+            ILinkedModeListener listener= cast(ILinkedModeListener) it.next();
+            listener.resume(this, flags);
+        }
+    }
+
+    /**
+     * Returns whether an offset is contained by any position in this
+     * model.
+     *
+     * @param offset the offset to check
+     * @return <code>true</code> if <code>offset</code> is included by any
+     *         position (see {@link LinkedPosition#includes(int)}) in this
+     *         model, <code>false</code> otherwise
+     */
+    public bool anyPositionContains(int offset) {
+        for (Iterator it= fGroups.iterator(); it.hasNext(); ) {
+            LinkedPositionGroup group= cast(LinkedPositionGroup) it.next();
+            if (group.contains(offset))
+                // take the first hit - exclusion is guaranteed by enforcing
+                // disjointness when adding positions
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the linked position group that contains <code>position</code>,
+     * or <code>null</code> if <code>position</code> is not contained in any
+     * group within this model. Group containment is tested by calling
+     * <code>group.contains(position)</code> for every <code>group</code> in
+     * this model.
+     *
+     * <p>
+     * This method part of the private protocol between
+     * <code>LinkedModeUI</code> and <code>LinkedModeModel</code>.
+     * </p>
+     *
+     * @param position the position the group of which is requested
+     * @return the first group in this model for which
+     *         <code>group.contains(position)</code> returns <code>true</code>,
+     *         or <code>null</code> if no group contains <code>position</code>
+     */
+    public LinkedPositionGroup getGroupForPosition(Position position) {
+        for (Iterator it= fGroups.iterator(); it.hasNext(); ) {
+            LinkedPositionGroup group= cast(LinkedPositionGroup) it.next();
+            if (group.contains(position))
+                return group;
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/link/LinkedModeUI.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1353 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.link.LinkedModeUI;
+
+import dwtx.jface.text.link.LinkedModeModel; // packageimport
+import dwtx.jface.text.link.LinkedPosition; // packageimport
+import dwtx.jface.text.link.ILinkedModeListener; // packageimport
+import dwtx.jface.text.link.TabStopIterator; // packageimport
+import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.link.LinkedPositionGroup; // packageimport
+import dwtx.jface.text.link.LinkedModeManager; // packageimport
+import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport
+import dwtx.jface.text.link.ProposalPosition; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.custom.VerifyKeyListener;
+import dwt.events.ShellEvent;
+import dwt.events.ShellListener;
+import dwt.events.VerifyEvent;
+import dwt.graphics.Point;
+import dwt.widgets.Display;
+import dwt.widgets.Shell;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.internal.text.link.contentassist.ContentAssistant2;
+import dwtx.jface.internal.text.link.contentassist.IProposalListener;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPartitioningException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DefaultPositionUpdater;
+import dwtx.jface.text.DocumentCommand;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IAutoEditStrategy;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentExtension3;
+import dwtx.jface.text.IDocumentListener;
+import dwtx.jface.text.IEditingSupport;
+import dwtx.jface.text.IEditingSupportRegistry;
+import dwtx.jface.text.IPositionUpdater;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.IRewriteTarget;
+import dwtx.jface.text.ITextInputListener;
+import dwtx.jface.text.ITextOperationTarget;
+import dwtx.jface.text.ITextSelection;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension;
+import dwtx.jface.text.ITextViewerExtension2;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.contentassist.ICompletionProposal;
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6;
+import dwtx.jface.text.source.IAnnotationModel;
+import dwtx.jface.text.source.IAnnotationModelExtension;
+import dwtx.jface.text.source.ISourceViewer;
+import dwtx.jface.viewers.IPostSelectionProvider;
+import dwtx.jface.viewers.ISelection;
+import dwtx.jface.viewers.ISelectionChangedListener;
+import dwtx.jface.viewers.SelectionChangedEvent;
+
+/**
+ * The UI for linked mode. Detects events that influence behavior of the linked mode
+ * UI and acts upon them.
+ * <p>
+ * <code>LinkedModeUI</code> relies on all added
+ * <code>LinkedModeUITarget</code>s to provide implementations of
+ * <code>ITextViewer</code> that implement <code>ITextViewerExtension</code>,
+ * and the documents being edited to implement <code>IDocumentExtension3</code>.
+ * </p>
+ * <p>
+ * Clients may instantiate and extend this class.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class LinkedModeUI {
+
+    /* cycle constants */
+    /**
+     * Constant indicating that this UI should never cycle from the last
+     * position to the first and vice versa.
+     */
+    public static Object CYCLE_NEVER_;
+    public static Object CYCLE_NEVER(){
+        if( CYCLE_NEVER_ is null ){
+            synchronized( LinkedModeUI.classinfo ){
+                if( CYCLE_NEVER_ is null ){
+                    CYCLE_NEVER_ = new Object();
+                }
+            }
+        }
+        return CYCLE_NEVER_;
+    }
+    /**
+     * Constant indicating that this UI should always cycle from the last
+     * position to the first and vice versa.
+     */
+    public static Object CYCLE_ALWAYS_;
+    public static Object CYCLE_ALWAYS(){
+        if( CYCLE_ALWAYS_ is null ){
+            synchronized( LinkedModeUI.classinfo ){
+                if( CYCLE_ALWAYS_ is null ){
+                    CYCLE_ALWAYS_ = new Object();
+                }
+            }
+        }
+        return CYCLE_ALWAYS_;
+    }
+    /**
+     * Constant indicating that this UI should cycle from the last position to
+     * the first and vice versa if its model is not nested.
+     */
+    public static Object CYCLE_WHEN_NO_PARENT_;
+    public static Object CYCLE_WHEN_NO_PARENT(){
+        if( CYCLE_WHEN_NO_PARENT_ is null ){
+            synchronized( LinkedModeUI.classinfo ){
+                if( CYCLE_WHEN_NO_PARENT_ is null ){
+                    CYCLE_WHEN_NO_PARENT_ = new Object();
+                }
+            }
+        }
+        return CYCLE_WHEN_NO_PARENT_;
+    }
+
+    /**
+     * Listener that gets notified when the linked mode UI switches its focus position.
+     * <p>
+     * Clients may implement this interface.
+     * </p>
+     */
+    public interface ILinkedModeUIFocusListener {
+        /**
+         * Called when the UI for the linked mode leaves a linked position.
+         *
+         * @param position the position being left
+         * @param target the target where <code>position</code> resides in
+         */
+        void linkingFocusLost(LinkedPosition position, LinkedModeUITarget target);
+        /**
+         * Called when the UI for the linked mode gives focus to a linked position.
+         *
+         * @param position the position being entered
+         * @param target the target where <code>position</code> resides in
+         */
+        void linkingFocusGained(LinkedPosition position, LinkedModeUITarget target);
+    }
+
+    /**
+     * Null object implementation of focus listener.
+     */
+    private static final class EmtpyFocusListener : ILinkedModeUIFocusListener {
+
+        public void linkingFocusGained(LinkedPosition position, LinkedModeUITarget target) {
+            // ignore
+        }
+
+        public void linkingFocusLost(LinkedPosition position, LinkedModeUITarget target) {
+            // ignore
+        }
+    }
+
+    /**
+     * A link target consists of a viewer and gets notified if the linked mode UI on
+     * it is being shown.
+     * <p>
+     * Clients may extend this class.
+     * </p>
+     * @since 3.0
+     */
+    public static abstract class LinkedModeUITarget : ILinkedModeUIFocusListener {
+        /**
+         * Returns the viewer represented by this target, never <code>null</code>.
+         *
+         * @return the viewer associated with this target.
+         */
+        public abstract ITextViewer getViewer();
+
+        /**
+         * The viewer's text widget is initialized when the UI first connects
+         * to the viewer and never changed thereafter. This is to keep the
+         * reference of the widget that we have registered our listeners with,
+         * as the viewer, when it gets disposed, does not remember it, resulting
+         * in a situation where we cannot uninstall the listeners and a memory leak.
+         */
+        StyledText fWidget;
+
+        /** The cached shell - same reason as fWidget. */
+        Shell fShell;
+
+        /** The registered listener, or <code>null</code>. */
+        KeyListener fKeyListener;
+
+        /** The cached custom annotation model. */
+        LinkedPositionAnnotations fAnnotationModel;
+    }
+
+    private static final class EmptyTarget : LinkedModeUITarget {
+
+        private ITextViewer fTextViewer;
+
+        /**
+         * @param viewer the viewer
+         */
+        public this(ITextViewer viewer) {
+            Assert.isNotNull(cast(Object)viewer);
+            fTextViewer= viewer;
+        }
+
+        /*
+         * @see dwtx.jdt.internal.ui.text.link2.LinkedModeUI.ILinkedUITarget#getViewer()
+         */
+        public ITextViewer getViewer() {
+            return fTextViewer;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void linkingFocusLost(LinkedPosition position, LinkedModeUITarget target) {
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        public void linkingFocusGained(LinkedPosition position, LinkedModeUITarget target) {
+        }
+
+    }
+
+    /**
+     * Listens for state changes in the model.
+     */
+    private final class ExitListener : ILinkedModeListener {
+        public void left(LinkedModeModel model, int flags) {
+            leave(ILinkedModeListener.EXIT_ALL | flags);
+        }
+
+        public void suspend(LinkedModeModel model) {
+            disconnect();
+            redraw();
+        }
+
+        public void resume(LinkedModeModel model, int flags) {
+            if ((flags & ILinkedModeListener.EXIT_ALL) !is 0) {
+                leave(flags);
+            } else {
+                connect();
+                if ((flags & ILinkedModeListener.SELECT) !is 0)
+                    select();
+                ensureAnnotationModelInstalled();
+                redraw();
+            }
+        }
+    }
+
+    /**
+     * Exit flags returned if a custom exit policy wants to exit linked mode.
+     * <p>
+     * Clients may instantiate this class.
+     * </p>
+     */
+    public static class ExitFlags {
+        /** The flags to return in the <code>leave</code> method. */
+        public int flags;
+        /** The doit flag of the checked <code>VerifyKeyEvent</code>. */
+        public bool doit;
+        /**
+         * Creates a new instance.
+         *
+         * @param flags the exit flags
+         * @param doit the doit flag for the verify event
+         */
+        public this(int flags, bool doit) {
+            this.flags= flags;
+            this.doit= doit;
+        }
+    }
+
+    /**
+     * An exit policy can be registered by a caller to get custom exit
+     * behavior.
+     * <p>
+     * Clients may implement this interface.
+     * </p>
+     */
+    public interface IExitPolicy {
+        /**
+         * Checks whether the linked mode should be left after receiving the
+         * given <code>VerifyEvent</code> and selection. Note that the event
+         * carries widget coordinates as opposed to <code>offset</code> and
+         * <code>length</code> which are document coordinates.
+         *
+         * @param model the linked mode model
+         * @param event the verify event
+         * @param offset the offset of the current selection
+         * @param length the length of the current selection
+         * @return valid exit flags or <code>null</code> if no special action
+         *         should be taken
+         */
+        ExitFlags doExit(LinkedModeModel model, VerifyEvent event, int offset, int length);
+    }
+
+    /**
+     * A NullObject implementation of <code>IExitPolicy</code>.
+     */
+    private static class NullExitPolicy : IExitPolicy {
+        /*
+         * @see dwtx.jdt.internal.ui.text.link2.LinkedModeUI.IExitPolicy#doExit(dwt.events.VerifyEvent, int, int)
+         */
+        public ExitFlags doExit(LinkedModeModel model, VerifyEvent event, int offset, int length) {
+            return null;
+        }
+    }
+
+    /**
+     * Listens for shell events and acts upon them.
+     */
+    private class Closer : ShellListener, ITextInputListener {
+
+        public void shellActivated(ShellEvent e) {
+        }
+
+        public void shellClosed(ShellEvent e) {
+            leave(ILinkedModeListener.EXIT_ALL);
+        }
+
+        public void shellDeactivated(ShellEvent e) {
+//          TODO re-enable after debugging
+//          if (true) return;
+
+            // from LinkedPositionUI:
+
+            // don't deactivate on focus lost, since the proposal popups may take focus
+            // plus: it doesn't hurt if you can check with another window without losing linked mode
+            // since there is no intrusive popup sticking out.
+
+            // need to check first what happens on reentering based on an open action
+            // Seems to be no problem
+
+            // Better:
+            // Check with content assistant and only leave if its not the proposal shell that took the
+            // focus away.
+
+            StyledText text;
+            ITextViewer viewer;
+            Display display;
+
+            if (fCurrentTarget is null || (text= fCurrentTarget.fWidget) is null
+                    || text.isDisposed() || (display= text.getDisplay()) is null
+                    || display.isDisposed()
+                    || (viewer= fCurrentTarget.getViewer()) is null)
+            {
+                leave(ILinkedModeListener.EXIT_ALL);
+            }
+            else
+            {
+                // Post in UI thread since the assistant popup will only get the focus after we lose it.
+                display.asyncExec(dgRunnable( (ITextViewer viewer_) {
+                    if (fIsActive && cast(IEditingSupportRegistry)viewer_ ) {
+                        IEditingSupport[] helpers= (cast(IEditingSupportRegistry) viewer_).getRegisteredSupports();
+                        for (int i= 0; i < helpers.length; i++) {
+                            if (helpers[i].ownsFocusShell())
+                                return;
+                        }
+                    }
+
+                    // else
+                    leave(ILinkedModeListener.EXIT_ALL);
+
+                }, viewer ));
+            }
+        }
+
+        public void shellDeiconified(ShellEvent e) {
+        }
+
+        public void shellIconified(ShellEvent e) {
+            leave(ILinkedModeListener.EXIT_ALL);
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument)
+         */
+        public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
+            leave(ILinkedModeListener.EXIT_ALL);
+        }
+
+        /*
+         * @see dwtx.jface.text.ITextInputListener#inputDocumentChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument)
+         */
+        public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+        }
+
+    }
+
+    /**
+     * @since 3.1
+     */
+    private class DocumentListener : IDocumentListener {
+        /*
+         * @see dwtx.jface.text.IDocumentListener#documentAboutToBeChanged(dwtx.jface.text.DocumentEvent)
+         */
+        public void documentAboutToBeChanged(DocumentEvent event) {
+
+            // default behavior: any document change outside a linked position
+            // causes us to exit
+            int end= event.getOffset() + event.getLength();
+            for (int offset= event.getOffset(); offset <= end; offset++) {
+                if (!fModel.anyPositionContains(offset)) {
+                    ITextViewer viewer= fCurrentTarget.getViewer();
+                    if (fFramePosition !is null && cast(IEditingSupportRegistry)viewer ) {
+                        IEditingSupport[] helpers= (cast(IEditingSupportRegistry) viewer).getRegisteredSupports();
+                        for (int i= 0; i < helpers.length; i++) {
+                            if (helpers[i].isOriginator(null, new Region(fFramePosition.getOffset(), fFramePosition.getLength())))
+                                return;
+                        }
+                    }
+
+                    leave(ILinkedModeListener.EXTERNAL_MODIFICATION);
+                    return;
+                }
+            }
+        }
+
+        /*
+         * @see dwtx.jface.text.IDocumentListener#documentChanged(dwtx.jface.text.DocumentEvent)
+         */
+        public void documentChanged(DocumentEvent event) {
+        }
+    }
+
+    /**
+     * Listens for key events, checks the exit policy for custom exit
+     * strategies but defaults to handling Tab, Enter, and Escape.
+     */
+    private class KeyListener : VerifyKeyListener {
+
+        private bool fIsEnabled= true;
+
+        public void verifyKey(VerifyEvent event) {
+
+            if (!event.doit || !fIsEnabled)
+                return;
+
+            Point selection= fCurrentTarget.getViewer().getSelectedRange();
+            int offset= selection.x;
+            int length= selection.y;
+
+            // if the custom exit policy returns anything, use that
+            ExitFlags exitFlags= fExitPolicy.doExit(fModel, event, offset, length);
+            if (exitFlags !is null) {
+                leave(exitFlags.flags);
+                event.doit= exitFlags.doit;
+                return;
+            }
+
+            // standard behavior:
+            // (Shift+)Tab: jumps from position to position, depending on cycle mode
+            // Enter:       accepts all entries and leaves all (possibly stacked) environments, the last sets the caret
+            // Esc:         accepts all entries and leaves all (possibly stacked) environments, the caret stays
+            // ? what do we do to leave one level of a cycling model that is stacked?
+            // -> This is only the case if the level was set up with forced cycling cast(CYCLE_ALWAYS), in which case
+            // the caller is sure that one does not need by-level exiting.
+            switch (event.character) {
+                // [SHIFT-]TAB = hop between edit boxes
+                case 0x09:
+                    if (!(fExitPosition !is null && fExitPosition.includes(offset)) && !fModel.anyPositionContains(offset)) {
+                        // outside any edit box -> leave (all? TODO should only leave the affected, level and forward to the next upper)
+                        leave(ILinkedModeListener.EXIT_ALL);
+                        break;
+                    }
+
+                    if (event.stateMask is DWT.SHIFT)
+                        previous();
+                    else
+                        next();
+
+                    event.doit= false;
+                    break;
+
+                // ENTER
+                case 0x0A:
+                // Ctrl+Enter on WinXP
+                case 0x0D:
+//                  if ((fExitPosition !is null && fExitPosition.includes(offset)) || !fModel.anyPositionContains(offset)) {
+                    if (!fModel.anyPositionContains(offset)) {
+//                  if ((fExitPosition is null || !fExitPosition.includes(offset)) && !fModel.anyPositionContains(offset)) {
+                        // outside any edit box or on exit position -> leave (all? TODO should only leave the affected, level and forward to the next upper)
+                        leave(ILinkedModeListener.EXIT_ALL);
+                        break;
+                    }
+
+                    // normal case: exit entire stack and put caret to final position
+                    leave(ILinkedModeListener.EXIT_ALL | ILinkedModeListener.UPDATE_CARET);
+                    event.doit= false;
+                    break;
+
+                // ESC
+                case 0x1B:
+                    // exit entire stack and leave caret
+                    leave(ILinkedModeListener.EXIT_ALL);
+                    event.doit= false;
+                    break;
+
+                default:
+                    if (event.character !is 0) {
+                        if (!controlUndoBehavior(offset, length)) {
+                            leave(ILinkedModeListener.EXIT_ALL);
+                            break;
+                        }
+                    }
+            }
+        }
+
+        private bool controlUndoBehavior(int offset, int length) {
+            LinkedPosition position= fModel.findPosition(new LinkedPosition(fCurrentTarget.getViewer().getDocument(), offset, length, LinkedPositionGroup.NO_STOP));
+            if (position !is null) {
+
+                // if the last position is not the same and there is an open change: close it.
+                if (!position.equals(fPreviousPosition))
+                    endCompoundChange();
+
+                beginCompoundChange();
+            }
+
+            fPreviousPosition= position;
+            return fPreviousPosition !is null;
+        }
+
+        /**
+         * @param enabled the new enabled state
+         */
+        public void setEnabled(bool enabled) {
+            fIsEnabled= enabled;
+        }
+
+    }
+
+    /**
+     * Installed as post selection listener on the watched viewer. Updates the
+     * linked position after cursor movement, even to positions not in the
+     * iteration list.
+     */
+    private class MySelectionListener : ISelectionChangedListener {
+
+        /*
+         * @see dwtx.jface.viewers.ISelectionChangedListener#selectionChanged(dwtx.jface.viewers.SelectionChangedEvent)
+         */
+        public void selectionChanged(SelectionChangedEvent event) {
+            ISelection selection= event.getSelection();
+            if ( cast(ITextSelection)selection ) {
+                ITextSelection textsel= cast(ITextSelection) selection;
+                if ( cast(ITextViewer)event.getSelectionProvider() ) {
+                    IDocument doc= (cast(ITextViewer) event.getSelectionProvider()).getDocument();
+                    if (doc !is null) {
+                        int offset= textsel.getOffset();
+                        int length= textsel.getLength();
+                        if (offset >= 0 && length >= 0) {
+                            LinkedPosition find= new LinkedPosition(doc, offset, length, LinkedPositionGroup.NO_STOP);
+                            LinkedPosition pos= fModel.findPosition(find);
+                            if (pos is null && fExitPosition !is null && fExitPosition.includes(find))
+                                pos= fExitPosition;
+
+                            if (pos !is null)
+                                switchPosition(pos, false, false);
+                        }
+                    }
+                }
+            }
+        }
+
+    }
+
+    private class ProposalListener : IProposalListener {
+
+        /*
+         * @see dwtx.jface.internal.text.link.contentassist.IProposalListener#proposalChosen(dwtx.jface.text.contentassist.ICompletionProposal)
+         */
+        public void proposalChosen(ICompletionProposal proposal) {
+            next();
+        }
+    }
+
+    /** The current viewer. */
+    private LinkedModeUITarget fCurrentTarget;
+    /**
+     * The manager of the linked positions we provide a UI for.
+     * @since 3.1
+     */
+    private LinkedModeModel fModel;
+    /** The set of viewers we manage. */
+    private LinkedModeUITarget[] fTargets;
+    /** The iterator over the tab stop positions. */
+    private TabStopIterator fIterator;
+
+    /* Our team of event listeners */
+    /** The shell listener. */
+    private Closer fCloser;
+    /** The linked mode listener. */
+    private ILinkedModeListener fLinkedListener;
+    /** The selection listener. */
+    private MySelectionListener fSelectionListener;
+    /** The content assist listener. */
+    private ProposalListener fProposalListener;
+    /**
+     * The document listener.
+     * @since 3.1
+     */
+    private IDocumentListener fDocumentListener;
+
+    /** The last caret position, used by fCaretListener. */
+    private const Position fCaretPosition;
+    /** The exit policy to control custom exit behavior */
+    private IExitPolicy fExitPolicy;
+    /** The current frame position shown in the UI, or <code>null</code>. */
+    private LinkedPosition fFramePosition;
+    /** The last visited position, used for undo / redo. */
+    private LinkedPosition fPreviousPosition;
+    /** The content assistant used to show proposals. */
+    private ContentAssistant2 fAssistant;
+    /** The exit position. */
+    private LinkedPosition fExitPosition;
+    /** State indicator to prevent multiple invocation of leave. */
+    private bool fIsActive= false;
+    /** The position updater for the exit position. */
+    private IPositionUpdater fPositionUpdater;
+    /** Whether to show context info. */
+    private bool fDoContextInfo= false;
+    /** Whether we have begun a compound change, but not yet closed. */
+    private bool fHasOpenCompoundChange= false;
+    /** The position listener. */
+    private ILinkedModeUIFocusListener fPositionListener;
+    private IAutoEditStrategy fAutoEditVetoer;
+    private void fAutoEditVetoer_init(){
+        fAutoEditVetoer = new class()  IAutoEditStrategy {
+            /*
+            * @see dwtx.jface.text.IAutoEditStrategy#customizeDocumentCommand(dwtx.jface.text.IDocument, dwtx.jface.text.DocumentCommand)
+            */
+            public void customizeDocumentCommand(IDocument document, DocumentCommand command) {
+                // invalidate the change to ensure that the change is performed on the document only.
+                if (fModel.anyPositionContains(command.offset)) {
+                    command.doit= false;
+                    command.caretOffset= command.offset + command.length;
+                }
+
+            }
+        };
+    }
+
+    /** Whether this UI is in simple highlighting mode or not. */
+    private bool fSimple;
+
+    /**
+     * Tells whether colored labels support is enabled.
+     * @since 3.4
+     */
+    private bool fIsColoredLabelsSupportEnabled= false;
+
+    private this(){
+        fCloser= new Closer();
+        fLinkedListener= new ExitListener();
+        fSelectionListener= new MySelectionListener();
+        fProposalListener= new ProposalListener();
+        fDocumentListener= new DocumentListener();
+        fCaretPosition= new Position(0, 0);
+        fExitPolicy= new NullExitPolicy();
+        fPositionUpdater= new DefaultPositionUpdater(getCategory());
+        fPositionListener= new EmtpyFocusListener();
+        fAutoEditVetoer_init();
+    }
+
+    /**
+     * Creates a new UI on the given model and the set of viewers. The model
+     * must provide a tab stop sequence with a non-empty list of tab stops.
+     *
+     * @param model the linked mode model
+     * @param targets the non-empty list of targets upon which the linked mode
+     *        UI should act
+     */
+    public this(LinkedModeModel model, LinkedModeUITarget[] targets) {
+        this();
+        constructor(model, targets);
+    }
+
+    /**
+     * Convenience constructor for just one viewer.
+     *
+     * @param model the linked mode model
+     * @param viewer the viewer upon which the linked mode UI should act
+     */
+    public this(LinkedModeModel model, ITextViewer viewer) {
+        this();
+        constructor(model, [new EmptyTarget(viewer)]);
+    }
+
+    /**
+     * Convenience constructor for multiple viewers.
+     *
+     * @param model the linked mode model
+     * @param viewers the non-empty list of viewers upon which the linked mode
+     *        UI should act
+     */
+    public this(LinkedModeModel model, ITextViewer[] viewers) {
+        this();
+        LinkedModeUITarget[] array= new LinkedModeUITarget[viewers.length];
+        for (int i= 0; i < array.length; i++) {
+            array[i]= new EmptyTarget(viewers[i]);
+        }
+        constructor(model, array);
+    }
+
+    /**
+     * Convenience constructor for one target.
+     *
+     * @param model the linked mode model
+     * @param target the target upon which the linked mode UI should act
+     */
+    public this(LinkedModeModel model, LinkedModeUITarget target) {
+        this();
+        constructor(model, [target]);
+    }
+
+    /**
+     * This does the actual constructor work.
+     *
+     * @param model the linked mode model
+     * @param targets the non-empty array of targets upon which the linked mode UI
+     *        should act
+     */
+    private void constructor(LinkedModeModel model, LinkedModeUITarget[] targets) {
+        Assert.isNotNull(model);
+        //Assert.isNotNull(targets);
+        Assert.isTrue(targets.length > 0);
+        Assert.isTrue(model.getTabStopSequence().size() > 0);
+
+        fModel= model;
+        fTargets= targets;
+        fCurrentTarget= targets[0];
+        fIterator= new TabStopIterator(fModel.getTabStopSequence());
+        fIterator.setCycling(!fModel.isNested());
+        fModel.addLinkingListener(fLinkedListener);
+
+        fAssistant= new ContentAssistant2();
+        fAssistant.addProposalListener(fProposalListener);
+        // TODO find a way to set up content assistant.
+//      fAssistant.setDocumentPartitioning(IJavaPartitions.JAVA_PARTITIONING);
+        fAssistant.enableColoredLabels(fIsColoredLabelsSupportEnabled);
+        fCaretPosition.delete_();
+    }
+
+    /**
+     * Starts this UI on the first position.
+     */
+    public void enter() {
+        fIsActive= true;
+        connect();
+        next();
+    }
+
+    /**
+     * Sets an <code>IExitPolicy</code> to customize the exit behavior of
+     * this linked mode UI.
+     *
+     * @param policy the exit policy to use.
+     */
+    public void setExitPolicy(IExitPolicy policy) {
+        fExitPolicy= policy;
+    }
+
+    /**
+     * Sets the exit position to move the caret to when linked mode mode is
+     * exited.
+     *
+     * @param target the target where the exit position is located
+     * @param offset the offset of the exit position
+     * @param length the length of the exit position (in case there should be a
+     *        selection)
+     * @param sequence set to the tab stop position of the exit position, or
+     *        <code>LinkedPositionGroup.NO_STOP</code> if there should be no
+     *        tab stop.
+     * @throws BadLocationException if the position is not valid in the viewer's
+     *         document
+     */
+    public void setExitPosition(LinkedModeUITarget target, int offset, int length, int sequence)  {
+        // remove any existing exit position
+        if (fExitPosition !is null) {
+            fExitPosition.getDocument().removePosition(fExitPosition);
+            fIterator.removePosition(fExitPosition);
+            fExitPosition= null;
+        }
+
+        IDocument doc= target.getViewer().getDocument();
+        if (doc is null)
+            return;
+
+        fExitPosition= new LinkedPosition(doc, offset, length, sequence);
+        doc.addPosition(fExitPosition); // gets removed in leave()
+        if (sequence !is LinkedPositionGroup.NO_STOP)
+            fIterator.addPosition(fExitPosition);
+
+    }
+
+    /**
+     * Sets the exit position to move the caret to when linked mode is exited.
+     *
+     * @param viewer the viewer where the exit position is located
+     * @param offset the offset of the exit position
+     * @param length the length of the exit position (in case there should be a
+     *        selection)
+     * @param sequence set to the tab stop position of the exit position, or
+     *        <code>LinkedPositionGroup.NO_STOP</code> if there should be no tab stop.
+     * @throws BadLocationException if the position is not valid in the
+     *         viewer's document
+     */
+    public void setExitPosition(ITextViewer viewer, int offset, int length, int sequence)  {
+        setExitPosition(new EmptyTarget(viewer), offset, length, sequence);
+    }
+
+    /**
+     * Sets the cycling mode to either of <code>CYCLING_ALWAYS</code>,
+     * <code>CYCLING_NEVER</code>, or <code>CYCLING_WHEN_NO_PARENT</code>,
+     * which is the default.
+     *
+     * @param mode the new cycling mode.
+     */
+    public void setCyclingMode(Object mode) {
+        if (mode !is CYCLE_ALWAYS && mode !is CYCLE_NEVER && mode !is CYCLE_WHEN_NO_PARENT)
+            throw new IllegalArgumentException(null);
+
+        if (mode is CYCLE_ALWAYS || mode is CYCLE_WHEN_NO_PARENT && !fModel.isNested())
+            fIterator.setCycling(true);
+        else
+            fIterator.setCycling(false);
+    }
+
+    void next() {
+        if (fIterator.hasNext(fFramePosition)) {
+            switchPosition(fIterator.next(fFramePosition), true, true);
+            return;
+        }
+        leave(ILinkedModeListener.UPDATE_CARET);
+    }
+
+    void previous() {
+        if (fIterator.hasPrevious(fFramePosition)) {
+            switchPosition(fIterator.previous(fFramePosition), true, true);
+        } else
+            // dont't update caret, but rather select the current frame
+            leave(ILinkedModeListener.SELECT);
+    }
+
+    private void triggerContextInfo() {
+        ITextOperationTarget target= fCurrentTarget.getViewer().getTextOperationTarget();
+        if (target !is null) {
+            if (target.canDoOperation(ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION))
+                target.doOperation(ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION);
+        }
+    }
+
+    /** Trigger content assist on choice positions */
+    private void triggerContentAssist() {
+        if ( cast(ProposalPosition)fFramePosition ) {
+            ProposalPosition pp= cast(ProposalPosition) fFramePosition;
+            ICompletionProposal[] choices= pp.getChoices();
+            if (choices !is null && choices.length > 0) {
+                fAssistant.setCompletions(choices);
+                fAssistant.showPossibleCompletions();
+                return;
+            }
+        }
+
+        fAssistant.setCompletions(new ICompletionProposal[0]);
+        fAssistant.hidePossibleCompletions();
+    }
+
+    private void switchPosition(LinkedPosition pos, bool select_, bool showProposals) {
+        Assert.isNotNull(pos);
+        if (pos.equals(fFramePosition))
+            return;
+
+        if (fFramePosition !is null && fCurrentTarget !is null)
+            fPositionListener.linkingFocusLost(fFramePosition, fCurrentTarget);
+
+        // undo
+        endCompoundChange();
+
+        redraw(); // redraw current position being left - usually not needed
+        IDocument oldDoc= fFramePosition is null ? null : fFramePosition.getDocument();
+        IDocument newDoc= pos.getDocument();
+
+        switchViewer(oldDoc, newDoc, pos);
+        fFramePosition= pos;
+
+        if (select_)
+            select();
+        if (fFramePosition is fExitPosition && !fIterator.isCycling())
+            leave(ILinkedModeListener.NONE);
+        else {
+            redraw(); // redraw new position
+            ensureAnnotationModelInstalled();
+        }
+        if (showProposals)
+            triggerContentAssist();
+        if (fFramePosition !is fExitPosition && fDoContextInfo)
+            triggerContextInfo();
+
+        if (fFramePosition !is null && fCurrentTarget !is null)
+            fPositionListener.linkingFocusGained(fFramePosition, fCurrentTarget);
+
+    }
+
+    private void ensureAnnotationModelInstalled() {
+        LinkedPositionAnnotations lpa= fCurrentTarget.fAnnotationModel;
+        if (lpa !is null) {
+            ITextViewer viewer= fCurrentTarget.getViewer();
+            if ( cast(ISourceViewer)viewer ) {
+                ISourceViewer sv= cast(ISourceViewer) viewer;
+                IAnnotationModel model= sv.getAnnotationModel();
+                if ( cast(IAnnotationModelExtension)model ) {
+                    IAnnotationModelExtension ext= cast(IAnnotationModelExtension) model;
+                    IAnnotationModel ourModel= ext.getAnnotationModel(stringcast(getUniqueKey()));
+                    if (ourModel is null) {
+                        ext.addAnnotationModel(stringcast(getUniqueKey()), lpa);
+                    }
+                }
+            }
+        }
+    }
+
+    private void uninstallAnnotationModel(LinkedModeUITarget target) {
+        ITextViewer viewer= target.getViewer();
+        if ( cast(ISourceViewer)viewer ) {
+            ISourceViewer sv= cast(ISourceViewer) viewer;
+            IAnnotationModel model= sv.getAnnotationModel();
+            if ( cast(IAnnotationModelExtension)model ) {
+                IAnnotationModelExtension ext= cast(IAnnotationModelExtension) model;
+                ext.removeAnnotationModel(stringcast(getUniqueKey()));
+            }
+        }
+    }
+
+    private void switchViewer(IDocument oldDoc, IDocument newDoc, LinkedPosition pos) {
+        if (oldDoc !is newDoc) {
+
+            // redraw current document with new position before switching viewer
+            if (fCurrentTarget.fAnnotationModel !is null)
+                fCurrentTarget.fAnnotationModel.switchToPosition(fModel, pos);
+
+            LinkedModeUITarget target= null;
+            for (int i= 0; i < fTargets.length; i++) {
+                if (fTargets[i].getViewer().getDocument() is newDoc) {
+                    target= fTargets[i];
+                    break;
+                }
+            }
+            if (target !is fCurrentTarget) {
+                disconnect();
+                fCurrentTarget= target;
+                target.linkingFocusLost(fFramePosition, target);
+                connect();
+                ensureAnnotationModelInstalled();
+                if (fCurrentTarget !is null)
+                    fCurrentTarget.linkingFocusGained(pos, fCurrentTarget);
+            }
+        }
+    }
+
+    private void select() {
+        ITextViewer viewer= fCurrentTarget.getViewer();
+        if ( cast(ITextViewerExtension5)viewer ) {
+            ITextViewerExtension5 extension5= cast(ITextViewerExtension5) viewer;
+            extension5.exposeModelRange(new Region(fFramePosition.offset, fFramePosition.length));
+        } else if (!viewer.overlapsWithVisibleRegion(fFramePosition.offset, fFramePosition.length)) {
+            viewer.resetVisibleRegion();
+        }
+        viewer.revealRange(fFramePosition.offset, fFramePosition.length);
+        viewer.setSelectedRange(fFramePosition.offset, fFramePosition.length);
+    }
+
+    private void redraw() {
+        if (fCurrentTarget.fAnnotationModel !is null)
+            fCurrentTarget.fAnnotationModel.switchToPosition(fModel, fFramePosition);
+    }
+
+    private void connect() {
+        Assert.isNotNull(fCurrentTarget);
+        ITextViewer viewer= fCurrentTarget.getViewer();
+        Assert.isNotNull(cast(Object)viewer);
+        fCurrentTarget.fWidget= viewer.getTextWidget();
+        if (fCurrentTarget.fWidget is null)
+            leave(ILinkedModeListener.EXIT_ALL);
+
+        if (fCurrentTarget.fKeyListener is null) {
+            fCurrentTarget.fKeyListener= new KeyListener();
+            (cast(ITextViewerExtension) viewer).prependVerifyKeyListener(fCurrentTarget.fKeyListener);
+        } else
+            fCurrentTarget.fKeyListener.setEnabled(true);
+
+        registerAutoEditVetoer(viewer);
+
+        (cast(IPostSelectionProvider) viewer).addPostSelectionChangedListener(fSelectionListener);
+
+        createAnnotationModel();
+
+        showSelection();
+
+        fCurrentTarget.fShell= fCurrentTarget.fWidget.getShell();
+        if (fCurrentTarget.fShell is null)
+            leave(ILinkedModeListener.EXIT_ALL);
+        fCurrentTarget.fShell.addShellListener(fCloser);
+
+        fAssistant.install(viewer);
+
+        viewer.addTextInputListener(fCloser);
+
+        viewer.getDocument().addDocumentListener(fDocumentListener);
+    }
+
+    /**
+     * Reveals the selection on the current target's widget, if it is valid.
+     */
+    private void showSelection() {
+        final StyledText widget= fCurrentTarget.fWidget;
+        if (widget is null || widget.isDisposed())
+            return;
+
+        // See https://bugs.eclipse.org/bugs/show_bug.cgi?id=132263
+        widget.getDisplay().asyncExec(new class()  Runnable {
+            public void run() {
+                if (!widget.isDisposed())
+                    try {
+                    widget.showSelection();
+                    } catch (IllegalArgumentException e) {
+                        /*
+                         * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=66914
+                         * if the StyledText is in setRedraw(false) mode, its
+                         * selection may not be up2date and calling showSelection
+                         * will throw an IAE.
+                         * We don't have means to find out whether the selection is valid
+                         * or whether the widget is redrawing or not therefore we try
+                         * and ignore an IAE.
+                         */
+                    }
+            }
+        });
+    }
+
+    /**
+     * Registers our auto edit vetoer with the viewer.
+     *
+     * @param viewer the viewer we want to veto ui-triggered changes within
+     *        linked positions
+     */
+    private void registerAutoEditVetoer(ITextViewer viewer) {
+        try {
+            String[] contentTypes= getContentTypes(viewer.getDocument());
+            if ( cast(ITextViewerExtension2)viewer ) {
+                ITextViewerExtension2 vExtension= (cast(ITextViewerExtension2) viewer);
+                for (int i= 0; i < contentTypes.length; i++) {
+                    vExtension.prependAutoEditStrategy(fAutoEditVetoer, contentTypes[i]);
+                }
+            } else {
+                Assert.isTrue(false);
+            }
+
+        } catch (BadPartitioningException e) {
+            leave(ILinkedModeListener.EXIT_ALL);
+        }
+    }
+
+    private void unregisterAutoEditVetoer(ITextViewer viewer) {
+        try {
+            String[] contentTypes= getContentTypes(viewer.getDocument());
+            if ( cast(ITextViewerExtension2)viewer ) {
+                ITextViewerExtension2 vExtension= (cast(ITextViewerExtension2) viewer);
+                for (int i= 0; i < contentTypes.length; i++) {
+                    vExtension.removeAutoEditStrategy(fAutoEditVetoer, contentTypes[i]);
+                }
+            } else {
+                Assert.isTrue(false);
+            }
+        } catch (BadPartitioningException e) {
+            leave(ILinkedModeListener.EXIT_ALL);
+        }
+    }
+
+    /**
+     * Returns all possible content types of <code>document</code>.
+     *
+     * @param document the document
+     * @return all possible content types of <code>document</code>
+     * @throws BadPartitioningException
+     * @since 3.1
+     */
+    private String[] getContentTypes(IDocument document)  {
+        if ( cast(IDocumentExtension3)document ) {
+            IDocumentExtension3 ext= cast(IDocumentExtension3) document;
+            String[] partitionings= ext.getPartitionings();
+            Set contentTypes= new HashSet(20);
+            for (int i= 0; i < partitionings.length; i++) {
+                contentTypes.addAll(Arrays.asList(stringcast(ext.getLegalContentTypes(partitionings[i]))));
+            }
+            contentTypes.add(IDocument.DEFAULT_CONTENT_TYPE);
+            return stringcast( contentTypes.toArray());
+        }
+        return document.getLegalContentTypes();
+    }
+
+    private void createAnnotationModel() {
+        if (fCurrentTarget.fAnnotationModel is null) {
+            LinkedPositionAnnotations lpa= new LinkedPositionAnnotations();
+            if (fSimple) {
+                lpa.markExitTarget(true);
+                lpa.markFocus(false);
+                lpa.markSlaves(false);
+                lpa.markTargets(false);
+            }
+            lpa.setTargets(fIterator.getPositions());
+            lpa.setExitTarget(fExitPosition);
+            lpa.connect(fCurrentTarget.getViewer().getDocument());
+            fCurrentTarget.fAnnotationModel= lpa;
+        }
+    }
+
+    private String getUniqueKey() {
+        return "linked.annotationmodelkey."~toString(); //$NON-NLS-1$
+    }
+
+    private void disconnect() {
+        Assert.isNotNull(fCurrentTarget);
+        ITextViewer viewer= fCurrentTarget.getViewer();
+        Assert.isNotNull(cast(Object)viewer);
+
+        viewer.getDocument().removeDocumentListener(fDocumentListener);
+
+        fAssistant.uninstall();
+        fAssistant.removeProposalListener(fProposalListener);
+
+        fCurrentTarget.fWidget= null;
+
+        Shell shell= fCurrentTarget.fShell;
+        fCurrentTarget.fShell= null;
+
+        if (shell !is null && !shell.isDisposed())
+            shell.removeShellListener(fCloser);
+
+        // this one is asymmetric: we don't install the model in
+        // connect, but leave it to its callers to ensure they
+        // have the model installed if they need it
+        uninstallAnnotationModel(fCurrentTarget);
+
+        unregisterAutoEditVetoer(viewer);
+
+        // don't remove the verify key listener to let it keep its position
+        // in the listener queue
+        if (fCurrentTarget.fKeyListener !is null)
+            fCurrentTarget.fKeyListener.setEnabled(false);
+
+        (cast(IPostSelectionProvider) viewer).removePostSelectionChangedListener(fSelectionListener);
+
+        redraw();
+    }
+
+    void leave(int flags) {
+        if (!fIsActive)
+            return;
+        fIsActive= false;
+
+        endCompoundChange();
+
+        Display display= null;
+        if (fCurrentTarget.fWidget !is null && !fCurrentTarget.fWidget.isDisposed())
+            display= fCurrentTarget.fWidget.getDisplay();
+
+        if (fCurrentTarget.fAnnotationModel !is null)
+            fCurrentTarget.fAnnotationModel.removeAllAnnotations();
+        disconnect();
+
+        for (int i= 0; i < fTargets.length; i++) {
+            LinkedModeUITarget target= fTargets[i];
+            ITextViewer viewer= target.getViewer();
+            if (target.fKeyListener !is null) {
+                (cast(ITextViewerExtension) viewer).removeVerifyKeyListener(target.fKeyListener);
+                target.fKeyListener= null;
+            }
+
+            viewer.removeTextInputListener(fCloser);
+        }
+
+        for (int i= 0; i < fTargets.length; i++) {
+
+            if (fTargets[i].fAnnotationModel !is null) {
+                fTargets[i].fAnnotationModel.removeAllAnnotations();
+                fTargets[i].fAnnotationModel.disconnect(fTargets[i].getViewer().getDocument());
+                fTargets[i].fAnnotationModel= null;
+            }
+
+            uninstallAnnotationModel(fTargets[i]);
+        }
+
+
+        if ((flags & ILinkedModeListener.UPDATE_CARET) !is 0 && fExitPosition !is null && fFramePosition !is fExitPosition && !fExitPosition.isDeleted())
+            switchPosition(fExitPosition, true, false);
+
+        final List docs= new ArrayList();
+        for (int i= 0; i < fTargets.length; i++) {
+            IDocument doc= fTargets[i].getViewer().getDocument();
+            if (doc !is null)
+                docs.add(cast(Object)doc);
+        }
+
+        fModel.stopForwarding(flags);
+
+        Runnable runnable= dgRunnable( (int flags_){
+            if (fExitPosition !is null)
+                fExitPosition.getDocument().removePosition(fExitPosition);
+
+            for (Iterator iter = docs.iterator(); iter.hasNext(); ) {
+                IDocument doc= cast(IDocument) iter.next();
+                doc.removePositionUpdater(fPositionUpdater);
+                bool uninstallCat= false;
+                String[] cats= doc.getPositionCategories();
+                for (int j= 0; j < cats.length; j++) {
+                    if (getCategory().equals(cats[j])) {
+                        uninstallCat= true;
+                        break;
+                    }
+                }
+                if (uninstallCat)
+                    try {
+                        doc.removePositionCategory(getCategory());
+                    } catch (BadPositionCategoryException e) {
+                        // ignore
+                    }
+            }
+            fModel.exit(flags_);
+        }, flags );
+
+        // remove positions (both exit positions AND linked positions in the
+        // model) asynchronously to make sure that the annotation painter
+        // gets correct document offsets.
+        if (display !is null)
+            display.asyncExec(runnable);
+        else
+            runnable.run();
+    }
+
+    private void endCompoundChange() {
+        if (fHasOpenCompoundChange) {
+            ITextViewerExtension extension= cast(ITextViewerExtension) fCurrentTarget.getViewer();
+            IRewriteTarget target= extension.getRewriteTarget();
+            target.endCompoundChange();
+            fHasOpenCompoundChange= false;
+        }
+    }
+
+    private void beginCompoundChange() {
+        if (!fHasOpenCompoundChange) {
+            ITextViewerExtension extension= cast(ITextViewerExtension) fCurrentTarget.getViewer();
+            IRewriteTarget target= extension.getRewriteTarget();
+            target.beginCompoundChange();
+            fHasOpenCompoundChange= true;
+        }
+    }
+
+    /**
+     * Returns the currently selected region or <code>null</code>.
+     *
+     * @return the currently selected region or <code>null</code>
+     */
+    public IRegion getSelectedRegion() {
+        if (fFramePosition !is null)
+            return new Region(fFramePosition.getOffset(), fFramePosition.getLength());
+        if (fExitPosition !is null)
+            return new Region(fExitPosition.getOffset(), fExitPosition.getLength());
+        return null;
+    }
+
+    private String getCategory() {
+        return toString();
+    }
+
+    /**
+     * Sets the context info property. If set to <code>true</code>, context
+     * info will be invoked on the current target's viewer whenever a position
+     * is switched.
+     *
+     * @param doContextInfo <code>true</code> if context information should be
+     *        displayed
+     */
+    public void setDoContextInfo(bool doContextInfo) {
+        fDoContextInfo= doContextInfo;
+    }
+
+    /**
+     * Sets the focus callback which will get informed when the focus of the
+     * linked mode UI changes.
+     * <p>
+     * If there is a listener installed already, it will be replaced.
+     * </p>
+     *
+     * @param listener the new listener, never <code>null</code>.
+     */
+    protected void setPositionListener(ILinkedModeUIFocusListener listener) {
+        Assert.isNotNull(cast(Object)listener);
+        fPositionListener= listener;
+    }
+
+    /**
+     * Sets the "simple" mode of the receiver. A linked mode UI in simple mode
+     * merely draws the exit position, but not the target, focus, and slave
+     * positions. Default is <code>false</code>. This method must be called
+     * before it is entered.
+     *
+     * @param simple <code>true</code> if the UI should be in simple mode.
+     */
+    public void setSimpleMode(bool simple) {
+        fSimple= simple;
+    }
+
+    /**
+     * Enables the support for colored labels in the proposal popup.
+     * <p>Completion proposals can implement {@link ICompletionProposalExtension6}
+     * to provide colored proposal labels.</p>
+     *
+     * @param isEnabled if <code>true</code> the support for colored labels is enabled in the proposal popup
+     * @since 3.4
+     */
+    public void enableColoredLabels(bool isEnabled) {
+        fIsColoredLabelsSupportEnabled= isEnabled;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/link/LinkedPosition.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.link.LinkedPosition;
+
+import dwtx.jface.text.link.LinkedModeModel; // packageimport
+import dwtx.jface.text.link.ILinkedModeListener; // packageimport
+import dwtx.jface.text.link.TabStopIterator; // packageimport
+import dwtx.jface.text.link.LinkedModeUI; // packageimport
+import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.link.LinkedPositionGroup; // packageimport
+import dwtx.jface.text.link.LinkedModeManager; // packageimport
+import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport
+import dwtx.jface.text.link.ProposalPosition; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.Position;
+
+/**
+ * A <code>Position</code> on a document that knows which document it is
+ * registered with and has a sequence number for tab stops.
+ * <p>
+ * Clients may extend this class.
+ * </p>
+ * @since 3.0
+ */
+public class LinkedPosition : Position {
+    alias Position.overlapsWith overlapsWith;
+    /** The document this position belongs to. */
+    private IDocument fDocument;
+    private int fSequenceNumber;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param document the document
+     * @param offset the offset of the position
+     * @param length the length of the position
+     * @param sequence the iteration sequence rank
+     */
+    public this(IDocument document, int offset, int length, int sequence) {
+        super(offset, length);
+        Assert.isNotNull(cast(Object)document);
+        fDocument= document;
+        fSequenceNumber= sequence;
+    }
+
+    /**
+     * Creates a new instance. Equivalent to calling
+     * <code>LinkedPosition(document, offset, length, LinkedPositionGroup.NO_STOP)</code>
+     *
+     * @param document the document
+     * @param offset the offset of the position
+     * @param length the length of the position
+     */
+    public this(IDocument document, int offset, int length) {
+        this(document, offset, length, LinkedPositionGroup.NO_STOP);
+    }
+
+    /**
+     * @return Returns the document.
+     */
+    public IDocument getDocument() {
+        return fDocument;
+    }
+
+    /*
+     * @see dwtx.jface.text.Position#equals(java.lang.Object)
+     */
+    public bool equals(Object other) {
+        if ( cast(LinkedPosition)other ) {
+            LinkedPosition p= cast(LinkedPosition) other;
+            return p.offset is offset && p.length is length && p.fDocument is fDocument;
+        }
+        return false;
+    }
+
+    /**
+     * Returns whether this position overlaps with <code>position</code>.
+     *
+     * @param position the position to check.
+     * @return <code>true</code> if this position overlaps with
+     *         <code>position</code>,<code>false</code> otherwise
+     */
+    public bool overlapsWith(LinkedPosition position) {
+        return position.getDocument() is fDocument && overlapsWith(position.getOffset(), position.getLength());
+    }
+
+    /**
+     * Returns whether this position includes <code>event</code>.
+     *
+     * @param event the event to check.
+     * @return <code>true</code> if this position includes <code>event</code>,
+     *         <code>false</code> otherwise
+     */
+    public bool includes(DocumentEvent event) {
+        return includes(event.getDocument(), event.getOffset(), event.getLength());
+    }
+
+    /**
+     * Returns whether this position includes <code>position</code>.
+     *
+     * @param position the position to check.
+     * @return <code>true</code> if this position includes
+     *         <code>position</code>,<code>false</code> otherwise
+     */
+    public bool includes(LinkedPosition position) {
+        return includes(position.getDocument(), position.getOffset(), position.getLength());
+    }
+
+    /**
+     * Overrides {@link Position#includes(int)}so every offset is considered
+     * included that lies in between the first and last offset of this position,
+     * and offsets that are right at the end of the position.
+     *
+     * @param pOffset the offset to check
+     * @return <code>true</code> if <code>pOffset</code> is in
+     *         <code>[offset, offset + length]</code>
+     */
+    public bool includes(int pOffset) {
+        return this.offset <= pOffset && pOffset <= this.offset + this.length;
+    }
+
+    /**
+     * Returns whether this position includes the range given by
+     * <code>offset</code> and <code>length</code>. A range is included by
+     * a <code>LinkedPosition</code> if {@link #includes(int) includes(offset)}
+     * returns true for every offset in the range, including the borders of the
+     * range.
+     *
+     * @param doc the document that the given range refers to, may be <code>null</code>
+     * @param off the offset of the range, referring to <code>document</code>
+     * @param len the length of the range
+     * @return <code>true</code> if <code>doc</code> is the same document as
+     *         this position refers to, and if the entire range is included in
+     *         this position
+     */
+    protected bool includes(IDocument doc, int off, int len) {
+        return doc is fDocument && off >= offset && len + off <= offset + length;
+
+    }
+
+    /**
+     * Returns the content of this position on the referenced document.
+     *
+     * @return the content of the document at this position
+     * @throws BadLocationException if the position is not valid
+     */
+    public String getContent()  {
+        return fDocument.get(offset, length);
+    }
+
+    /**
+     * Returns the sequence number of this position.
+     *
+     * @return the sequence number of this position
+     */
+    public int getSequenceNumber() {
+        return fSequenceNumber;
+    }
+
+    /**
+     * Sets the sequence number of this position.
+     *
+     * @param sequence the new sequence number
+     */
+    public void setSequenceNumber(int sequence) {
+        fSequenceNumber= sequence;
+    }
+
+    /*
+     * @see dwtx.jface.text.Position#hashCode()
+     */
+    public override hash_t toHash() {
+        alias .toHash toHash;
+        return (cast(Object)fDocument).toHash() | super.toHash() | fSequenceNumber;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/link/LinkedPositionAnnotations.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,331 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.link.LinkedPositionAnnotations;
+
+import dwtx.jface.text.link.LinkedModeModel; // packageimport
+import dwtx.jface.text.link.LinkedPosition; // packageimport
+import dwtx.jface.text.link.ILinkedModeListener; // packageimport
+import dwtx.jface.text.link.TabStopIterator; // packageimport
+import dwtx.jface.text.link.LinkedModeUI; // packageimport
+import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.link.LinkedPositionGroup; // packageimport
+import dwtx.jface.text.link.LinkedModeManager; // packageimport
+import dwtx.jface.text.link.ProposalPosition; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.source.Annotation;
+import dwtx.jface.text.source.AnnotationModel;
+
+/**
+ * Internal class.
+ *
+ * @since 3.0
+ */
+final class LinkedPositionAnnotations : AnnotationModel {
+
+    /* annotation types */
+    private static const String TARGET_ANNOTATION_TYPE= "dwtx.ui.internal.workbench.texteditor.link.target"; //$NON-NLS-1$
+    private static const String SLAVE_ANNOTATION_TYPE= "dwtx.ui.internal.workbench.texteditor.link.slave"; //$NON-NLS-1$
+    private static const String FOCUS_ANNOTATION_TYPE= "dwtx.ui.internal.workbench.texteditor.link.master"; //$NON-NLS-1$
+    private static const String EXIT_ANNOTATION_TYPE= "dwtx.ui.internal.workbench.texteditor.link.exit"; //$NON-NLS-1$
+
+    /* configuration */
+    private bool fMarkTargets= true;
+    private bool fMarkSlaves= true;
+    private bool fMarkFocus= true;
+    private bool fMarkExitTarget= true;
+
+    private Annotation fFocusAnnotation= null;
+    private Annotation fExitAnnotation= null;
+    private const Map fGroupAnnotations;
+    private const Map fTargetAnnotations;
+    private Position[] fTargets;
+    private LinkedPosition fExitPosition= null;
+
+    public this(){
+        fGroupAnnotations= new HashMap();
+        fTargetAnnotations= new HashMap();
+    }
+
+    /**
+     * Sets the position that should be highlighted as the focus position, i.e.
+     * as the position whose changes are propagated to all its linked positions
+     * by the linked environment.
+     *
+     * @param position the new focus position, or <code>null</code> if no focus is set.
+     * @throws BadLocationException if <code>position</code> is invalid
+     */
+    private void setFocusPosition(Position position)  {
+        if (fMarkFocus && getPosition(fFocusAnnotation) !is position) {
+            removeAnnotation(fFocusAnnotation, false);
+            if (position !is null) {
+                fFocusAnnotation= new Annotation(FOCUS_ANNOTATION_TYPE, false, ""); //$NON-NLS-1$
+                addAnnotation(fFocusAnnotation, position, false);
+            } else
+                fFocusAnnotation= null;
+        }
+    }
+
+    /**
+     * Sets the position that should be highlighted as the exit position, i.e.
+     * as the position whose changes are propagated to all its linked positions
+     * by the linked environment.
+     *
+     * @param position the new exit position, or <code>null</code> if no focus is set.
+     * @throws BadLocationException in case <code>position</code> is invalid
+     */
+    private void setExitPosition(Position position)  {
+        if (fMarkExitTarget && getPosition(fExitAnnotation) !is position) {
+            removeAnnotation(fExitAnnotation, false);
+            if (position !is null) {
+                fExitAnnotation= new Annotation(EXIT_ANNOTATION_TYPE, false, ""); //$NON-NLS-1$
+                addAnnotation(fExitAnnotation, position, false);
+            } else
+                fExitAnnotation= null;
+        }
+    }
+
+    /**
+     * Sets the positions that should be highlighted as the slave positions, i.e.
+     * as the positions that are linked to the focus position.
+     *
+     * @param positions the new slave positions, or <code>null</code> if no slave positions are to be set
+     * @throws BadLocationException in case any of the given positions is invalid
+     */
+    private void setGroupPositions(List positions)  {
+        if (!fMarkSlaves)
+            return;
+
+        // remove all positions which are already there
+        // Algorithm: toRemove contains all mappings at first, but all that are in
+        // positions get removed -> toRemove contains the difference set of previous - new
+        // toAdd are the new positions, which don't exist in previous = new - previous
+        List toRemove= new ArrayList(fGroupAnnotations.values());
+        Map toAdd= new HashMap();
+        if (positions !is null) {
+            for (Iterator iter= positions.iterator(); iter.hasNext();) {
+                Position p= cast(Position) iter.next();
+                if (fGroupAnnotations.containsKey(p)) {
+                    toRemove.remove(fGroupAnnotations.get(p));
+                } else {
+                    Annotation a= new Annotation(SLAVE_ANNOTATION_TYPE, false, ""); //$NON-NLS-1$
+                    toAdd.put(a, p);
+                    fGroupAnnotations.put(p, a);
+                }
+            }
+        }
+        fGroupAnnotations.values().removeAll(toRemove);
+
+        replaceAnnotations(arraycast!(Annotation)( toRemove.toArray()), toAdd, false);
+    }
+
+    /**
+     * Sets the positions that should be highlighted as the target positions, i.e.
+     * as the positions that can be jumped to in a linked set up.
+     *
+     * @param positions the new target positions, or <code>null</code> if no target positions are to be set
+     * @throws BadLocationException in case any of the given positions is invalid
+     */
+    private void setTargetPositions(List positions)  {
+        if (!fMarkTargets)
+            return;
+
+        // remove all positions which are already there
+        // Algorithm: toRemove contains all mappings at first, but all that are in
+        // positions get removed -> toRemove contains the difference set of previous - new
+        // toAdd are the new positions, which don't exist in previous = new - previous
+        List toRemove= new ArrayList(fTargetAnnotations.values());
+        Map toAdd= new HashMap();
+        if (positions !is null) {
+            for (Iterator iter= positions.iterator(); iter.hasNext();) {
+                Position p= cast(Position) iter.next();
+                if (fTargetAnnotations.containsKey(p)) {
+                    toRemove.remove(fTargetAnnotations.get(p));
+                } else {
+                    Annotation a= new Annotation(TARGET_ANNOTATION_TYPE, false, ""); //$NON-NLS-1$
+                    toAdd.put(a, p);
+                    fTargetAnnotations.put(p, a);
+                }
+            }
+        }
+        fTargetAnnotations.values().removeAll(toRemove);
+
+        replaceAnnotations(arraycast!(Annotation)( toRemove.toArray()), toAdd, false);
+    }
+
+    /**
+     * Switches the focus position to <code>position</code> given the
+     * <code>LinkedModeModel env</code>. The slave positions for <code>position</code>
+     * is extracted from the environment and set accordingly, the target positions
+     * are updated as well.
+     *
+     * @param env
+     * @param position
+     */
+    public void switchToPosition(LinkedModeModel env, LinkedPosition position) {
+        if (fDocument is null ||
+                (position !is null && getPosition(fFocusAnnotation) is position) ||
+                (position is null && fFocusAnnotation is null))
+            return;
+
+        LinkedPositionGroup linkedGroup= null;
+        if (position !is null)
+            linkedGroup= env.getGroupForPosition(position);
+
+        List targets= new ArrayList();
+        targets.addAll(Arrays.asList(fTargets));
+
+        List group;
+        if (linkedGroup !is null)
+            group= new ArrayList(Arrays.asList(linkedGroup.getPositions()));
+        else
+            group= new ArrayList();
+
+        if (position is null || !(cast(Object)fDocument).opEquals(cast(Object)position.getDocument()))
+            // position is not valid if not in this document
+            position= null;
+
+        LinkedPosition exit= fExitPosition;
+        if (exit is null || !(cast(Object)fDocument).opEquals(cast(Object)exit.getDocument()))
+            // position is not valid if not in this document
+            exit= null;
+
+
+        if (exit !is null) {
+            group.remove(exit);
+            targets.remove(exit);
+        }
+
+        group.removeAll(targets);
+        targets.remove(position);
+        group.remove(position);
+        prune(targets);
+        prune(group);
+
+        try {
+            setFocusPosition(position);
+            setExitPosition(exit);
+            setGroupPositions(group);
+            setTargetPositions(targets);
+        } catch (BadLocationException e) {
+            // will never happen as we don't actually add/remove positions from the document
+            // see the addPosition / removePosition methods
+            Assert.isTrue(false);
+        }
+        fireModelChanged();
+
+    }
+
+    /**
+     * Prune <code>list</code> of all <code>LinkedPosition</code>s that
+     * do not belong to this model's <code>IDocument</code>.
+     *
+     * @param list the list of positions to prune
+     */
+    private void prune(List list) {
+        for (Iterator iter= list.iterator(); iter.hasNext();) {
+            LinkedPosition pos= cast(LinkedPosition) iter.next();
+            if (!(cast(Object)pos.getDocument()).opEquals(cast(Object)fDocument))
+                iter.remove();
+        }
+    }
+
+    /**
+     * Sets the target positions
+     * @param positions
+     */
+    public void setTargets(Position[] positions) {
+        fTargets= positions;
+    }
+
+    /**
+     * Sets the exit position.
+     *
+     * @param position the new exit position, or <code>null</code> if no exit position should be set
+     */
+    public void setExitTarget(LinkedPosition position) {
+        fExitPosition = position;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.AnnotationModel#addPosition(dwtx.jface.text.IDocument, dwtx.jface.text.Position)
+     */
+    protected void addPosition(IDocument document, Position position) {
+        // don't to anything as our positions are managed by custom
+        // position updaters
+    }
+
+    /*
+     * @see dwtx.jface.text.source.AnnotationModel#removePosition(dwtx.jface.text.IDocument, dwtx.jface.text.Position)
+     */
+    protected void removePosition(IDocument document, Position pos) {
+        // don't to anything as our positions are managed by custom
+        // position updaters
+    }
+
+    /*
+     * @see dwtx.jface.text.source.AnnotationModel#fireModelChanged()
+     */
+    public void fireModelChanged() {
+        super.fireModelChanged();
+    }
+
+    /**
+     * Sets the drawing state for the exit target. Default is <code>true</code>.
+     *
+     * @param markExitTargets the new drawing state for exit targets
+     */
+    public void markExitTarget(bool markExitTargets) {
+        fMarkExitTarget= markExitTargets;
+    }
+
+    /**
+     * Sets the drawing state for the focus position. Default is <code>true</code>.
+     *
+     * @param markFocus the new drawing state for exit targets
+     */
+    public void markFocus(bool markFocus) {
+        fMarkFocus= markFocus;
+    }
+
+    /**
+     * Sets the drawing state for slave positions. Default is <code>true</code>.
+     *
+     * @param markSlaves the new drawing state for slaves
+     */
+    public void markSlaves(bool markSlaves) {
+        fMarkSlaves= markSlaves;
+    }
+
+    /**
+     * Sets the drawing state for targets. Default is <code>true</code>.
+     *
+     * @param markTargets the new drawing state for targets
+     */
+    public void markTargets(bool markTargets) {
+        fMarkTargets= markTargets;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/link/LinkedPositionGroup.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,429 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.link.LinkedPositionGroup;
+
+import dwtx.jface.text.link.LinkedModeModel; // packageimport
+import dwtx.jface.text.link.LinkedPosition; // packageimport
+import dwtx.jface.text.link.ILinkedModeListener; // packageimport
+import dwtx.jface.text.link.TabStopIterator; // packageimport
+import dwtx.jface.text.link.LinkedModeUI; // packageimport
+import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.link.LinkedModeManager; // packageimport
+import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport
+import dwtx.jface.text.link.ProposalPosition; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.text.convert.Format;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.text.edits.MalformedTreeException;
+import dwtx.text.edits.MultiTextEdit;
+import dwtx.text.edits.ReplaceEdit;
+import dwtx.text.edits.TextEdit;
+
+/**
+ * A group of positions in multiple documents that are simultaneously modified -
+ * if one gets edited, all other positions in a group are edited the same way.
+ * All linked positions in a group have the same content.
+ * <p>
+ * Normally, new positions are given a tab stop weight which can be used by
+ * clients, e.g. the UI. If no weight is given, a position will not be visited.
+ * If no weights are used at all, the first position in a document is taken as
+ * the only stop as to comply with the behavior of the old linked position
+ * infrastructure.
+ * </p>
+ * <p>
+ * Clients may instantiate this class.
+ * </p>
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class LinkedPositionGroup {
+
+    /** Sequence constant declaring that a position should not be stopped by. */
+    public static const int NO_STOP= -1;
+
+    /* members */
+
+    /** The linked positions of this group. */
+    private const List fPositions;
+    /** Whether we are sealed or not. */
+    private bool fIsSealed= false;
+    /**
+     * <code>true</code> if there are custom iteration weights. For backward
+     * compatibility.
+     */
+    private bool fHasCustomIteration= false;
+
+    /*
+     * iteration variables, set to communicate state between isLegalEvent and
+     * handleEvent
+     */
+    /** The position including the most recent <code>DocumentEvent</code>. */
+    private LinkedPosition fLastPosition;
+    /** The region covered by <code>fLastPosition</code> before the document
+     * change.
+     */
+    private IRegion fLastRegion;
+
+    this(){
+        fPositions= new LinkedList();
+    }
+
+    /**
+     * Adds a position to this group. The document region defined by the
+     * position must contain the same content (and thus have the same length) as
+     * any of the other positions already in this group. Additionally, all
+     * positions added must be disjoint; otherwise a
+     * <code>BadLocationException</code> is thrown.
+     * <p>
+     * Positions added using this method are owned by this group afterwards and
+     * may not be updated or modified thereafter.
+     * </p>
+     * <p>
+     * Once a group has been added to a <code>LinkedModeModel</code>, it
+     * becomes <em>sealed</em> and no positions may be added any more.
+     * </p>
+     *
+     * @param position the position to add
+     * @throws BadLocationException if the position is invalid or conflicts with
+     *         other positions in the group
+     * @throws IllegalStateException if the group has already been added to a
+     *         model
+     */
+    public void addPosition(LinkedPosition position)  {
+        /*
+         * Enforces constraints and sets the custom iteration flag. If the
+         * position is already in this group, nothing happens.
+         */
+        Assert.isNotNull(position);
+        if (fIsSealed)
+            throw new IllegalStateException("cannot add positions after the group is added to an model"); //$NON-NLS-1$
+
+        if (!fPositions.contains(position)) {
+            enforceDisjoint(position);
+            enforceEqualContent(position);
+            fPositions.add(position);
+            fHasCustomIteration |= position.getSequenceNumber() !is LinkedPositionGroup.NO_STOP;
+        } else
+            return; // nothing happens
+    }
+
+    /**
+     * Enforces the invariant that all positions must contain the same string.
+     *
+     * @param position the position to check
+     * @throws BadLocationException if the equal content check fails
+     */
+    private void enforceEqualContent(LinkedPosition position)  {
+        if (fPositions.size() > 0) {
+            LinkedPosition groupPosition= cast(LinkedPosition) fPositions.get(0);
+            String groupContent= groupPosition.getContent();
+            String positionContent= position.getContent();
+            if (!groupContent.equals(positionContent))
+                throw new BadLocationException(Format( "First position: '{}' at {}, this position: '{}' at {}",
+                        groupContent, groupPosition.getOffset(), //$NON-NLS-1$ //$NON-NLS-2$
+                        positionContent, position.getOffset())); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+    }
+
+    /**
+     * Enforces the invariant that all positions must be disjoint.
+     *
+     * @param position the position to check
+     * @throws BadLocationException if the disjointness check fails
+     */
+    private void enforceDisjoint(LinkedPosition position)  {
+        for (Iterator it= fPositions.iterator(); it.hasNext(); ) {
+            LinkedPosition p= cast(LinkedPosition) it.next();
+            if (p.overlapsWith(position))
+                throw new BadLocationException();
+        }
+    }
+
+    /**
+     * Enforces the disjointness for another group
+     *
+     * @param group the group to check
+     * @throws BadLocationException if the disjointness check fails
+     */
+    void enforceDisjoint(LinkedPositionGroup group)  {
+        Assert.isNotNull(group);
+        for (Iterator it= group.fPositions.iterator(); it.hasNext(); ) {
+            LinkedPosition p= cast(LinkedPosition) it.next();
+            enforceDisjoint(p);
+        }
+    }
+
+    /**
+     * Checks whether <code>event</code> is a legal event for this group. An
+     * event is legal if it touches at most one position contained within this
+     * group.
+     *
+     * @param event the document event to check
+     * @return <code>true</code> if <code>event</code> is legal
+     */
+    bool isLegalEvent(DocumentEvent event) {
+        fLastPosition= null;
+        fLastRegion= null;
+
+        for (Iterator it= fPositions.iterator(); it.hasNext(); ) {
+            LinkedPosition pos= cast(LinkedPosition) it.next();
+            if (overlapsOrTouches(pos, event)) {
+                if (fLastPosition !is null) {
+                    fLastPosition= null;
+                    fLastRegion= null;
+                    return false;
+                }
+
+                fLastPosition= pos;
+                fLastRegion= new Region(pos.getOffset(), pos.getLength());
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Checks whether the given event touches the given position. To touch means
+     * to overlap or come up to the borders of the position.
+     *
+     * @param position the position
+     * @param event the event
+     * @return <code>true</code> if <code>position</code> and
+     *         <code>event</code> are not absolutely disjoint
+     * @since 3.1
+     */
+    private bool overlapsOrTouches(LinkedPosition position, DocumentEvent event) {
+        return (cast(Object)position.getDocument()).opEquals(cast(Object)event.getDocument()) && position.getOffset() <= event.getOffset() + event.getLength() && position.getOffset() + position.getLength() >= event.getOffset();
+    }
+
+    /**
+     * Creates an edition of a document change that will forward any
+     * modification in one position to all linked siblings. The return value is
+     * a map from <code>IDocument</code> to <code>TextEdit</code>.
+     *
+     * @param event the document event to check
+     * @return a map of edits, grouped by edited document, or <code>null</code>
+     *         if there are no edits
+     */
+    Map handleEvent(DocumentEvent event) {
+
+        if (fLastPosition !is null) {
+
+            Map map= new HashMap();
+
+
+            int relativeOffset= event.getOffset() - fLastRegion.getOffset();
+            if (relativeOffset < 0) {
+                relativeOffset= 0;
+            }
+
+            int eventEnd= event.getOffset() + event.getLength();
+            int lastEnd= fLastRegion.getOffset() + fLastRegion.getLength();
+            int length;
+            if (eventEnd > lastEnd)
+                length= lastEnd - relativeOffset - fLastRegion.getOffset();
+            else
+                length= eventEnd - relativeOffset - fLastRegion.getOffset();
+
+            String text= event.getText();
+            if (text is null)
+                text= ""; //$NON-NLS-1$
+
+            for (Iterator it= fPositions.iterator(); it.hasNext(); ) {
+                LinkedPosition p= cast(LinkedPosition) it.next();
+                if (p is fLastPosition || p.isDeleted())
+                    continue; // don't re-update the origin of the change
+
+                List edits= cast(List) map.get(cast(Object)p.getDocument());
+                if (edits is null) {
+                    edits= new ArrayList();
+                    map.put(cast(Object)p.getDocument(), cast(Object)edits);
+                }
+
+                edits.add(new ReplaceEdit(p.getOffset() + relativeOffset, length, text));
+            }
+
+            try {
+                for (Iterator it= map.keySet().iterator(); it.hasNext();) {
+                    IDocument d= cast(IDocument) it.next();
+                    TextEdit edit= new MultiTextEdit(0, d.getLength());
+                    edit.addChildren(arraycast!(TextEdit)( (cast(List) map.get(cast(Object)d)).toArray()));
+                    map.put(cast(Object)d, edit);
+                }
+
+                return map;
+            } catch (MalformedTreeException x) {
+                // may happen during undo, as LinkedModeModel does not know
+                // that the changes technically originate from a parent environment
+                // if this happens, post notification changes are not accepted anyway and
+                // we can simply return null - any changes will be undone by the undo
+                // manager
+                return null;
+            }
+
+        }
+
+        return null;
+    }
+
+    /**
+     * Sets the model of this group. Once a model has been set, no
+     * more positions can be added and the model cannot be changed.
+     */
+    void seal() {
+        Assert.isTrue(!fIsSealed);
+        fIsSealed= true;
+
+        if (fHasCustomIteration is false && fPositions.size() > 0) {
+            (cast(LinkedPosition) fPositions.get(0)).setSequenceNumber(0);
+        }
+    }
+
+    IDocument[] getDocuments() {
+        IDocument[] docs= new IDocument[fPositions.size()];
+        int i= 0;
+        for (Iterator it= fPositions.iterator(); it.hasNext(); i++) {
+            LinkedPosition pos= cast(LinkedPosition) it.next();
+            docs[i]= pos.getDocument();
+        }
+        return docs;
+    }
+
+    void register(LinkedModeModel model)  {
+        for (Iterator it= fPositions.iterator(); it.hasNext(); ) {
+            LinkedPosition pos= cast(LinkedPosition) it.next();
+            model.register(pos);
+        }
+    }
+
+    /**
+     * Returns the position in this group that encompasses all positions in
+     * <code>group</code>.
+     *
+     * @param group the group to be adopted
+     * @return a position in the receiver that contains all positions in <code>group</code>,
+     *         or <code>null</code> if none can be found
+     * @throws BadLocationException if more than one position are affected by
+     *         <code>group</code>
+     */
+    LinkedPosition adopt(LinkedPositionGroup group)  {
+        LinkedPosition found= null;
+        for (Iterator it= group.fPositions.iterator(); it.hasNext(); ) {
+            LinkedPosition pos= cast(LinkedPosition) it.next();
+            LinkedPosition localFound= null;
+            for (Iterator it2= fPositions.iterator(); it2.hasNext(); ) {
+                LinkedPosition myPos= cast(LinkedPosition) it2.next();
+                if (myPos.includes(pos)) {
+                    if (found is null)
+                        found= myPos;
+                    else if (found !is myPos)
+                        throw new BadLocationException();
+                    if (localFound is null)
+                        localFound= myPos;
+                }
+            }
+
+            if (localFound !is found)
+                throw new BadLocationException();
+        }
+        return found;
+    }
+
+    /**
+     * Finds the closest position to <code>toFind</code>.
+     *
+     * @param toFind the linked position for which to find the closest position
+     * @return the closest position to <code>toFind</code>.
+     */
+    LinkedPosition getPosition(LinkedPosition toFind) {
+        for (Iterator it= fPositions.iterator(); it.hasNext(); ) {
+            LinkedPosition p= cast(LinkedPosition) it.next();
+            if (p.includes(toFind))
+                return p;
+        }
+        return null;
+    }
+
+    /**
+     * Returns <code>true</code> if <code>offset</code> is contained in any
+     * position in this group.
+     *
+     * @param offset the offset to check
+     * @return <code>true</code> if offset is contained by this group
+     */
+    bool contains(int offset) {
+        for (Iterator it= fPositions.iterator(); it.hasNext(); ) {
+            LinkedPosition pos= cast(LinkedPosition) it.next();
+            if (pos.includes(offset)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns whether this group contains any positions.
+     *
+     * @return <code>true</code> if this group is empty, <code>false</code> otherwise
+     * @since 3.1
+     */
+    public bool isEmpty() {
+        return fPositions.size() is 0;
+    }
+
+    /**
+     * Returns whether this group contains any positions.
+     *
+     * @return <code>true</code> if this group is empty, <code>false</code> otherwise
+     * @deprecated As of 3.1, replaced by {@link #isEmpty()}
+     */
+    public bool isEmtpy() {
+        return isEmpty();
+    }
+
+    /**
+     * Returns the positions contained in the receiver as an array. The
+     * positions are the actual positions and must not be modified; the array
+     * is a copy of internal structures.
+     *
+     * @return the positions of this group in no particular order
+     */
+    public LinkedPosition[] getPositions() {
+        return arraycast!(LinkedPosition) (fPositions.toArray());
+    }
+
+    /**
+     * Returns <code>true</code> if the receiver contains <code>position</code>.
+     *
+     * @param position the position to check
+     * @return <code>true</code> if the receiver contains <code>position</code>
+     */
+    bool contains(Position position) {
+        for (Iterator it= fPositions.iterator(); it.hasNext(); ) {
+            LinkedPosition p= cast(LinkedPosition) it.next();
+            if (position.opEquals(p))
+                return true;
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/link/ProposalPosition.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.link.ProposalPosition;
+
+import dwtx.jface.text.link.LinkedModeModel; // packageimport
+import dwtx.jface.text.link.LinkedPosition; // packageimport
+import dwtx.jface.text.link.ILinkedModeListener; // packageimport
+import dwtx.jface.text.link.TabStopIterator; // packageimport
+import dwtx.jface.text.link.LinkedModeUI; // packageimport
+import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.link.LinkedPositionGroup; // packageimport
+import dwtx.jface.text.link.LinkedModeManager; // packageimport
+import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.contentassist.ICompletionProposal;
+
+/**
+ * LinkedPosition with added completion proposals.
+ * <p>
+ * Clients may instantiate or extend this class.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class ProposalPosition : LinkedPosition {
+
+    /**
+     * The proposals
+     */
+    private ICompletionProposal[] fProposals;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param document the document
+     * @param offset the offset of the position
+     * @param length the length of the position
+     * @param sequence the iteration sequence rank
+     * @param proposals the proposals to be shown when entering this position
+     */
+    public this(IDocument document, int offset, int length, int sequence, ICompletionProposal[] proposals) {
+        super(document, offset, length, sequence);
+        fProposals= copy(proposals);
+    }
+
+    /**
+     * Creates a new instance, with no sequence number.
+     *
+     * @param document the document
+     * @param offset the offset of the position
+     * @param length the length of the position
+     * @param proposals the proposals to be shown when entering this position
+     */
+    public this(IDocument document, int offset, int length, ICompletionProposal[] proposals) {
+        super(document, offset, length, LinkedPositionGroup.NO_STOP);
+        fProposals= copy(proposals);
+    }
+
+    /*
+     * @since 3.1
+     */
+    private ICompletionProposal[] copy(ICompletionProposal[] proposals) {
+        if (proposals !is null) {
+            ICompletionProposal[] copy= new ICompletionProposal[proposals.length];
+            SimpleType!(ICompletionProposal).arraycopy(proposals, 0, copy, 0, proposals.length);
+            return copy;
+        }
+        return null;
+    }
+
+    /*
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public override int opEquals(Object o) {
+        if ( cast(ProposalPosition)o ) {
+            if (super.opEquals(o)) {
+                return Arrays.equals(fProposals, (cast(ProposalPosition)o).fProposals);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns the proposals attached to this position. The returned array is owned by
+     * this <code>ProposalPosition</code> and may not be modified by clients.
+     *
+     * @return an array of choices, including the initial one. Callers must not
+     *         modify it.
+     */
+    public ICompletionProposal[] getChoices() {
+        return fProposals;
+    }
+
+    /*
+     * @see dwtx.jdt.internal.ui.text.link.LinkedPosition#hashCode()
+     */
+    public override hash_t toHash() {
+        return super.toHash() | (fProposals is null ? 0 : (cast(hash_t)fProposals.ptr)/+.toHash()+/);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/link/TabStopIterator.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,234 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.link.TabStopIterator;
+
+import dwtx.jface.text.link.LinkedModeModel; // packageimport
+import dwtx.jface.text.link.LinkedPosition; // packageimport
+import dwtx.jface.text.link.ILinkedModeListener; // packageimport
+import dwtx.jface.text.link.LinkedModeUI; // packageimport
+import dwtx.jface.text.link.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.link.LinkedPositionGroup; // packageimport
+import dwtx.jface.text.link.LinkedModeManager; // packageimport
+import dwtx.jface.text.link.LinkedPositionAnnotations; // packageimport
+import dwtx.jface.text.link.ProposalPosition; // packageimport
+
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.core.Exception;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.Position;
+
+
+
+/**
+ * Iterator that leaps over the double occurrence of an element when switching from forward
+ * to backward iteration that is shown by <code>ListIterator</code>.
+ * <p>
+ * Package private, only for use by LinkedModeUI.
+ * </p>
+ * @since 3.0
+ */
+class TabStopIterator {
+    /**
+     * Comparator for <code>LinkedPosition</code>s. If the sequence number of two positions is equal, the
+     * offset is used.
+     */
+    private static class SequenceComparator : Comparator {
+
+        /**
+         * {@inheritDoc}
+         *
+         * <p><code>o1</code> and <code>o2</code> are required to be instances
+         * of <code>LinkedPosition</code>.</p>
+         */
+        public int compare(Object o1, Object o2) {
+            LinkedPosition p1= cast(LinkedPosition)o1;
+            LinkedPosition p2= cast(LinkedPosition)o2;
+            int i= p1.getSequenceNumber() - p2.getSequenceNumber();
+            if (i !is 0)
+                return i;
+            return p1.getOffset() - p2.getOffset();
+        }
+
+    }
+
+    /** The comparator to sort the list of positions. */
+    private static Comparator fComparator_;
+    private static Comparator fComparator(){
+        if( fComparator_ is null ){
+            synchronized( TabStopIterator.classinfo ){
+                if( fComparator_ is null ){
+                    fComparator_ = new SequenceComparator();
+                }
+            }
+        }
+        return fComparator_;
+    }
+
+    /** The iteration sequence. */
+    private const ArrayList fList;
+    /** The size of <code>fList</code>. */
+    private int fSize;
+    /** Index of the current element, to the first one initially. */
+    private int fIndex;
+    /** Cycling property. */
+    private bool fIsCycling= false;
+
+    this(List positionSequence) {
+        Assert.isNotNull(cast(Object)positionSequence);
+        fList= new ArrayList(positionSequence);
+        Collections.sort(fList, fComparator);
+        fSize= fList.size();
+        fIndex= -1;
+        Assert.isTrue(fSize > 0);
+    }
+
+    bool hasNext(LinkedPosition current) {
+        return getNextIndex(current) !is fSize;
+    }
+
+    private int getNextIndex(LinkedPosition current) {
+        if (current !is null && fList.get(fIndex) !is current)
+            return findNext(current);
+        else if (fIsCycling && fIndex is fSize - 1)
+            return 0;
+        else
+            // default: increase
+            return fIndex + 1;
+    }
+
+    /**
+     * Finds the closest position in the iteration set that follows after
+     * <code>current</code> and sets <code>fIndex</code> accordingly. If <code>current</code>
+     * is in the iteration set, the next in turn is chosen.
+     *
+     * @param current the current position
+     * @return <code>true</code> if there is a next position, <code>false</code> otherwise
+     */
+    private int findNext(LinkedPosition current) {
+        Assert.isNotNull(current);
+        // if the position is in the iteration set, jump to the next one
+        int index= fList.indexOf(current);
+        if (index !is -1) {
+            if (fIsCycling && index is fSize - 1)
+                return 0;
+            return index + 1;
+        }
+
+        // index is -1
+
+        // find the position that follows closest to the current position
+        LinkedPosition found= null;
+        for (Iterator it= fList.iterator(); it.hasNext(); ) {
+            LinkedPosition p= cast(LinkedPosition) it.next();
+            if (p.offset > current.offset)
+                if (found is null || found.offset > p.offset)
+                    found= p;
+        }
+
+        if (found !is null) {
+            return fList.indexOf(found);
+        } else if (fIsCycling) {
+            return 0;
+        } else
+            return fSize;
+    }
+
+    bool hasPrevious(LinkedPosition current) {
+        return getPreviousIndex(current) !is -1;
+    }
+
+    private int getPreviousIndex(LinkedPosition current) {
+        if (current !is null && fList.get(fIndex) !is current)
+            return findPrevious(current);
+        else if (fIsCycling && fIndex is 0)
+            return fSize - 1;
+        else
+            return fIndex - 1;
+    }
+
+    /**
+     * Finds the closest position in the iteration set that precedes
+     * <code>current</code>. If <code>current</code>
+     * is in the iteration set, the previous in turn is chosen.
+     *
+     * @param current the current position
+     * @return the index of the previous position
+     */
+    private int findPrevious(LinkedPosition current) {
+        Assert.isNotNull(current);
+        // if the position is in the iteration set, jump to the next one
+        int index= fList.indexOf(current);
+        if (index !is -1) {
+            if (fIsCycling && index is 0)
+                return fSize - 1;
+            return index - 1;
+        }
+
+        // index is -1
+
+        // find the position that follows closest to the current position
+        LinkedPosition found= null;
+        for (Iterator it= fList.iterator(); it.hasNext(); ) {
+            LinkedPosition p= cast(LinkedPosition) it.next();
+            if (p.offset < current.offset)
+                if (found is null || found.offset < p.offset)
+                    found= p;
+        }
+        if (found !is null) {
+            return fList.indexOf(found);
+        } else if (fIsCycling) {
+            return fSize - 1;
+        } else
+            return -1;
+    }
+
+    LinkedPosition next(LinkedPosition current) {
+        if (!hasNext(current))
+            throw new NoSuchElementException(null);
+        return cast(LinkedPosition) fList.get(fIndex= getNextIndex(current));
+    }
+
+    LinkedPosition previous(LinkedPosition current) {
+        if (!hasPrevious(current))
+            throw new NoSuchElementException(null);
+        return cast(LinkedPosition) fList.get(fIndex= getPreviousIndex(current));
+    }
+
+    void setCycling(bool mode) {
+        fIsCycling= mode;
+    }
+
+    void addPosition(Position position) {
+        fList.add(fSize++, position);
+        Collections.sort(fList, fComparator);
+    }
+
+    void removePosition(Position position) {
+        if (fList.remove(position))
+            fSize--;
+    }
+
+    /**
+     * @return Returns the isCycling.
+     */
+    bool isCycling() {
+        return fIsCycling;
+    }
+
+    LinkedPosition[] getPositions() {
+        return arraycast!(LinkedPosition)( fList.toArray());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/presentation/IPresentationDamager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.presentation.IPresentationDamager;
+
+import dwtx.jface.text.presentation.IPresentationReconciler; // packageimport
+import dwtx.jface.text.presentation.PresentationReconciler; // packageimport
+import dwtx.jface.text.presentation.IPresentationRepairer; // packageimport
+import dwtx.jface.text.presentation.IPresentationReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITypedRegion;
+
+
+/**
+ * A presentation damager is a strategy used by a presentation reconciler to
+ * determine the region of the document's presentation which must be rebuilt
+ * because of a document change. A presentation damager is assumed to be
+ * specific for a particular document content type. A presentation damager is
+ * expected to return a damage region which is a valid input for a presentation
+ * repairer. I.e. having access to the damage region only the repairer must be
+ * able to derive all the information needed to successfully repair this region.
+ * <p>
+ * This interface must either be implemented by clients or clients use the
+ * rule-based default implementation
+ * {@link dwtx.jface.text.rules.DefaultDamagerRepairer}. Implementers
+ * should be registered with a presentation reconciler in order get involved in
+ * the reconciling process.</p>
+ *
+ * @see IPresentationReconciler
+ * @see IDocument
+ * @see DocumentEvent
+ * @see IPresentationRepairer
+ */
+public interface IPresentationDamager {
+
+    /**
+     * Tells the presentation damager on which document it will work.
+     *
+     * @param document the damager's working document
+     */
+    void setDocument(IDocument document);
+
+    /**
+     * Returns the damage in the document's presentation caused by the given document change.
+     * The damage is restricted to the specified partition for which the presentation damager is
+     * responsible. The damage may also depend on whether the document change also caused changes
+     * of the document's partitioning.
+     *
+     * @param partition the partition inside which the damage must be determined
+     * @param event the event describing the change whose damage must be determined
+     * @param documentPartitioningChanged indicates whether the given change changed the document's partitioning
+     * @return the computed damage
+     */
+    IRegion getDamageRegion(ITypedRegion partition, DocumentEvent event, bool documentPartitioningChanged);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/presentation/IPresentationReconciler.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.presentation.IPresentationReconciler;
+
+import dwtx.jface.text.presentation.IPresentationDamager; // packageimport
+import dwtx.jface.text.presentation.PresentationReconciler; // packageimport
+import dwtx.jface.text.presentation.IPresentationRepairer; // packageimport
+import dwtx.jface.text.presentation.IPresentationReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * An <code>IPresentationReconciler</code> defines and maintains the
+ * representation of a text viewer's document in the presence of changes applied
+ * to the document. An <code>IPresentationReconciler</code> is a
+ * <code>ITextViewer</code> add-on.
+ * <p>
+ * The presentation reconciler keeps track of changes applied to the text
+ * viewer. It sends each change to presentation damagers which are registered
+ * for the content types of the regions in which the change occurred. The
+ * presentation reconciler passes the computed damage to presentation repairer
+ * which construct text presentations. When applied to the presentation
+ * reconciler's text viewer, those text presentations bring the document's
+ * presentation in sync with the document's content and thus repair the damage.
+ * A presentation damager is expected to return damage which is a valid input
+ * for a presentation repairer registered for the same content type as the
+ * damager.
+ * </p>
+ * <p>
+ * A presentation reconciler should always be configured with a pair of
+ * damager/repairer strategies. I.e. for each damager there should be a
+ * corresponding repairer.
+ * </p>
+ * <p>
+ * The interface may be implemented by clients. Clients may use
+ * <code>PresentationReconciler</code> as the standard implementation of this
+ * interface.
+ * </p>
+ * <p>
+ * In order to provided backward compatibility for clients of
+ * <code>IPresentationReconciler</code>, extension interfaces are used to
+ * provide a means of evolution. The following extension interface exists:
+ * <ul>
+ * <li>
+ * {@link dwtx.jface.text.presentation.IPresentationReconcilerExtension}
+ * since version 3.0 adding support for documents with multiple partitionings.
+ * </li>
+ * </ul>
+ * </p>
+ *
+ * @see dwtx.jface.text.presentation.IPresentationReconcilerExtension
+ * @see dwtx.jface.text.ITextViewer
+ * @see dwtx.jface.text.presentation.IPresentationDamager
+ * @see dwtx.jface.text.presentation.IPresentationRepairer
+ * @see dwtx.jface.text.TextPresentation
+ */
+public interface IPresentationReconciler {
+
+    /**
+     * Installs this presentation reconciler on the given text viewer. After
+     * this method has been finished, the reconciler is operational. I.e., it
+     * works without requesting further client actions until
+     * <code>uninstall</code> is called.
+     * <p>
+     * The <code>install</code> and <code>uninstall</code> methods must be
+     * called in sequence; i.e. repeatedly calling <code>install</code>
+     * without calling <code>uninstall</code> may throw an exception.
+     * </p>
+     *
+     * @param viewer the viewer on which this presentation reconciler is
+     *        installed
+     */
+    void install(ITextViewer viewer);
+
+    /**
+     * Removes the reconciler from the text viewer it has previously been
+     * installed on.
+     */
+    void uninstall();
+
+    /**
+     * Returns the presentation damager registered with this presentation reconciler
+     * for the specified content type.
+     *
+     * @param contentType the content type for which to determine the damager
+     * @return the presentation damager registered for the given content type, or
+     *      <code>null</code> if there is no damager
+     */
+    IPresentationDamager getDamager(String contentType);
+
+    /**
+     * Returns the presentation repairer registered with this presentation reconciler
+     * for the specified content type.
+     *
+     * @param contentType the content type for which to determine the repairer
+     * @return the presentation repairer registered for the given content type, or
+     *      <code>null</code> if there is no repairer
+     */
+    IPresentationRepairer getRepairer(String contentType);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/presentation/IPresentationReconcilerExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.presentation.IPresentationReconcilerExtension;
+
+import dwtx.jface.text.presentation.IPresentationDamager; // packageimport
+import dwtx.jface.text.presentation.IPresentationReconciler; // packageimport
+import dwtx.jface.text.presentation.PresentationReconciler; // packageimport
+import dwtx.jface.text.presentation.IPresentationRepairer; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link IPresentationReconciler}. Adds awareness of
+ * documents with multiple partitions.
+ *
+ * @since 3.0
+ */
+public interface IPresentationReconcilerExtension {
+
+    /**
+     * Returns the document partitioning this presentation reconciler is using.
+     *
+     * @return the document partitioning this presentation reconciler is using
+     */
+    String getDocumentPartitioning();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/presentation/IPresentationRepairer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.presentation.IPresentationRepairer;
+
+import dwtx.jface.text.presentation.IPresentationDamager; // packageimport
+import dwtx.jface.text.presentation.IPresentationReconciler; // packageimport
+import dwtx.jface.text.presentation.PresentationReconciler; // packageimport
+import dwtx.jface.text.presentation.IPresentationReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.ITypedRegion;
+import dwtx.jface.text.TextPresentation;
+
+
+/**
+ * A presentation repairer is a strategy used by a presentation reconciler to
+ * rebuild a damaged region in a document's presentation. A presentation
+ * repairer is assumed to be specific for a particular document content type.
+ * The presentation repairer gets the region which it should repair and
+ * constructs a "repair description". The presentation repairer merges the steps
+ * contained within this description into the text presentation passed into
+ * <code>createPresentation</code>.
+ * <p>
+ * This interface may be implemented by clients. Alternatively, clients may use
+ * the rule-based default implementation
+ * {@link dwtx.jface.text.rules.DefaultDamagerRepairer}. Implementers
+ * should be registered with a presentation reconciler in order get involved in
+ * the reconciling process.
+ * </p>
+ *
+ * @see IPresentationReconciler
+ * @see IDocument
+ * @see dwt.custom.StyleRange
+ * @see TextPresentation
+ */
+public interface IPresentationRepairer {
+
+
+    /**
+     * Tells the presentation repairer on which document it will work.
+     *
+     * @param document the damager's working document
+     */
+    void setDocument(IDocument document);
+
+    /**
+     * Fills the given presentation with the style ranges which when applied to the
+     * presentation reconciler's text viewer repair the  presentation damage described by
+     * the given region.
+     *
+     * @param presentation the text presentation to be filled by this repairer
+     * @param damage the damage to be repaired
+     */
+    void createPresentation(TextPresentation presentation, ITypedRegion damage);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/presentation/PresentationReconciler.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,603 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.presentation.PresentationReconciler;
+
+import dwtx.jface.text.presentation.IPresentationDamager; // packageimport
+import dwtx.jface.text.presentation.IPresentationReconciler; // packageimport
+import dwtx.jface.text.presentation.IPresentationRepairer; // packageimport
+import dwtx.jface.text.presentation.IPresentationReconcilerExtension; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+import dwt.custom.StyleRange;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DefaultPositionUpdater;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.DocumentPartitioningChangedEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentExtension3;
+import dwtx.jface.text.IDocumentListener;
+import dwtx.jface.text.IDocumentPartitioningListener;
+import dwtx.jface.text.IDocumentPartitioningListenerExtension;
+import dwtx.jface.text.IDocumentPartitioningListenerExtension2;
+import dwtx.jface.text.IPositionUpdater;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextInputListener;
+import dwtx.jface.text.ITextListener;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.ITypedRegion;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextEvent;
+import dwtx.jface.text.TextPresentation;
+import dwtx.jface.text.TextUtilities;
+import dwtx.jface.text.TypedPosition;
+
+
+
+/**
+ * Standard implementation of <code>IPresentationReconciler</code>. This
+ * implementation assumes that the tasks performed by its presentation damagers
+ * and repairers are lightweight and of low cost. This presentation reconciler
+ * runs in the UI thread and always repairs the complete damage caused by a
+ * document change rather than just the portion overlapping with the viewer's
+ * viewport.
+ * <p>
+ * Usually, clients instantiate this class and configure it before using it.
+ * </p>
+ */
+public class PresentationReconciler : IPresentationReconciler, IPresentationReconcilerExtension {
+
+    /** Prefix of the name of the position category for tracking damage regions. */
+    protected const static String TRACKED_PARTITION= "__reconciler_tracked_partition"; //$NON-NLS-1$
+
+
+    /**
+     * Internal listener class.
+     */
+    class InternalListener :
+            ITextInputListener, IDocumentListener, ITextListener,
+            IDocumentPartitioningListener, IDocumentPartitioningListenerExtension, IDocumentPartitioningListenerExtension2 {
+
+        /** Set to <code>true</code> if between a document about to be changed and a changed event. */
+        private bool fDocumentChanging= false;
+        /**
+         * The cached redraw state of the text viewer.
+         * @since 3.0
+         */
+        private bool fCachedRedrawState= true;
+
+        /*
+         * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument)
+         */
+        public void inputDocumentAboutToBeChanged(IDocument oldDocument, IDocument newDocument) {
+            if (oldDocument !is null) {
+                try {
+
+                    fViewer.removeTextListener(this);
+                    oldDocument.removeDocumentListener(this);
+                    oldDocument.removeDocumentPartitioningListener(this);
+
+                    oldDocument.removePositionUpdater(fPositionUpdater);
+                    oldDocument.removePositionCategory(fPositionCategory);
+
+                } catch (BadPositionCategoryException x) {
+                    // should not happened for former input documents;
+                }
+            }
+        }
+
+        /*
+         * @see ITextInputListener#inputDocumenChanged(IDocument, IDocument)
+         */
+        public void inputDocumentChanged(IDocument oldDocument, IDocument newDocument) {
+
+            fDocumentChanging= false;
+            fCachedRedrawState= true;
+
+            if (newDocument !is null) {
+
+                newDocument.addPositionCategory(fPositionCategory);
+                newDocument.addPositionUpdater(fPositionUpdater);
+
+                newDocument.addDocumentPartitioningListener(this);
+                newDocument.addDocumentListener(this);
+                fViewer.addTextListener(this);
+
+                setDocumentToDamagers(newDocument);
+                setDocumentToRepairers(newDocument);
+                processDamage(new Region(0, newDocument.getLength()), newDocument);
+            }
+        }
+
+        /*
+         * @see IDocumentPartitioningListener#documentPartitioningChanged(IDocument)
+         */
+        public void documentPartitioningChanged(IDocument document) {
+            if (!fDocumentChanging && fCachedRedrawState)
+                processDamage(new Region(0, document.getLength()), document);
+            else
+                fDocumentPartitioningChanged= true;
+        }
+
+        /*
+         * @see IDocumentPartitioningListenerExtension#documentPartitioningChanged(IDocument, IRegion)
+         * @since 2.0
+         */
+        public void documentPartitioningChanged(IDocument document, IRegion changedRegion) {
+            if (!fDocumentChanging && fCachedRedrawState) {
+                processDamage(new Region(changedRegion.getOffset(), changedRegion.getLength()), document);
+            } else {
+                fDocumentPartitioningChanged= true;
+                fChangedDocumentPartitions= changedRegion;
+            }
+        }
+
+        /*
+         * @see dwtx.jface.text.IDocumentPartitioningListenerExtension2#documentPartitioningChanged(dwtx.jface.text.DocumentPartitioningChangedEvent)
+         * @since 3.0
+         */
+        public void documentPartitioningChanged(DocumentPartitioningChangedEvent event) {
+            IRegion changedRegion= event.getChangedRegion(getDocumentPartitioning());
+            if (changedRegion !is null)
+                documentPartitioningChanged(event.getDocument(), changedRegion);
+        }
+
+        /*
+         * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
+         */
+        public void documentAboutToBeChanged(DocumentEvent e) {
+
+            fDocumentChanging= true;
+            if (fCachedRedrawState) {
+                try {
+                    int offset= e.getOffset() + e.getLength();
+                    ITypedRegion region= getPartition(e.getDocument(), offset);
+                    fRememberedPosition= new TypedPosition(region);
+                    e.getDocument().addPosition(fPositionCategory, fRememberedPosition);
+                } catch (BadLocationException x) {
+                    // can not happen
+                } catch (BadPositionCategoryException x) {
+                    // should not happen on input elements
+                }
+            }
+        }
+
+        /*
+         * @see IDocumentListener#documentChanged(DocumentEvent)
+         */
+        public void documentChanged(DocumentEvent e) {
+            if (fCachedRedrawState) {
+                try {
+                    e.getDocument().removePosition(fPositionCategory, fRememberedPosition);
+                } catch (BadPositionCategoryException x) {
+                    // can not happen on input documents
+                }
+            }
+            fDocumentChanging= false;
+        }
+
+        /*
+         * @see ITextListener#textChanged(TextEvent)
+         */
+        public void textChanged(TextEvent e) {
+
+            fCachedRedrawState= e.getViewerRedrawState();
+            if (!fCachedRedrawState)
+                return;
+
+            IRegion damage= null;
+            IDocument document= null;
+
+            if (e.getDocumentEvent() is null) {
+                document= fViewer.getDocument();
+                if (document !is null)  {
+                    if (e.getOffset() is 0 && e.getLength() is 0 && e.getText() is null) {
+                        // redraw state change, damage the whole document
+                        damage= new Region(0, document.getLength());
+                    } else {
+                        IRegion region= widgetRegion2ModelRegion(e);
+                        try {
+                            String text= document.get(region.getOffset(), region.getLength());
+                            DocumentEvent de= new DocumentEvent(document, region.getOffset(), region.getLength(), text);
+                            damage= getDamage(de, false);
+                        } catch (BadLocationException x) {
+                        }
+                    }
+                }
+            } else  {
+                DocumentEvent de= e.getDocumentEvent();
+                document= de.getDocument();
+                damage= getDamage(de, true);
+            }
+
+            if (damage !is null && document !is null)
+                processDamage(damage, document);
+
+            fDocumentPartitioningChanged= false;
+            fChangedDocumentPartitions= null;
+        }
+
+        /**
+         * Translates the given text event into the corresponding range of the viewer's document.
+         *
+         * @param e the text event
+         * @return the widget region corresponding the region of the given event
+         * @since 2.1
+         */
+        protected IRegion widgetRegion2ModelRegion(TextEvent e) {
+
+            String text= e.getText();
+            int length= text is null ? 0 : text.length();
+
+            if ( cast(ITextViewerExtension5)fViewer ) {
+                ITextViewerExtension5 extension= cast(ITextViewerExtension5) fViewer;
+                return extension.widgetRange2ModelRange(new Region(e.getOffset(), length));
+            }
+
+            IRegion visible= fViewer.getVisibleRegion();
+            IRegion region= new Region(e.getOffset() + visible.getOffset(), length);
+            return region;
+        }
+    }
+
+    /** The map of presentation damagers. */
+    private Map fDamagers;
+    /** The map of presentation repairers. */
+    private Map fRepairers;
+    /** The target viewer. */
+    private ITextViewer fViewer;
+    /** The internal listener. */
+    private InternalListener fInternalListener;
+    /** The name of the position category to track damage regions. */
+    private String fPositionCategory;
+    /** The position updated for the damage regions' position category. */
+    private IPositionUpdater fPositionUpdater;
+    /** The positions representing the damage regions. */
+    private TypedPosition fRememberedPosition;
+    /** Flag indicating the receipt of a partitioning changed notification. */
+    private bool fDocumentPartitioningChanged= false;
+    /** The range covering the changed partitioning. */
+    private IRegion fChangedDocumentPartitions= null;
+    /**
+     * The partitioning used by this presentation reconciler.
+     * @since 3.0
+     */
+    private String fPartitioning;
+
+    /**
+     * Creates a new presentation reconciler. There are no damagers or repairers
+     * registered with this reconciler by default. The default partitioning
+     * <code>IDocumentExtension3.DEFAULT_PARTITIONING</code> is used.
+     */
+    public this() {
+        fInternalListener= new InternalListener();
+//         super();
+        fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING;
+        fPositionCategory= TRACKED_PARTITION ~ Integer.toString(toHash());
+        fPositionUpdater= new DefaultPositionUpdater(fPositionCategory);
+    }
+
+    /**
+     * Sets the document partitioning for this presentation reconciler.
+     *
+     * @param partitioning the document partitioning for this presentation reconciler.
+     * @since 3.0
+     */
+    public void setDocumentPartitioning(String partitioning) {
+        Assert.isNotNull(partitioning);
+        fPartitioning= partitioning;
+    }
+
+    /*
+     * @see dwtx.jface.text.presentation.IPresentationReconcilerExtension#geDocumenttPartitioning()
+     * @since 3.0
+     */
+    public String getDocumentPartitioning() {
+        return fPartitioning;
+    }
+
+    /**
+     * Registers the given presentation damager for a particular content type.
+     * If there is already a damager registered for this type, the old damager
+     * is removed first.
+     *
+     * @param damager the presentation damager to register, or <code>null</code> to remove an existing one
+     * @param contentType the content type under which to register
+     */
+    public void setDamager(IPresentationDamager damager, String contentType) {
+
+        Assert.isNotNull(contentType);
+
+        if (fDamagers is null)
+            fDamagers= new HashMap();
+
+        if (damager is null)
+            fDamagers.remove(contentType);
+        else
+            fDamagers.put(stringcast(contentType), cast(Object)damager);
+    }
+
+    /**
+     * Registers the given presentation repairer for a particular content type.
+     * If there is already a repairer registered for this type, the old repairer
+     * is removed first.
+     *
+     * @param repairer the presentation repairer to register, or <code>null</code> to remove an existing one
+     * @param contentType the content type under which to register
+     */
+    public void setRepairer(IPresentationRepairer repairer, String contentType) {
+
+        Assert.isNotNull(contentType);
+
+        if (fRepairers is null)
+            fRepairers= new HashMap();
+
+        if (repairer is null)
+            fRepairers.remove(contentType);
+        else
+            fRepairers.put(stringcast(contentType), cast(Object)repairer);
+    }
+
+    /*
+     * @see IPresentationReconciler#install(ITextViewer)
+     */
+    public void install(ITextViewer viewer) {
+        Assert.isNotNull(cast(Object)viewer);
+
+        fViewer= viewer;
+        fViewer.addTextInputListener(fInternalListener);
+
+        IDocument document= viewer.getDocument();
+        if (document !is null)
+            fInternalListener.inputDocumentChanged(null, document);
+    }
+
+    /*
+     * @see IPresentationReconciler#uninstall()
+     */
+    public void uninstall() {
+        fViewer.removeTextInputListener(fInternalListener);
+
+        // Ensure we uninstall all listeners
+        fInternalListener.inputDocumentAboutToBeChanged(fViewer.getDocument(), null);
+    }
+
+    /*
+     * @see IPresentationReconciler#getDamager(String)
+     */
+    public IPresentationDamager getDamager(String contentType) {
+
+        if (fDamagers is null)
+            return null;
+
+        return cast(IPresentationDamager) fDamagers.get(contentType);
+    }
+
+    /*
+     * @see IPresentationReconciler#getRepairer(String)
+     */
+    public IPresentationRepairer getRepairer(String contentType) {
+
+        if (fRepairers is null)
+            return null;
+
+        return cast(IPresentationRepairer) fRepairers.get(contentType);
+    }
+
+    /**
+     * Informs all registered damagers about the document on which they will work.
+     *
+     * @param document the document on which to work
+     */
+    protected void setDocumentToDamagers(IDocument document) {
+        if (fDamagers !is null) {
+            Iterator e= fDamagers.values().iterator();
+            while (e.hasNext()) {
+                IPresentationDamager damager= cast(IPresentationDamager) e.next();
+                damager.setDocument(document);
+            }
+        }
+    }
+
+    /**
+     * Informs all registered repairers about the document on which they will work.
+     *
+     * @param document the document on which to work
+     */
+    protected void setDocumentToRepairers(IDocument document) {
+        if (fRepairers !is null) {
+            Iterator e= fRepairers.values().iterator();
+            while (e.hasNext()) {
+                IPresentationRepairer repairer= cast(IPresentationRepairer) e.next();
+                repairer.setDocument(document);
+            }
+        }
+    }
+
+    /**
+     * Constructs a "repair description" for the given damage and returns this
+     * description as a text presentation. For this, it queries the partitioning
+     * of the damage region and asks the appropriate presentation repairer for
+     * each partition to construct the "repair description" for this partition.
+     *
+     * @param damage the damage to be repaired
+     * @param document the document whose presentation must be repaired
+     * @return the presentation repair description as text presentation or
+     *         <code>null</code> if the partitioning could not be computed
+     */
+    protected TextPresentation createPresentation(IRegion damage, IDocument document) {
+        try {
+            if (fRepairers is null || fRepairers.isEmpty()) {
+                TextPresentation presentation= new TextPresentation(damage, 100);
+                presentation.setDefaultStyleRange(new StyleRange(damage.getOffset(), damage.getLength(), null, null));
+                return presentation;
+            }
+
+            TextPresentation presentation= new TextPresentation(damage, 1000);
+
+            ITypedRegion[] partitioning= TextUtilities.computePartitioning(document, getDocumentPartitioning(), damage.getOffset(), damage.getLength(), false);
+            for (int i= 0; i < partitioning.length; i++) {
+                ITypedRegion r= partitioning[i];
+                IPresentationRepairer repairer= getRepairer(r.getType());
+                if (repairer !is null)
+                    repairer.createPresentation(presentation, r);
+            }
+
+            return presentation;
+
+        } catch (BadLocationException x) {
+            return null;
+        }
+    }
+
+
+    /**
+     * Checks for the first and the last affected partition affected by a
+     * document event and calls their damagers. Invalidates everything from the
+     * start of the damage for the first partition until the end of the damage
+     * for the last partition.
+     *
+     * @param e the event describing the document change
+     * @param optimize <code>true</code> if partition changes should be
+     *        considered for optimization
+     * @return the damaged caused by the change or <code>null</code> if
+     *         computing the partitioning failed
+     * @since 3.0
+     */
+    private IRegion getDamage(DocumentEvent e, bool optimize) {
+        int length= e.getText() is null ? 0 : e.getText().length();
+
+        if (fDamagers is null || fDamagers.isEmpty()) {
+            length= Math.max(e.getLength(), length);
+            length= Math.min(e.getDocument().getLength() - e.getOffset(), length);
+            return new Region(e.getOffset(), length);
+        }
+
+        bool isDeletion= length is 0;
+        IRegion damage= null;
+        try {
+            int offset= e.getOffset();
+            if (isDeletion)
+                offset= Math.max(0, offset - 1);
+            ITypedRegion partition= getPartition(e.getDocument(), offset);
+            IPresentationDamager damager= getDamager(partition.getType());
+            if (damager is null)
+                return null;
+
+            IRegion r= damager.getDamageRegion(partition, e, fDocumentPartitioningChanged);
+
+            if (!fDocumentPartitioningChanged && optimize && !isDeletion) {
+                damage= r;
+            } else {
+
+                int damageEnd= getDamageEndOffset(e);
+
+                int parititionDamageEnd= -1;
+                if (fChangedDocumentPartitions !is null)
+                    parititionDamageEnd= fChangedDocumentPartitions.getOffset() + fChangedDocumentPartitions.getLength();
+
+                int end= Math.max(damageEnd, parititionDamageEnd);
+
+                damage= end is -1 ? r : new Region(r.getOffset(), end - r.getOffset());
+            }
+
+        } catch (BadLocationException x) {
+        }
+
+        return damage;
+    }
+
+    /**
+     * Returns the end offset of the damage. If a partition has been split by
+     * the given document event also the second half of the original
+     * partition must be considered. This is achieved by using the remembered
+     * partition range.
+     *
+     * @param e the event describing the change
+     * @return the damage end offset (excluding)
+     * @exception BadLocationException if method accesses invalid offset
+     */
+    private int getDamageEndOffset(DocumentEvent e)  {
+
+        IDocument d= e.getDocument();
+
+        int length= 0;
+        if (e.getText() !is null) {
+            length= e.getText().length;
+            if (length > 0)
+                -- length;
+        }
+
+        ITypedRegion partition= getPartition(d, e.getOffset() + length);
+        int endOffset= partition.getOffset() + partition.getLength();
+        if (endOffset is e.getOffset())
+            return -1;
+
+        int end= fRememberedPosition is null ? -1 : fRememberedPosition.getOffset() + fRememberedPosition.getLength();
+        if (endOffset < end && end < d.getLength())
+            partition= getPartition(d, end);
+
+        IPresentationDamager damager= getDamager(partition.getType());
+        if (damager is null)
+            return -1;
+
+        IRegion r= damager.getDamageRegion(partition, e, fDocumentPartitioningChanged);
+
+        return r.getOffset() + r.getLength();
+    }
+
+    /**
+     * Processes the given damage.
+     * @param damage the damage to be repaired
+     * @param document the document whose presentation must be repaired
+     */
+    private void processDamage(IRegion damage, IDocument document) {
+        if (damage !is null && damage.getLength() > 0) {
+            TextPresentation p= createPresentation(damage, document);
+            if (p !is null)
+                applyTextRegionCollection(p);
+        }
+    }
+
+    /**
+     * Applies the given text presentation to the text viewer the presentation
+     * reconciler is installed on.
+     *
+     * @param presentation the text presentation to be applied to the text viewer
+     */
+    private void applyTextRegionCollection(TextPresentation presentation) {
+        fViewer.changeTextPresentation(presentation, false);
+    }
+
+    /**
+     * Returns the partition for the given offset in the given document.
+     *
+     * @param document the document
+     * @param offset the offset
+     * @return the partition
+     * @throws BadLocationException if offset is invalid in the given document
+     * @since 3.0
+     */
+    private ITypedRegion getPartition(IDocument document, int offset)  {
+        return TextUtilities.getPartition(document, getDocumentPartitioning(), offset, false);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/projection/ChildDocument.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.projection.ChildDocument;
+
+import dwtx.jface.text.projection.ProjectionMapping; // packageimport
+import dwtx.jface.text.projection.ChildDocumentManager; // packageimport
+import dwtx.jface.text.projection.SegmentUpdater; // packageimport
+import dwtx.jface.text.projection.Segment; // packageimport
+import dwtx.jface.text.projection.ProjectionDocument; // packageimport
+import dwtx.jface.text.projection.FragmentUpdater; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport
+import dwtx.jface.text.projection.IMinimalMapping; // packageimport
+import dwtx.jface.text.projection.Fragment; // packageimport
+import dwtx.jface.text.projection.ProjectionTextStore; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.Position;
+
+/**
+ * Implementation of a child document based on
+ * {@link dwtx.jface.text.projection.ProjectionDocument}. This class
+ * exists for compatibility reasons.
+ * <p>
+ * Internal class. This class is not intended to be used by clients.</p>
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ChildDocument : ProjectionDocument {
+
+    /**
+     * Position reflecting a visible region. The exclusive end offset of the position
+     * is considered being overlapping with the visible region.
+     */
+    static private class VisibleRegion : Position {
+
+        /**
+         * Creates a new visible region.
+         *
+         * @param regionOffset the offset of the region
+         * @param regionLength the length of the region
+         */
+        public this(int regionOffset, int regionLength) {
+            super(regionOffset, regionLength);
+        }
+
+        /**
+         * If <code>regionOffset</code> is the end of the visible region and the <code>regionLength is 0</code>,
+         * the <code>regionOffset</code> is considered overlapping with the visible region.
+         *
+         * @see dwtx.jface.text.Position#overlapsWith(int, int)
+         */
+        public bool overlapsWith(int regionOffset, int regionLength) {
+            bool appending= (regionOffset is offset + length) && regionLength is 0;
+            return appending || super.overlapsWith(regionOffset, regionLength);
+        }
+    }
+
+    /**
+     * Creates a new child document.
+     *
+     * @param masterDocument @inheritDoc
+     */
+    public this(IDocument masterDocument) {
+        super(masterDocument);
+    }
+
+    /**
+     * Returns the parent document of this child document.
+     *
+     * @return the parent document of this child document
+     * @see ProjectionDocument#getMasterDocument()
+     */
+    public IDocument getParentDocument() {
+        return getMasterDocument();
+    }
+
+    /**
+     * Sets the parent document range covered by this child document to the
+     * given range.
+     *
+     * @param offset the offset of the range
+     * @param length the length of the range
+     * @throws BadLocationException if the given range is not valid
+     */
+    public void setParentDocumentRange(int offset, int length)  {
+        replaceMasterDocumentRanges(offset, length);
+    }
+
+    /**
+     * Returns the parent document range of this child document.
+     *
+     * @return the parent document range of this child document
+     */
+    public Position getParentDocumentRange() {
+        IRegion coverage= getDocumentInformationMapping().getCoverage();
+        return new VisibleRegion(coverage.getOffset(), coverage.getLength());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/projection/ChildDocumentManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.projection.ChildDocumentManager;
+
+import dwtx.jface.text.projection.ProjectionMapping; // packageimport
+import dwtx.jface.text.projection.SegmentUpdater; // packageimport
+import dwtx.jface.text.projection.Segment; // packageimport
+import dwtx.jface.text.projection.ProjectionDocument; // packageimport
+import dwtx.jface.text.projection.FragmentUpdater; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport
+import dwtx.jface.text.projection.ChildDocument; // packageimport
+import dwtx.jface.text.projection.IMinimalMapping; // packageimport
+import dwtx.jface.text.projection.Fragment; // packageimport
+import dwtx.jface.text.projection.ProjectionTextStore; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.IDocument;
+
+
+/**
+ * Implementation of a child document manager based on
+ * {@link dwtx.jface.text.projection.ProjectionDocumentManager}. This
+ * class exists for compatibility reasons.
+ * <p>
+ * Internal class. This class is not intended to be used by clients outside
+ * the Platform Text framework.</p>
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ChildDocumentManager : ProjectionDocumentManager {
+
+    /*
+     * @see dwtx.jface.text.projection.ProjectionDocumentManager#createProjectionDocument(dwtx.jface.text.IDocument)
+     */
+    protected ProjectionDocument createProjectionDocument(IDocument master) {
+        return new ChildDocument(master);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/projection/Fragment.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.projection.Fragment;
+
+import dwtx.jface.text.projection.ProjectionMapping; // packageimport
+import dwtx.jface.text.projection.ChildDocumentManager; // packageimport
+import dwtx.jface.text.projection.SegmentUpdater; // packageimport
+import dwtx.jface.text.projection.Segment; // packageimport
+import dwtx.jface.text.projection.ProjectionDocument; // packageimport
+import dwtx.jface.text.projection.FragmentUpdater; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport
+import dwtx.jface.text.projection.ChildDocument; // packageimport
+import dwtx.jface.text.projection.IMinimalMapping; // packageimport
+import dwtx.jface.text.projection.ProjectionTextStore; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.Position;
+
+
+/**
+ * Internal class. Do not use. Only public for testing purposes.
+ * <p>
+ * A fragment is a range of the master document that has an image, the so called
+ * segment, in a projection document.</p>
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Fragment : Position {
+
+    /**
+     * The corresponding segment of this fragment.
+     */
+    public Segment segment;
+
+    /**
+     * Creates a new fragment covering the given range.
+     *
+     * @param offset the offset of the fragment
+     * @param length the length of the fragment
+     */
+    public this(int offset, int length) {
+        super(offset, length);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/projection/FragmentUpdater.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,152 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.projection.FragmentUpdater;
+
+import dwtx.jface.text.projection.ProjectionMapping; // packageimport
+import dwtx.jface.text.projection.ChildDocumentManager; // packageimport
+import dwtx.jface.text.projection.SegmentUpdater; // packageimport
+import dwtx.jface.text.projection.Segment; // packageimport
+import dwtx.jface.text.projection.ProjectionDocument; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport
+import dwtx.jface.text.projection.ChildDocument; // packageimport
+import dwtx.jface.text.projection.IMinimalMapping; // packageimport
+import dwtx.jface.text.projection.Fragment; // packageimport
+import dwtx.jface.text.projection.ProjectionTextStore; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DefaultPositionUpdater;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.Position;
+
+
+/**
+ * The position updater used to adapt the fragments of a master document. If an
+ * insertion happens at a fragment's offset, the fragment is extended rather
+ * than shifted. Also, the last fragment is extended if an insert operation
+ * happens at the end of the fragment.
+ *
+ * @since 3.0
+ */
+class FragmentUpdater : DefaultPositionUpdater {
+
+    /** Indicates whether the position being updated represents the last fragment. */
+    private bool fIsLast= false;
+
+    /**
+     * Creates the fragment updater for the given category.
+     *
+     * @param fragmentCategory the position category used for managing the fragments of a document
+     */
+    /+protected+/ this(String fragmentCategory) {
+        super(fragmentCategory);
+    }
+
+    /*
+     * @see dwtx.jface.text.IPositionUpdater#update(dwtx.jface.text.DocumentEvent)
+     */
+    public void update(DocumentEvent event) {
+
+        try {
+
+            Position[] category= event.getDocument().getPositions(getCategory());
+
+            fOffset= event.getOffset();
+            fLength= event.getLength();
+            fReplaceLength= (event.getText() is null ? 0 : event.getText().length());
+            fDocument= event.getDocument();
+
+            for (int i= 0; i < category.length; i++) {
+
+                fPosition= category[i];
+                fIsLast= (i is category.length -1);
+
+                fOriginalPosition.offset= fPosition.offset;
+                fOriginalPosition.length= fPosition.length;
+
+                if (notDeleted())
+                    adaptToReplace();
+            }
+
+        } catch (BadPositionCategoryException x) {
+            // do nothing
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.DefaultPositionUpdater#adaptToInsert()
+     */
+    protected void adaptToInsert() {
+        int myStart= fPosition.offset;
+        int myEnd= Math.max(myStart, fPosition.offset + fPosition.length - (fIsLast || isAffectingReplace() ? 0 : 1));
+
+        if (myEnd < fOffset)
+            return;
+
+        if (fLength <= 0) {
+
+            if (myStart <= fOffset)
+                fPosition.length += fReplaceLength;
+            else
+                fPosition.offset += fReplaceLength;
+
+        } else {
+
+            if (myStart <= fOffset && fOriginalPosition.offset <= fOffset)
+                fPosition.length += fReplaceLength;
+            else
+                fPosition.offset += fReplaceLength;
+        }
+    }
+
+    /**
+     * Returns whether this updater considers any position affected by the given document event. A
+     * position is affected if <code>event</code> {@link Position#overlapsWith(int, int) overlaps}
+     * with it but not if the position is only shifted.
+     *
+     * @param event the event
+     * @return <code>true</code> if there is any affected position, <code>false</code> otherwise
+     */
+    public bool affectsPositions(DocumentEvent event) {
+        IDocument document= event.getDocument();
+        try {
+
+            int index= document.computeIndexInCategory(getCategory(), event.getOffset());
+            Position[] fragments= document.getPositions(getCategory());
+
+            if (0 < index) {
+                Position fragment= fragments[index - 1];
+                if (fragment.overlapsWith(event.getOffset(), event.getLength()))
+                    return true;
+                if (index is fragments.length && fragment.offset + fragment.length is event.getOffset())
+                    return true;
+            }
+
+            if (index < fragments.length) {
+                Position fragment= fragments[index];
+                return fragment.overlapsWith(event.getOffset(), event.getLength());
+            }
+
+        } catch (BadLocationException x) {
+        } catch (BadPositionCategoryException x) {
+        }
+
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/projection/IMinimalMapping.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.projection.IMinimalMapping;
+
+import dwtx.jface.text.projection.ProjectionMapping; // packageimport
+import dwtx.jface.text.projection.ChildDocumentManager; // packageimport
+import dwtx.jface.text.projection.SegmentUpdater; // packageimport
+import dwtx.jface.text.projection.Segment; // packageimport
+import dwtx.jface.text.projection.ProjectionDocument; // packageimport
+import dwtx.jface.text.projection.FragmentUpdater; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport
+import dwtx.jface.text.projection.ChildDocument; // packageimport
+import dwtx.jface.text.projection.Fragment; // packageimport
+import dwtx.jface.text.projection.ProjectionTextStore; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IRegion;
+
+
+/**
+ * Internal interface for defining the exact subset of
+ * {@link dwtx.jface.text.projection.ProjectionMapping} that the
+ * {@link dwtx.jface.text.projection.ProjectionTextStore} is allowed to
+ * access.
+ *
+ * @since 3.0
+ */
+interface IMinimalMapping {
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMapping#getCoverage()
+     */
+    IRegion getCoverage();
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMapping#toOriginRegion(IRegion)
+     */
+    IRegion toOriginRegion(IRegion region) ;
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMapping#toOriginOffset(int)
+     */
+    int toOriginOffset(int offset) ;
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMappingExtension#toExactOriginRegions(IRegion)
+     */
+    IRegion[] toExactOriginRegions(IRegion region) ;
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMappingExtension#getImageLength()
+     */
+    int getImageLength();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/projection/ProjectionDocument.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,919 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.projection.ProjectionDocument;
+
+import dwtx.jface.text.projection.ProjectionMapping; // packageimport
+import dwtx.jface.text.projection.ChildDocumentManager; // packageimport
+import dwtx.jface.text.projection.SegmentUpdater; // packageimport
+import dwtx.jface.text.projection.Segment; // packageimport
+import dwtx.jface.text.projection.FragmentUpdater; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport
+import dwtx.jface.text.projection.ChildDocument; // packageimport
+import dwtx.jface.text.projection.IMinimalMapping; // packageimport
+import dwtx.jface.text.projection.Fragment; // packageimport
+import dwtx.jface.text.projection.ProjectionTextStore; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.jface.text.AbstractDocument;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DefaultLineTracker;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentExtension;
+import dwtx.jface.text.IDocumentInformationMapping;
+import dwtx.jface.text.IDocumentListener;
+import dwtx.jface.text.ILineTracker;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextStore;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextUtilities;
+
+
+/**
+ * A <code>ProjectionDocument</code> represents a projection of its master
+ * document. The contents of a projection document is a sequence of fragments of
+ * the master document, i.e. the projection document can be thought as being
+ * constructed from the master document by not copying the whole master document
+ * but omitting several ranges of the master document.
+ * <p>
+ * The projection document indirectly utilizes its master document as
+ * <code>ITextStore</code> by means of a <code>ProjectionTextStore</code>.
+ * <p>
+ * The content of a projection document can be changed in two ways. Either by a
+ * text replace applied to the master document or the projection document. Or by
+ * changing the projection between the master document and the projection
+ * document. For the latter the two methods <code>addMasterDocumentRange</code>
+ * and <code>removeMasterDocumentRange</code> are provided. For any
+ * manipulation, the projection document sends out a
+ * {@link dwtx.jface.text.projection.ProjectionDocumentEvent} describing
+ * the change.
+ * <p>
+ * Clients are not supposed to directly instantiate this class. In order to
+ * obtain a projection document, a
+ * {@link dwtx.jface.text.projection.ProjectionDocumentManager}should be
+ * used. This class is not intended to be subclassed outside of its origin
+ * package.</p>
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ProjectionDocument : AbstractDocument {
+
+
+    /**
+     * Prefix of the name of the position category used to keep track of the master
+     * document's fragments that correspond to the segments of the projection
+     * document.
+     */
+    private const static String FRAGMENTS_CATEGORY_PREFIX= "__fragmentsCategory"; //$NON-NLS-1$
+
+    /**
+     * Name of the position category used to keep track of the project
+     * document's segments that correspond to the fragments of the master
+     * document.
+     */
+    private const static String SEGMENTS_CATEGORY= "__segmentsCategory"; //$NON-NLS-1$
+
+
+    /** The master document */
+    private IDocument fMasterDocument;
+    /** The master document as document extension */
+    private IDocumentExtension fMasterDocumentExtension;
+    /** The fragments' position category */
+    private String fFragmentsCategory;
+    /** The segment's position category */
+    private String fSegmentsCategory;
+    /** The document event issued by the master document */
+    private DocumentEvent fMasterEvent;
+    /** The document event to be issued by the projection document */
+    private ProjectionDocumentEvent fSlaveEvent;
+    /** The original document event generated by a direct manipulation of this projection document */
+    private DocumentEvent fOriginalEvent;
+    /** Indicates whether the projection document initiated a master document update or not */
+    private bool fIsUpdating= false;
+    /** Indicated whether the projection document is in auto expand mode nor not */
+    private bool fIsAutoExpanding= false;
+    /** The position updater for the segments */
+    private SegmentUpdater fSegmentUpdater;
+    /** The position updater for the fragments */
+    private FragmentUpdater fFragmentsUpdater;
+    /** The projection mapping */
+    private ProjectionMapping fMapping;
+
+    /**
+     * Creates a projection document for the given master document.
+     *
+     * @param masterDocument the master document
+     */
+    public this(IDocument masterDocument) {
+        super();
+
+        fMasterDocument= masterDocument;
+        if ( cast(IDocumentExtension)fMasterDocument )
+            fMasterDocumentExtension= cast(IDocumentExtension) fMasterDocument;
+
+        fSegmentsCategory= SEGMENTS_CATEGORY;
+        fFragmentsCategory= FRAGMENTS_CATEGORY_PREFIX ~ Integer.toString(toHash());
+        fMasterDocument.addPositionCategory(fFragmentsCategory);
+        fFragmentsUpdater= new FragmentUpdater(fFragmentsCategory);
+        fMasterDocument.addPositionUpdater(fFragmentsUpdater);
+
+        fMapping= new ProjectionMapping(masterDocument, fFragmentsCategory, this, fSegmentsCategory);
+
+        ITextStore s= new ProjectionTextStore(masterDocument, fMapping);
+        ILineTracker tracker= new DefaultLineTracker();
+
+        setTextStore(s);
+        setLineTracker(tracker);
+
+        completeInitialization();
+
+        initializeProjection();
+        tracker.set(s.get(0, s.getLength()));
+    }
+
+    /**
+     * Disposes this projection document.
+     */
+    public void dispose() {
+        fMasterDocument.removePositionUpdater(fFragmentsUpdater);
+        try {
+            fMasterDocument.removePositionCategory(fFragmentsCategory);
+        } catch (BadPositionCategoryException x) {
+            // allow multiple dispose calls
+        }
+    }
+
+    private void internalError() {
+        throw new IllegalStateException();
+    }
+
+    /**
+     * Returns the fragments of the master documents.
+     *
+     * @return the fragment of the master document
+     */
+    protected final Position[] getFragments() {
+        try {
+            return fMasterDocument.getPositions(fFragmentsCategory);
+        } catch (BadPositionCategoryException e) {
+            internalError();
+        }
+        // unreachable
+        return null;
+    }
+
+    /**
+     * Returns the segments of this projection document.
+     *
+     * @return the segments of this projection document
+     */
+    protected final Position[] getSegments() {
+        try {
+            return getPositions(fSegmentsCategory);
+        } catch (BadPositionCategoryException e) {
+            internalError();
+        }
+        // unreachable
+        return null;
+    }
+
+    /**
+     * Returns the projection mapping used by this document.
+     *
+     * @return the projection mapping used by this document
+     * @deprecated As of 3.4, replaced by {@link #getDocumentInformationMapping()}
+     */
+    public ProjectionMapping getProjectionMapping(){
+        return fMapping;
+    }
+
+    /**
+     * Returns the projection mapping used by this document.
+     *
+     * @return the projection mapping used by this document
+     * @since 3.4
+     */
+    public IDocumentInformationMapping getDocumentInformationMapping() {
+        return fMapping;
+    }
+
+    /**
+     * Returns the master document of this projection document.
+     *
+     * @return the master document of this projection document
+     */
+    public IDocument getMasterDocument() {
+        return fMasterDocument;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentExtension4#getDefaultLineDelimiter()
+     * @since 3.1
+     */
+    public String getDefaultLineDelimiter() {
+        return TextUtilities.getDefaultLineDelimiter(fMasterDocument);
+    }
+
+    /**
+     * Initializes the projection document from the master document based on
+     * the master's fragments.
+     */
+    private void initializeProjection() {
+
+        try {
+
+            addPositionCategory(fSegmentsCategory);
+            fSegmentUpdater= new SegmentUpdater(fSegmentsCategory);
+            addPositionUpdater(fSegmentUpdater);
+
+            int offset= 0;
+            Position[] fragments= getFragments();
+            for (int i= 0; i < fragments.length; i++) {
+                Fragment fragment= cast(Fragment) fragments[i];
+                Segment segment= new Segment(offset, fragment.getLength());
+                segment.fragment= fragment;
+                addPosition(fSegmentsCategory, segment);
+                offset += fragment.length;
+            }
+
+        } catch (BadPositionCategoryException x) {
+            internalError();
+        } catch (BadLocationException x) {
+            internalError();
+        }
+    }
+
+    /**
+     * Creates a segment for the given fragment at the given position inside the list of segments.
+     *
+     * @param fragment the corresponding fragment
+     * @param index the index in the list of segments
+     * @return the created segment
+     * @throws BadLocationException in case the fragment is invalid
+     * @throws BadPositionCategoryException in case the segment category is invalid
+     */
+    private Segment createSegmentFor(Fragment fragment, int index)  {
+
+        int offset= 0;
+        if (index > 0) {
+            Position[] segments= getSegments();
+            Segment segment= cast(Segment) segments[index - 1];
+            offset= segment.getOffset() + segment.getLength();
+        }
+
+        Segment segment= new Segment(offset, 0);
+        segment.fragment= fragment;
+        fragment.segment= segment;
+        addPosition(fSegmentsCategory, segment);
+        return segment;
+    }
+
+    /**
+     * Adds the given range of the master document to this projection document.
+     *
+     * @param offsetInMaster offset of the master document range
+     * @param lengthInMaster length of the master document range
+     * @param masterDocumentEvent the master document event that causes this
+     *            projection change or <code>null</code> if none
+     * @throws BadLocationException if the given range is invalid in the master
+     *             document
+     */
+    private void internalAddMasterDocumentRange(int offsetInMaster, int lengthInMaster, DocumentEvent masterDocumentEvent)  {
+        if (lengthInMaster is 0)
+            return;
+
+        try {
+
+            Position[] fragments= getFragments();
+            int index= fMasterDocument.computeIndexInCategory(fFragmentsCategory, offsetInMaster);
+
+            Fragment left= null;
+            Fragment right= null;
+
+            if (index < fragments.length) {
+                Fragment fragment= cast(Fragment) fragments[index];
+                if (offsetInMaster is fragment.offset)
+                    if (fragment.length is 0) // the fragment does not overlap - it is a zero-length fragment at the same offset
+                        left= fragment;
+                    else
+                        throw new IllegalArgumentException("overlaps with existing fragment"); //$NON-NLS-1$
+                if (offsetInMaster + lengthInMaster is fragment.offset)
+                    right= fragment;
+            }
+
+            if (0 < index && index <= fragments.length) {
+                Fragment fragment= cast(Fragment) fragments[index - 1];
+                if (fragment.includes(offsetInMaster))
+                    throw new IllegalArgumentException("overlaps with existing fragment"); //$NON-NLS-1$
+                if (fragment.getOffset() + fragment.getLength() is offsetInMaster)
+                    left= fragment;
+            }
+
+            int offsetInSlave= 0;
+            if (index > 0) {
+                Fragment fragment= cast(Fragment) fragments[index - 1];
+                Segment segment= fragment.segment;
+                offsetInSlave= segment.getOffset() + segment.getLength();
+            }
+
+            ProjectionDocumentEvent event= new ProjectionDocumentEvent(this, offsetInSlave, 0, fMasterDocument.get(offsetInMaster, lengthInMaster), offsetInMaster, lengthInMaster, masterDocumentEvent);
+            super.fireDocumentAboutToBeChanged(event);
+
+            // check for neighboring fragment
+            if (left !is null && right !is null) {
+
+                int endOffset= right.getOffset() + right.getLength();
+                left.setLength(endOffset - left.getOffset());
+                left.segment.setLength(left.segment.getLength() + right.segment.getLength());
+
+                removePosition(fSegmentsCategory, right.segment);
+                fMasterDocument.removePosition(fFragmentsCategory, right);
+
+            } else if (left !is null) {
+                int endOffset= offsetInMaster +lengthInMaster;
+                left.setLength(endOffset - left.getOffset());
+                left.segment.markForStretch();
+
+            } else if (right !is null) {
+                right.setOffset(right.getOffset() - lengthInMaster);
+                right.setLength(right.getLength() + lengthInMaster);
+                right.segment.markForStretch();
+
+            } else {
+                // create a new segment
+                Fragment fragment= new Fragment(offsetInMaster, lengthInMaster);
+                fMasterDocument.addPosition(fFragmentsCategory, fragment);
+                Segment segment= createSegmentFor(fragment, index);
+                segment.markForStretch();
+            }
+
+            getTracker().replace(event.getOffset(), event.getLength(), event.getText());
+            super.fireDocumentChanged(event);
+
+        } catch (BadPositionCategoryException x) {
+            internalError();
+        }
+    }
+
+    /**
+     * Finds the fragment of the master document that represents the given range.
+     *
+     * @param offsetInMaster the offset of the range in the master document
+     * @param lengthInMaster the length of the range in the master document
+     * @return the fragment representing the given master document range
+     */
+    private Fragment findFragment(int offsetInMaster, int lengthInMaster) {
+        Position[] fragments= getFragments();
+        for (int i= 0; i < fragments.length; i++) {
+            Fragment f= cast(Fragment) fragments[i];
+            if (f.getOffset() <= offsetInMaster && offsetInMaster + lengthInMaster <= f.getOffset() + f.getLength())
+                return f;
+        }
+        return null;
+    }
+
+    /**
+     * Removes the given range of the master document from this projection
+     * document.
+     *
+     * @param offsetInMaster the offset of the range in the master document
+     * @param lengthInMaster the length of the range in the master document
+     *
+     * @throws BadLocationException if the given range is not valid in the
+     *             master document
+     * @throws IllegalArgumentException if the given range is not projected in
+     *             this projection document or is not completely comprised by
+     *             an existing fragment
+     */
+    private void internalRemoveMasterDocumentRange(int offsetInMaster, int lengthInMaster)  {
+        try {
+
+            IRegion imageRegion= fMapping.toExactImageRegion(new Region(offsetInMaster, lengthInMaster));
+            if (imageRegion is null)
+                throw new IllegalArgumentException(null);
+
+            Fragment fragment= findFragment(offsetInMaster, lengthInMaster);
+            if (fragment is null)
+                throw new IllegalArgumentException(null);
+
+            ProjectionDocumentEvent event= new ProjectionDocumentEvent(this, imageRegion.getOffset(), imageRegion.getLength(), "", offsetInMaster, lengthInMaster); //$NON-NLS-1$
+            super.fireDocumentAboutToBeChanged(event);
+
+            if (fragment.getOffset() is offsetInMaster) {
+                fragment.setOffset(offsetInMaster + lengthInMaster);
+                fragment.setLength(fragment.getLength() - lengthInMaster);
+            } else if (fragment.getOffset() + fragment.getLength() is offsetInMaster + lengthInMaster) {
+                fragment.setLength(fragment.getLength() - lengthInMaster);
+            } else {
+                // split fragment into three fragments, let position updater remove it
+
+                // add fragment for the region to be removed
+                Fragment newFragment= new Fragment(offsetInMaster, lengthInMaster);
+                Segment segment= new Segment(imageRegion.getOffset(), imageRegion.getLength());
+                newFragment.segment= segment;
+                segment.fragment= newFragment;
+                fMasterDocument.addPosition(fFragmentsCategory, newFragment);
+                addPosition(fSegmentsCategory, segment);
+
+                // add fragment for the remainder right of the deleted range in the original fragment
+                int offset= offsetInMaster + lengthInMaster;
+                newFragment= new Fragment(offset, fragment.getOffset() + fragment.getLength() - offset);
+                offset= imageRegion.getOffset() + imageRegion.getLength();
+                segment= new Segment(offset, fragment.segment.getOffset() + fragment.segment.getLength() - offset);
+                newFragment.segment= segment;
+                segment.fragment= newFragment;
+                fMasterDocument.addPosition(fFragmentsCategory, newFragment);
+                addPosition(fSegmentsCategory, segment);
+
+                // adjust length of initial fragment (the left one)
+                fragment.setLength(offsetInMaster - fragment.getOffset());
+                fragment.segment.setLength(imageRegion.getOffset() - fragment.segment.getOffset());
+            }
+
+            getTracker().replace(event.getOffset(), event.getLength(), event.getText());
+            super.fireDocumentChanged(event);
+
+        } catch (BadPositionCategoryException x) {
+            internalError();
+        }
+    }
+
+    /**
+     * Returns the sequence of all master document regions which are contained
+     * in the given master document range and which are not yet part of this
+     * projection document.
+     *
+     * @param offsetInMaster the range offset in the master document
+     * @param lengthInMaster the range length in the master document
+     * @return the sequence of regions which are not yet part of the projection
+     *         document
+     * @throws BadLocationException in case the given range is invalid in the
+     *         master document
+     */
+    public final IRegion[] computeUnprojectedMasterRegions(int offsetInMaster, int lengthInMaster)  {
+
+        IRegion[] fragments= null;
+        IRegion imageRegion= fMapping.toImageRegion(new Region(offsetInMaster, lengthInMaster));
+        if (imageRegion !is null)
+            fragments= fMapping.toExactOriginRegions(imageRegion);
+
+        if (fragments is null || fragments.length is 0)
+            return [ new Region(offsetInMaster, lengthInMaster) ];
+
+        List gaps= new ArrayList();
+
+        IRegion region= fragments[0];
+        if (offsetInMaster < region.getOffset())
+            gaps.add(new Region(offsetInMaster, region.getOffset() - offsetInMaster));
+
+        for (int i= 0; i < fragments.length - 1; i++) {
+            IRegion left= fragments[i];
+            IRegion right= fragments[i + 1];
+            int leftEnd= left.getOffset() + left.getLength();
+            if (leftEnd < right.getOffset())
+                gaps.add(new Region(leftEnd, right.getOffset() - leftEnd));
+        }
+
+        region= fragments[fragments.length - 1];
+        int leftEnd= region.getOffset() + region.getLength();
+        int rightEnd= offsetInMaster + lengthInMaster;
+        if (leftEnd < rightEnd)
+            gaps.add(new Region(leftEnd, rightEnd - leftEnd));
+
+        return arraycast!(IRegion)(gaps.toArray());
+    }
+
+    /**
+     * Returns the first master document region which is contained in the given
+     * master document range and which is not yet part of this projection
+     * document.
+     *
+     * @param offsetInMaster the range offset in the master document
+     * @param lengthInMaster the range length in the master document
+     * @return the first region that is not yet part of the projection document
+     * @throws BadLocationException in case the given range is invalid in the
+     *         master document
+     * @since 3.1
+     */
+    private IRegion computeFirstUnprojectedMasterRegion(int offsetInMaster, int lengthInMaster)  {
+
+        IRegion[] fragments= null;
+        IRegion imageRegion= fMapping.toImageRegion(new Region(offsetInMaster, lengthInMaster));
+        if (imageRegion !is null)
+            fragments= fMapping.toExactOriginRegions(imageRegion);
+
+        if (fragments is null || fragments.length is 0)
+            return new Region(offsetInMaster, lengthInMaster);
+
+        IRegion region= fragments[0];
+        if (offsetInMaster < region.getOffset())
+            return new Region(offsetInMaster, region.getOffset() - offsetInMaster);
+
+        for (int i= 0; i < fragments.length - 1; i++) {
+            IRegion left= fragments[i];
+            IRegion right= fragments[i + 1];
+            int leftEnd= left.getOffset() + left.getLength();
+            if (leftEnd < right.getOffset())
+                return new Region(leftEnd, right.getOffset() - leftEnd);
+        }
+
+        region= fragments[fragments.length - 1];
+        int leftEnd= region.getOffset() + region.getLength();
+        int rightEnd= offsetInMaster + lengthInMaster;
+        if (leftEnd < rightEnd)
+            return new Region(leftEnd, rightEnd - leftEnd);
+
+        return null;
+    }
+
+    /**
+     * Ensures that the given range of the master document is part of this
+     * projection document.
+     *
+     * @param offsetInMaster the offset of the master document range
+     * @param lengthInMaster the length of the master document range
+     * @throws BadLocationException in case the master event is not valid
+     */
+    public void addMasterDocumentRange(int offsetInMaster, int lengthInMaster)  {
+        addMasterDocumentRange(offsetInMaster, lengthInMaster, null);
+    }
+
+    /**
+     * Ensures that the given range of the master document is part of this
+     * projection document.
+     *
+     * @param offsetInMaster the offset of the master document range
+     * @param lengthInMaster the length of the master document range
+     * @param masterDocumentEvent the master document event which causes this
+     *            projection change, or <code>null</code> if none
+     * @throws BadLocationException in case the master event is not valid
+     */
+    private void addMasterDocumentRange(int offsetInMaster, int lengthInMaster, DocumentEvent masterDocumentEvent)  {
+        /*
+         * Calling internalAddMasterDocumentRange may cause other master ranges
+         * to become unfolded, resulting in re-entrant calls to this method. In
+         * order to not add a region twice, we have to compute the next region
+         * to add in every iteration.
+         *
+         * To place an upper bound on the number of iterations, we use the number
+         * of fragments * 2 as the limit.
+         */
+        int limit= Math.max(getFragments().length * 2, 20);
+        while (true) {
+            if (limit-- < 0)
+                throw new IllegalArgumentException("safety loop termination"); //$NON-NLS-1$
+
+            IRegion gap= computeFirstUnprojectedMasterRegion(offsetInMaster, lengthInMaster);
+            if (gap is null)
+                return;
+
+            internalAddMasterDocumentRange(gap.getOffset(), gap.getLength(), masterDocumentEvent);
+        }
+    }
+
+    /**
+     * Ensures that the given range of the master document is not part of this
+     * projection document.
+     *
+     * @param offsetInMaster the offset of the master document range
+     * @param lengthInMaster the length of the master document range
+     * @throws BadLocationException in case the master event is not valid
+     */
+    public void removeMasterDocumentRange(int offsetInMaster, int lengthInMaster)  {
+        IRegion[] fragments= computeProjectedMasterRegions(offsetInMaster, lengthInMaster);
+        if (fragments is null || fragments.length is 0)
+            return;
+
+        for (int i= 0; i < fragments.length; i++) {
+            IRegion fragment= fragments[i];
+            internalRemoveMasterDocumentRange(fragment.getOffset(), fragment.getLength());
+        }
+    }
+
+    /**
+     * Returns the sequence of all master document regions with are contained in the given master document
+     * range and which are part of this projection document. May return <code>null</code> if no such
+     * regions exist.
+     *
+     * @param offsetInMaster the range offset in the master document
+     * @param lengthInMaster the range length in the master document
+     * @return the sequence of regions which are part of the projection document or <code>null</code>
+     * @throws BadLocationException in case the given range is invalid in the master document
+     */
+    public final IRegion[] computeProjectedMasterRegions(int offsetInMaster, int lengthInMaster)  {
+        IRegion imageRegion= fMapping.toImageRegion(new Region(offsetInMaster, lengthInMaster));
+        return imageRegion !is null ? fMapping.toExactOriginRegions(imageRegion) : null;
+    }
+
+    /**
+     * Returns whether this projection is being updated.
+     *
+     * @return <code>true</code> if the document is updating
+     */
+    protected bool isUpdating() {
+        return fIsUpdating;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#replace(int, int, java.lang.String)
+     */
+    public void replace(int offset, int length, String text)  {
+        try {
+            fIsUpdating= true;
+            if (fMasterDocumentExtension !is null)
+                fMasterDocumentExtension.stopPostNotificationProcessing();
+
+            super.replace(offset, length, text);
+
+        } finally {
+            fIsUpdating= false;
+            if (fMasterDocumentExtension !is null)
+                fMasterDocumentExtension.resumePostNotificationProcessing();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocument#set(java.lang.String)
+     */
+    public void set(String text) {
+        try {
+            fIsUpdating= true;
+            if (fMasterDocumentExtension !is null)
+                fMasterDocumentExtension.stopPostNotificationProcessing();
+
+            super.set(text);
+
+        } finally {
+            fIsUpdating= false;
+            if (fMasterDocumentExtension !is null)
+                fMasterDocumentExtension.resumePostNotificationProcessing();
+        }
+    }
+
+    /**
+     * Transforms a document event of the master document into a projection
+     * document based document event.
+     *
+     * @param masterEvent the master document event
+     * @return the slave document event
+     * @throws BadLocationException in case the master event is not valid
+     */
+    private ProjectionDocumentEvent normalize(DocumentEvent masterEvent)  {
+        if (!isUpdating()) {
+            IRegion imageRegion= fMapping.toExactImageRegion(new Region(masterEvent.getOffset(), masterEvent.getLength()));
+            if (imageRegion !is null)
+                return new ProjectionDocumentEvent(this, imageRegion.getOffset(), imageRegion.getLength(), masterEvent.getText(), masterEvent);
+            return null;
+        }
+
+        ProjectionDocumentEvent event= new ProjectionDocumentEvent(this, fOriginalEvent.getOffset(), fOriginalEvent.getLength(), fOriginalEvent.getText(), masterEvent);
+        fOriginalEvent= null;
+        return event;
+    }
+
+    /**
+     * Ensures that when the master event affects this projection document, that the whole region described by the
+     * event is part of this projection document.
+     *
+     * @param masterEvent the master document event
+     * @return <code>true</code> if masterEvent affects this projection document
+     * @throws BadLocationException in case the master event is not valid
+     */
+    protected final bool adaptProjectionToMasterChange(DocumentEvent masterEvent)  {
+        if (!isUpdating() && fFragmentsUpdater.affectsPositions(masterEvent) || fIsAutoExpanding && masterEvent.getLength() > 0) {
+
+            addMasterDocumentRange(masterEvent.getOffset(), masterEvent.getLength(), masterEvent);
+            return true;
+
+        } else if (fMapping.getImageLength() is 0 && masterEvent.getLength() is 0) {
+
+            Position[] fragments= getFragments();
+            if (fragments.length is 0) {
+                // there is no segment in this projection document, thus one must be created
+                // need to bypass the usual infrastructure as the new segment/fragment would be of length 0 and thus the segmentation be not well formed
+                try {
+                    Fragment fragment= new Fragment(0, 0);
+                    fMasterDocument.addPosition(fFragmentsCategory, fragment);
+                    createSegmentFor(fragment, 0);
+                } catch (BadPositionCategoryException x) {
+                    internalError();
+                }
+            }
+        }
+
+        return isUpdating();
+    }
+
+    /**
+     * When called, this projection document is informed about a forthcoming
+     * change of its master document. This projection document checks whether
+     * the master document change affects it and if so informs all document
+     * listeners.
+     *
+     * @param masterEvent the master document event
+     */
+    public void masterDocumentAboutToBeChanged(DocumentEvent masterEvent) {
+        try {
+
+            bool assertNotNull= adaptProjectionToMasterChange(masterEvent);
+            fSlaveEvent= normalize(masterEvent);
+            if (assertNotNull && fSlaveEvent is null)
+                internalError();
+
+            fMasterEvent= masterEvent;
+            if (fSlaveEvent !is null)
+                delayedFireDocumentAboutToBeChanged();
+
+        } catch (BadLocationException e) {
+            internalError();
+        }
+    }
+
+    /**
+     * When called, this projection document is informed about a change of its
+     * master document. If this projection document is affected it informs all
+     * of its document listeners.
+     *
+     * @param masterEvent the master document event
+     */
+    public void masterDocumentChanged(DocumentEvent masterEvent) {
+        if ( !isUpdating() && masterEvent is fMasterEvent) {
+            if (fSlaveEvent !is null) {
+                try {
+                    getTracker().replace(fSlaveEvent.getOffset(), fSlaveEvent.getLength(), fSlaveEvent.getText());
+                    fireDocumentChanged(fSlaveEvent);
+                } catch (BadLocationException e) {
+                    internalError();
+                }
+            } else if (ensureWellFormedSegmentation(masterEvent.getOffset()))
+                fMapping.projectionChanged();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractDocument#fireDocumentAboutToBeChanged(dwtx.jface.text.DocumentEvent)
+     */
+    protected void fireDocumentAboutToBeChanged(DocumentEvent event) {
+        fOriginalEvent= event;
+        // delay it until there is a notification from the master document
+        // at this point, it is expensive to construct the master document information
+    }
+
+    /**
+     * Fires the slave document event as about-to-be-changed event to all registered listeners.
+     */
+    private void delayedFireDocumentAboutToBeChanged() {
+        super.fireDocumentAboutToBeChanged(fSlaveEvent);
+    }
+
+    /**
+     * Ignores the given event and sends the semantically equal slave document event instead.
+     *
+     * @param event the event to be ignored
+     */
+    protected void fireDocumentChanged(DocumentEvent event) {
+        super.fireDocumentChanged(fSlaveEvent);
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractDocument#updateDocumentStructures(dwtx.jface.text.DocumentEvent)
+     */
+    protected void updateDocumentStructures(DocumentEvent event) {
+        super.updateDocumentStructures(event);
+        ensureWellFormedSegmentation(computeAnchor(event));
+        fMapping.projectionChanged();
+    }
+
+    private int computeAnchor(DocumentEvent event) {
+        if ( cast(ProjectionDocumentEvent)event ) {
+            ProjectionDocumentEvent slave= cast(ProjectionDocumentEvent) event;
+            Object changeType= slave.getChangeType();
+            if (ProjectionDocumentEvent.CONTENT_CHANGE is changeType) {
+                DocumentEvent master= slave.getMasterEvent();
+                if (master !is null)
+                    return master.getOffset();
+            } else if (ProjectionDocumentEvent.PROJECTION_CHANGE is changeType) {
+                return slave.getMasterOffset();
+            }
+        }
+        return -1;
+    }
+
+    private bool ensureWellFormedSegmentation(int anchorOffset) {
+        bool changed= false;
+        Position[] segments= getSegments();
+        for (int i= 0; i < segments.length; i++) {
+            Segment segment= cast(Segment) segments[i];
+            if (segment.isDeleted() || segment.getLength() is 0) {
+                try {
+                    removePosition(fSegmentsCategory, segment);
+                    fMasterDocument.removePosition(fFragmentsCategory, segment.fragment);
+                    changed= true;
+                } catch (BadPositionCategoryException e) {
+                    internalError();
+                }
+            } else if (i < segments.length - 1) {
+                Segment next= cast(Segment) segments[i + 1];
+                if (next.isDeleted() || next.getLength() is 0)
+                    continue;
+                Fragment fragment= segment.fragment;
+                if (fragment.getOffset() + fragment.getLength() is next.fragment.getOffset()) {
+                    // join fragments and their corresponding segments
+                    segment.setLength(segment.getLength() + next.getLength());
+                    fragment.setLength(fragment.getLength() + next.fragment.getLength());
+                    next.delete_();
+                }
+            }
+        }
+
+        if (changed && anchorOffset !is -1) {
+            Position[] changedSegments= getSegments();
+            if (changedSegments is null || changedSegments.length is 0) {
+                Fragment fragment= new Fragment(anchorOffset, 0);
+                try {
+                    fMasterDocument.addPosition(fFragmentsCategory, fragment);
+                    createSegmentFor(fragment, 0);
+                } catch (BadLocationException e) {
+                    internalError();
+                } catch (BadPositionCategoryException e) {
+                    internalError();
+                }
+            }
+        }
+
+        return changed;
+    }
+
+    /*
+     * @see IDocumentExtension#registerPostNotificationReplace(IDocumentListener, IDocumentExtension.IReplace)
+     */
+    public void registerPostNotificationReplace(IDocumentListener owner, IDocumentExtension.IReplace replace) {
+        if (!isUpdating())
+            throw new UnsupportedOperationException();
+        super.registerPostNotificationReplace(owner, replace);
+    }
+
+    /**
+     * Sets the auto expand mode for this document.
+     *
+     * @param autoExpandMode <code>true</code> if auto-expanding
+     */
+    public void setAutoExpandMode(bool autoExpandMode) {
+        fIsAutoExpanding= autoExpandMode;
+    }
+
+    /**
+     * Replaces all master document ranges with the given master document range.
+     *
+     * @param offsetInMaster the offset in the master document
+     * @param lengthInMaster the length in the master document
+     * @throws BadLocationException if the given range of the master document is not valid
+     */
+    public void replaceMasterDocumentRanges(int offsetInMaster, int lengthInMaster)  {
+        try {
+
+            ProjectionDocumentEvent event= new ProjectionDocumentEvent(this, 0, fMapping.getImageLength(), fMasterDocument.get(offsetInMaster, lengthInMaster), offsetInMaster, lengthInMaster);
+            super.fireDocumentAboutToBeChanged(event);
+
+            Position[] fragments= getFragments();
+            for (int i= 0; i < fragments.length; i++) {
+                Fragment fragment= cast(Fragment) fragments[i];
+                fMasterDocument.removePosition(fFragmentsCategory, fragment);
+                removePosition(fSegmentsCategory, fragment.segment);
+            }
+
+            Fragment fragment= new Fragment(offsetInMaster, lengthInMaster);
+            Segment segment= new Segment(0, 0);
+            segment.fragment= fragment;
+            fragment.segment= segment;
+            fMasterDocument.addPosition(fFragmentsCategory, fragment);
+            addPosition(fSegmentsCategory, segment);
+
+            getTracker().set(fMasterDocument.get(offsetInMaster, lengthInMaster));
+            super.fireDocumentChanged(event);
+
+        } catch (BadPositionCategoryException x) {
+            internalError();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/projection/ProjectionDocumentEvent.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.projection.ProjectionDocumentEvent;
+
+import dwtx.jface.text.projection.ProjectionMapping; // packageimport
+import dwtx.jface.text.projection.ChildDocumentManager; // packageimport
+import dwtx.jface.text.projection.SegmentUpdater; // packageimport
+import dwtx.jface.text.projection.Segment; // packageimport
+import dwtx.jface.text.projection.ProjectionDocument; // packageimport
+import dwtx.jface.text.projection.FragmentUpdater; // packageimport
+import dwtx.jface.text.projection.ChildDocument; // packageimport
+import dwtx.jface.text.projection.IMinimalMapping; // packageimport
+import dwtx.jface.text.projection.Fragment; // packageimport
+import dwtx.jface.text.projection.ProjectionTextStore; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.SlaveDocumentEvent;
+
+
+/**
+ * This event is sent out by an
+ * {@link dwtx.jface.text.projection.ProjectionDocument}when it is
+ * manipulated. The manipulation is either a content manipulation or a change of
+ * the projection between the master and the slave. Clients can determine the
+ * type of change by asking the projection document event for its change type
+ * (see {@link #getChangeType()}) and comparing it with the predefined types
+ * {@link #PROJECTION_CHANGE}and {@link #CONTENT_CHANGE}.
+ * <p>
+ * Clients are not supposed to create instances of this class. Instances are
+ * created by {@link dwtx.jface.text.projection.ProjectionDocument}
+ * instances. This class is not intended to be subclassed.</p>
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ProjectionDocumentEvent : SlaveDocumentEvent {
+
+    /** The change type indicating a projection change */
+    private static Object PROJECTION_CHANGE_;
+    public static Object PROJECTION_CHANGE(){
+        if( PROJECTION_CHANGE_ is null ) {
+            synchronized( ProjectionDocumentEvent.classinfo ) {
+                if( PROJECTION_CHANGE_ is null ) {
+                    PROJECTION_CHANGE_ = new Object();
+                }
+            }
+        }
+        return PROJECTION_CHANGE_;
+    }
+    /** The change type indicating a content change */
+    private static Object CONTENT_CHANGE_;
+    public static Object CONTENT_CHANGE(){
+        if( CONTENT_CHANGE_ is null ) {
+            synchronized( ProjectionDocumentEvent.classinfo ) {
+                if( CONTENT_CHANGE_ is null ) {
+                    CONTENT_CHANGE_ = new Object();
+                }
+            }
+        }
+        return CONTENT_CHANGE_;
+    }
+
+    /** The change type */
+    private Object fChangeType;
+    /** The offset of the change in the master document */
+    private int fMasterOffset= -1;
+    /** The length of the change in the master document */
+    private int fMasterLength= -1;
+
+    /**
+     * Creates a new content change event caused by the given master document
+     * change. Instances created using this constructor return <code>-1</code>
+     * when calling <code>getMasterOffset</code> or
+     * <code>getMasterLength</code>. This information can be obtained by
+     * accessing the master event.
+     *
+     * @param doc the changed projection document
+     * @param offset the offset in the projection document
+     * @param length the length in the projection document
+     * @param text the replacement text
+     * @param masterEvent the original master event
+     */
+    public this(IDocument doc, int offset, int length, String text, DocumentEvent masterEvent) {
+        super(doc, offset, length, text, masterEvent);
+        fChangeType= CONTENT_CHANGE;
+    }
+
+    /**
+     * Creates a new projection change event for the given properties. Instances
+     * created with this constructor return the given master document offset and
+     * length but do not have an associated master document event.
+     *
+     * @param doc the projection document
+     * @param offset the offset in the projection document
+     * @param length the length in the projection document
+     * @param text the replacement text
+     * @param masterOffset the offset in the master document
+     * @param masterLength the length in the master document
+     */
+    public this(IDocument doc, int offset, int length, String text, int masterOffset, int masterLength) {
+        super(doc, offset, length, text, null);
+        fChangeType= PROJECTION_CHANGE;
+        fMasterOffset= masterOffset;
+        fMasterLength= masterLength;
+    }
+
+    /**
+     * Creates a new projection document event for the given properties. The
+     * projection change is caused by a manipulation of the master document. In
+     * order to accommodate the master document change, the projection document
+     * had to change the projection. Instances created with this constructor
+     * return the given master document offset and length and also have an
+     * associated master document event.
+     *
+     * @param doc the projection document
+     * @param offset the offset in the projection document
+     * @param length the length in the projection document
+     * @param text the replacement text
+     * @param masterOffset the offset in the master document
+     * @param masterLength the length in the master document
+     * @param masterEvent the master document event
+     */
+    public this(IDocument doc, int offset, int length, String text, int masterOffset, int masterLength, DocumentEvent masterEvent) {
+        super(doc, offset, length, text, masterEvent);
+        fChangeType= PROJECTION_CHANGE;
+        fMasterOffset= masterOffset;
+        fMasterLength= masterLength;
+    }
+
+    /**
+     * Returns the change type of this event. This is either {@link #PROJECTION_CHANGE} or
+     * {@link #CONTENT_CHANGE}.
+     *
+     * @return the change type of this event
+     */
+    public Object getChangeType() {
+        return fChangeType;
+    }
+
+    /**
+     * Returns the offset of the master document range that has been added or removed in case this
+     * event describes a projection change, otherwise it returns <code>-1</code>.
+     *
+     * @return the master document offset of the projection change or <code>-1</code>
+     */
+    public int getMasterOffset() {
+        return fMasterOffset;
+    }
+
+    /**
+     * Returns the length of the master document range that has been added or removed in case this event
+     * describes a projection changed, otherwise <code>-1</code>.
+     *
+     * @return the master document length of the projection change or <code>-1</code>
+     */
+    public int getMasterLength() {
+        return fMasterLength;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/projection/ProjectionDocumentManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,242 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.projection.ProjectionDocumentManager;
+
+import dwtx.jface.text.projection.ProjectionMapping; // packageimport
+import dwtx.jface.text.projection.ChildDocumentManager; // packageimport
+import dwtx.jface.text.projection.SegmentUpdater; // packageimport
+import dwtx.jface.text.projection.Segment; // packageimport
+import dwtx.jface.text.projection.ProjectionDocument; // packageimport
+import dwtx.jface.text.projection.FragmentUpdater; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport
+import dwtx.jface.text.projection.ChildDocument; // packageimport
+import dwtx.jface.text.projection.IMinimalMapping; // packageimport
+import dwtx.jface.text.projection.Fragment; // packageimport
+import dwtx.jface.text.projection.ProjectionTextStore; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentInformationMapping;
+import dwtx.jface.text.IDocumentListener;
+import dwtx.jface.text.ISlaveDocumentManager;
+import dwtx.jface.text.ISlaveDocumentManagerExtension;
+
+
+/**
+ * A <code>ProjectionDocumentManager</code> is one particular implementation
+ * of {@link dwtx.jface.text.ISlaveDocumentManager}. This manager
+ * creates so called projection documents (see
+ * {@link dwtx.jface.text.projection.ProjectionDocument}as slave
+ * documents for given master documents.
+ * <p>
+ * A projection document represents a particular projection of the master
+ * document and is accordingly adapted to changes of the master document. Vice
+ * versa, the master document is accordingly adapted to changes of its slave
+ * documents. The manager does not maintain any particular management structure
+ * but utilizes mechanisms given by {@link dwtx.jface.text.IDocument}
+ * such as position categories and position updaters.
+ * <p>
+ * Clients can instantiate this class. This class is not intended to be
+ * subclassed.</p>
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ProjectionDocumentManager : IDocumentListener, ISlaveDocumentManager, ISlaveDocumentManagerExtension {
+
+    /** Registry for master documents and their projection documents. */
+    private Map fProjectionRegistry;
+
+    this(){
+        fProjectionRegistry= new HashMap();
+    }
+
+    /**
+     * Registers the given projection document for the given master document.
+     *
+     * @param master the master document
+     * @param projection the projection document
+     */
+    private void add(IDocument master, ProjectionDocument projection) {
+        List list= cast(List) fProjectionRegistry.get(cast(Object)master);
+        if (list is null) {
+            list= new ArrayList(1);
+            fProjectionRegistry.put(cast(Object)master, cast(Object)list);
+        }
+        list.add(projection);
+    }
+
+    /**
+     * Unregisters the given projection document from its master.
+     *
+     * @param master the master document
+     * @param projection the projection document
+     */
+    private void remove(IDocument master, ProjectionDocument projection) {
+        List list= cast(List) fProjectionRegistry.get(cast(Object)master);
+        if (list !is null) {
+            list.remove(projection);
+            if (list.size() is 0)
+                fProjectionRegistry.remove(cast(Object)master);
+        }
+    }
+
+    /**
+     * Returns whether the given document is a master document.
+     *
+     * @param master the document
+     * @return <code>true</code> if the given document is a master document known to this manager
+     */
+    private bool hasProjection(IDocument master) {
+        return ( null !is cast(List)fProjectionRegistry.get(cast(Object)master) );
+    }
+
+    /**
+     * Returns an iterator enumerating all projection documents registered for the given document or
+     * <code>null</code> if the document is not a known master document.
+     *
+     * @param master the document
+     * @return an iterator for all registered projection documents or <code>null</code>
+     */
+    private Iterator getProjectionsIterator(IDocument master) {
+        List list= cast(List) fProjectionRegistry.get(cast(Object)master);
+        if (list !is null)
+            return list.iterator();
+        return null;
+    }
+
+    /**
+     * Informs all projection documents of the master document that issued the given document event.
+     *
+     * @param about indicates whether the change is about to happen or happened already
+     * @param masterEvent the document event which will be processed to inform the projection documents
+     */
+    protected void fireDocumentEvent(bool about, DocumentEvent masterEvent) {
+        IDocument master= masterEvent.getDocument();
+        Iterator e= getProjectionsIterator(master);
+        if (e is null)
+            return;
+
+        while (e.hasNext()) {
+            ProjectionDocument document= cast(ProjectionDocument) e.next();
+            if (about)
+                document.masterDocumentAboutToBeChanged(masterEvent);
+            else
+                document.masterDocumentChanged(masterEvent);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentListener#documentChanged(dwtx.jface.text.DocumentEvent)
+     */
+    public void documentChanged(DocumentEvent event) {
+        fireDocumentEvent(false, event);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentListener#documentAboutToBeChanged(dwtx.jface.text.DocumentEvent)
+     */
+    public void documentAboutToBeChanged(DocumentEvent event) {
+        fireDocumentEvent(true, event);
+    }
+
+    /*
+     * @see dwtx.jface.text.ISlaveDocumentManager#createMasterSlaveMapping(dwtx.jface.text.IDocument)
+     */
+    public IDocumentInformationMapping createMasterSlaveMapping(IDocument slave) {
+        if ( cast(ProjectionDocument)slave ) {
+            ProjectionDocument projectionDocument= cast(ProjectionDocument) slave;
+            return projectionDocument.getDocumentInformationMapping();
+        }
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.ISlaveDocumentManager#createSlaveDocument(dwtx.jface.text.IDocument)
+     */
+    public IDocument createSlaveDocument(IDocument master) {
+        if (!hasProjection(master))
+            master.addDocumentListener(this);
+        ProjectionDocument slave= createProjectionDocument(master);
+        add(master, slave);
+        return slave;
+    }
+
+    /**
+     * Factory method for projection documents.
+     *
+     * @param master the master document
+     * @return the newly created projection document
+     */
+    protected ProjectionDocument createProjectionDocument(IDocument master) {
+        return new ProjectionDocument(master);
+    }
+
+    /*
+     * @see dwtx.jface.text.ISlaveDocumentManager#freeSlaveDocument(dwtx.jface.text.IDocument)
+     */
+    public void freeSlaveDocument(IDocument slave) {
+        if ( cast(ProjectionDocument)slave ) {
+            ProjectionDocument projectionDocument= cast(ProjectionDocument) slave;
+            IDocument master= projectionDocument.getMasterDocument();
+            remove(master, projectionDocument);
+            projectionDocument.dispose();
+            if (!hasProjection(master))
+                master.removeDocumentListener(this);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ISlaveDocumentManager#getMasterDocument(dwtx.jface.text.IDocument)
+     */
+    public IDocument getMasterDocument(IDocument slave) {
+        if ( cast(ProjectionDocument)slave )
+            return (cast(ProjectionDocument) slave).getMasterDocument();
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.ISlaveDocumentManager#isSlaveDocument(dwtx.jface.text.IDocument)
+     */
+    public bool isSlaveDocument(IDocument document) {
+        return ( null !is cast(ProjectionDocument)document );
+    }
+
+    /*
+     * @see dwtx.jface.text.ISlaveDocumentManager#setAutoExpandMode(dwtx.jface.text.IDocument, bool)
+     */
+    public void setAutoExpandMode(IDocument slave, bool autoExpanding) {
+        if ( cast(ProjectionDocument)slave )
+            (cast(ProjectionDocument) slave).setAutoExpandMode(autoExpanding);
+    }
+
+    /*
+     * @see dwtx.jface.text.ISlaveDocumentManagerExtension#getSlaveDocuments(dwtx.jface.text.IDocument)
+     */
+    public IDocument[] getSlaveDocuments(IDocument master) {
+        List list= cast(List) fProjectionRegistry.get(cast(Object)master);
+        if (list !is null) {
+            return arraycast!(IDocument)(list.toArray());
+        }
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/projection/ProjectionMapping.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,723 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.projection.ProjectionMapping;
+
+import dwtx.jface.text.projection.ChildDocumentManager; // packageimport
+import dwtx.jface.text.projection.SegmentUpdater; // packageimport
+import dwtx.jface.text.projection.Segment; // packageimport
+import dwtx.jface.text.projection.ProjectionDocument; // packageimport
+import dwtx.jface.text.projection.FragmentUpdater; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport
+import dwtx.jface.text.projection.ChildDocument; // packageimport
+import dwtx.jface.text.projection.IMinimalMapping; // packageimport
+import dwtx.jface.text.projection.Fragment; // packageimport
+import dwtx.jface.text.projection.ProjectionTextStore; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentInformationMapping;
+import dwtx.jface.text.IDocumentInformationMappingExtension;
+import dwtx.jface.text.IDocumentInformationMappingExtension2;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+
+
+/**
+ * Internal class. Do not use. Only public for testing purposes.
+ * <p>
+ * Implementation of {@link dwtx.jface.text.IDocumentInformationMapping}
+ * for the projection mapping between a master and a slave document.
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ProjectionMapping : IDocumentInformationMapping , IDocumentInformationMappingExtension, IDocumentInformationMappingExtension2, IMinimalMapping {
+
+    private static const int LEFT=  -1;
+    private static const int NONE=   0;
+    private static const int RIGHT= +1;
+
+    /** The master document */
+    private IDocument fMasterDocument;
+    /** The position category used to manage the projection fragments inside the master document */
+    private String fFragmentsCategory;
+    /** The projection document */
+    private IDocument fSlaveDocument;
+    /** The position category to manage the projection segments inside the slave document. */
+    private String fSegmentsCategory;
+    /** Cached segments */
+    private Position[] fCachedSegments;
+    /** Cached fragments */
+    private Position[] fCachedFragments;
+
+    /**
+     * Creates a new mapping between the given parent document and the given projection document.
+     *
+     * @param masterDocument the master document
+     * @param fragmentsCategory the position category of the parent document used to manage the projected regions
+     * @param slaveDocument the slave document
+     * @param segmentsCategory the position category of the projection document used to manage the fragments
+     */
+    public this(IDocument masterDocument, String fragmentsCategory, IDocument slaveDocument, String segmentsCategory) {
+        fMasterDocument= masterDocument;
+        fFragmentsCategory= fragmentsCategory;
+        fSlaveDocument= slaveDocument;
+        fSegmentsCategory= segmentsCategory;
+    }
+
+    /**
+     * Notifies this projection mapping that there was a projection change.
+     */
+    public void projectionChanged() {
+        fCachedSegments= null;
+        fCachedFragments= null;
+    }
+
+    private Position[] getSegments() {
+        if (fCachedSegments is null) {
+            try {
+                fCachedSegments= fSlaveDocument.getPositions(fSegmentsCategory);
+            } catch (BadPositionCategoryException e) {
+                return new Position[0];
+            }
+        }
+        return fCachedSegments;
+    }
+
+    private Position[] getFragments() {
+        if (fCachedFragments is null) {
+            try {
+                fCachedFragments= fMasterDocument.getPositions(fFragmentsCategory);
+            } catch (BadPositionCategoryException e) {
+                return new Position[0];
+            }
+        }
+        return fCachedFragments;
+    }
+
+    private int findSegmentIndex(int offset)  {
+        Position[] segments= getSegments();
+        if (segments.length is 0) {
+            if (offset > 0)
+                throw new BadLocationException();
+            return -1;
+        }
+
+        try {
+            int index= fSlaveDocument.computeIndexInCategory(fSegmentsCategory, offset);
+            if (index is segments.length && offset > exclusiveEnd(segments[index-1]))
+                throw new BadLocationException();
+
+            if (index < segments.length && offset is segments[index].offset)
+                return index;
+
+            if (index > 0)
+                index--;
+
+            return index;
+
+        } catch (BadPositionCategoryException e) {
+            throw new IllegalStateException();
+        }
+    }
+
+    private Segment findSegment(int offset)  {
+
+        checkImageOffset(offset);
+
+        int index= findSegmentIndex(offset);
+        if (index is -1) {
+
+            Segment s= new Segment(0, 0);
+            Fragment f= new Fragment(0, 0);
+            s.fragment= f;
+            f.segment= s;
+            return s;
+        }
+
+        Position[] segments= getSegments();
+        return cast(Segment) segments[index];
+    }
+
+    /**
+     * Computes the fragment index given an origin offset. Returns the index of
+     * the fragment that contains <code>offset</code>, or <code>-1</code>
+     * if no fragment contains <code>offset</code>.
+     * <p>
+     * If <code>extensionDirection</code> is set to <code>RIGHT</code> or
+     * <code>LEFT</code>, the next fragment in that direction is returned if
+     * there is no fragment containing <code>offset</code>. Note that if
+     * <code>offset</code> occurs before any fragment and
+     * <code>extensionDirection</code> is <code>LEFT</code>,
+     * <code>-1</code> is also returned. The same applies for an offset after
+     * the last fragment and <code>extensionDirection</code> set to
+     * <code>RIGHT</code>.
+     * </p>
+     *
+     * @param offset an origin offset
+     * @param extensionDirection the direction in which to extend the search, or
+     *        <code>NONE</code>
+     * @return the index of the fragment containing <code>offset</code>, or
+     *         <code>-1</code>
+     * @throws BadLocationException if the index is not valid on the master
+     *         document
+     */
+    private int findFragmentIndex(int offset, int extensionDirection)  {
+        try {
+
+            Position[] fragments= getFragments();
+            if (fragments.length is 0)
+                return -1;
+
+            int index= fMasterDocument.computeIndexInCategory(fFragmentsCategory, offset);
+
+            if (index < fragments.length && offset is fragments[index].offset)
+                return index;
+
+            if (0 < index && index <= fragments.length && fragments[index - 1].includes(offset))
+                return index - 1;
+
+            switch (extensionDirection) {
+                case LEFT:
+                    return index - 1;
+                case RIGHT:
+                    if (index < fragments.length)
+                        return index;
+            }
+
+            return -1;
+
+        } catch (BadPositionCategoryException e) {
+            throw new IllegalStateException();
+        }
+    }
+
+    private Fragment findFragment(int offset)  {
+        checkOriginOffset(offset);
+
+        int index= findFragmentIndex(offset, NONE);
+        Position[] fragments= getFragments();
+        if (index is -1) {
+            if (fragments.length > 0) {
+                Fragment last= cast(Fragment) fragments[fragments.length - 1];
+                if (exclusiveEnd(last) is offset)
+                    return last;
+            }
+            return null;
+        }
+        return cast(Fragment) fragments[index];
+    }
+
+    /**
+     * Returns the image region for <code>originRegion</code>.
+     *
+     * @param originRegion the region to get the image for
+     * @param exact if <code>true</code>, the begin and end offsets of
+     *        <code>originRegion</code> must be projected, otherwise
+     *        <code>null</code> is returned. If <code>false</code>, the
+     *        begin and end range that is not visible is simply clipped.
+     * @param takeClosestImage if <code>false</code>, <code>null</code> is
+     *        returned if <code>originRegion</code> is completely invisible.
+     *        If <code>true</code>, the zero-length region is returned that
+     *        "covers" the hidden origin region
+     * @return the image region of <code>originRegion</code>
+     * @throws BadLocationException if the region is not a valid origin region
+     */
+    private IRegion toImageRegion(IRegion originRegion, bool exact, bool takeClosestImage)  {
+        if (originRegion.getLength() is 0 && !takeClosestImage) {
+            int imageOffset= toImageOffset(originRegion.getOffset());
+            return imageOffset is -1 ? null : new Region(imageOffset, 0);
+        }
+
+        Fragment[] fragments= findFragments(originRegion, exact, takeClosestImage);
+        if (fragments is null) {
+            if (takeClosestImage) {
+                // originRegion may before the first or after the last fragment
+                Position[] allFragments= getFragments();
+                if (allFragments.length > 0) {
+                    // before the first
+                    if (exclusiveEnd(originRegion) <= allFragments[0].getOffset())
+                        return new Region(0, 0);
+                    // after last
+                    Position last= allFragments[allFragments.length - 1];
+                    if (originRegion.getOffset() >= exclusiveEnd(last))
+                        return new Region(exclusiveEnd((cast(Fragment) last).segment), 0);
+                }
+                return new Region(0, 0);
+            }
+            return null;
+        }
+
+        int imageOffset, exclusiveImageEndOffset;
+
+        // translate start offset
+        int relative= originRegion.getOffset() - fragments[0].getOffset();
+        if (relative < 0) {
+            Assert.isTrue(!exact);
+            relative= 0;
+        }
+        imageOffset= fragments[0].segment.getOffset() + relative;
+
+        // translate end offset
+        relative= exclusiveEnd(originRegion) - fragments[1].getOffset();
+        if (relative > fragments[1].getLength()) {
+            Assert.isTrue(!exact);
+            relative= fragments[1].getLength();
+        }
+        exclusiveImageEndOffset= fragments[1].segment.getOffset() + relative;
+
+        return new Region(imageOffset, exclusiveImageEndOffset - imageOffset);
+    }
+
+    /**
+     * Returns the two fragments containing the begin and end offsets of
+     * <code>originRegion</code>.
+     *
+     * @param originRegion the region to get the fragments for
+     * @param exact if <code>true</code>, only the fragments that contain the
+     *        begin and end offsets are returned; if <code>false</code>, the
+     *        first fragment after the begin offset and the last fragment before
+     *        the end offset are returned if the offsets are not projected
+     * @param takeClosestImage if <code>true</code>, the method will return
+     *        fragments also if <code>originRegion</code> completely lies in
+     *        an unprojected region.
+     * @return the two fragments containing the begin and end offset of
+     *         <code>originRegion</code>, or <code>null</code> if these do
+     *         not exist
+     * @throws BadLocationException if the region is not a valid origin region
+     */
+    private Fragment[] findFragments(IRegion originRegion, bool exact, bool takeClosestImage)  {
+        Position[] fragments= getFragments();
+        if (fragments.length is 0)
+            return null;
+
+        checkOriginRegion(originRegion);
+
+        int startFragmentIdx= findFragmentIndex(originRegion.getOffset(), exact ? NONE : RIGHT);
+        if (startFragmentIdx is -1)
+            return null;
+
+        int endFragmentIdx= findFragmentIndex(inclusiveEnd(originRegion), exact ? NONE : LEFT);
+        if (!takeClosestImage && startFragmentIdx > endFragmentIdx || endFragmentIdx is -1)
+            return null;
+
+        Fragment[] result= [cast(Fragment) fragments[startFragmentIdx], cast(Fragment) fragments[endFragmentIdx]];
+        return result;
+    }
+
+    private IRegion createOriginStartRegion(Segment image, int offsetShift) {
+        return new Region(image.fragment.getOffset() + offsetShift, image.fragment.getLength() - offsetShift);
+    }
+
+    private IRegion createOriginRegion(Segment image) {
+        return new Region(image.fragment.getOffset(), image.fragment.getLength());
+    }
+
+    private IRegion createOriginEndRegion(Segment image, int lengthReduction) {
+        return new Region(image.fragment.getOffset(), image.fragment.getLength() - lengthReduction);
+    }
+
+    private IRegion createImageStartRegion(Fragment origin, int offsetShift) {
+        int shift= offsetShift > 0 ? offsetShift : 0;
+        return new Region(origin.segment.getOffset() + shift, origin.segment.getLength() - shift);
+    }
+
+    private IRegion createImageRegion(Fragment origin) {
+        return new Region(origin.segment.getOffset(), origin.segment.getLength());
+    }
+
+    private IRegion createImageEndRegion(Fragment origin, int lengthReduction) {
+        int reduction= lengthReduction > 0 ? lengthReduction : 0;
+        return new Region(origin.segment.getOffset(), origin.segment.getLength() - reduction);
+    }
+
+    private IRegion createOriginStartRegion(Fragment origin, int offsetShift) {
+        int shift= offsetShift > 0 ? offsetShift : 0;
+        return new Region(origin.getOffset() + shift, origin.getLength() - shift);
+    }
+
+    private IRegion createOriginRegion(Fragment origin) {
+        return new Region(origin.getOffset(), origin.getLength());
+    }
+
+    private IRegion createOriginEndRegion(Fragment origin, int lengthReduction) {
+        int reduction= lengthReduction > 0 ? lengthReduction : 0;
+        return new Region(origin.getOffset(), origin.getLength() - reduction);
+    }
+
+    private IRegion getIntersectingRegion(IRegion left, IRegion right) {
+        int offset= Math.max(left.getOffset(), right.getOffset());
+        int exclusiveEndOffset= Math.min(exclusiveEnd(left), exclusiveEnd(right));
+        if (exclusiveEndOffset < offset)
+            return null;
+        return new Region(offset, exclusiveEndOffset - offset);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMapping#getCoverage()
+     */
+    public IRegion getCoverage() {
+        Position[] fragments= getFragments();
+        if (fragments !is null && fragments.length > 0) {
+            Position first=fragments[0];
+            Position last= fragments[fragments.length -1];
+            return  new Region(first.offset, exclusiveEnd(last) - first.offset);
+        }
+        return new Region(0, 0);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMapping#toOriginOffset(int)
+     */
+    public int toOriginOffset(int imageOffset)  {
+        Segment segment= findSegment(imageOffset);
+        int relative= imageOffset - segment.offset;
+        return segment.fragment.offset + relative;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMapping#toOriginRegion(dwtx.jface.text.IRegion)
+     */
+    public IRegion toOriginRegion(IRegion imageRegion)  {
+        int imageOffset= imageRegion.getOffset();
+        int imageLength= imageRegion.getLength();
+
+        if (imageLength is 0) {
+            if (imageOffset is 0) {
+                Position[] fragments= getFragments();
+                if (fragments.length is 0 || (fragments.length is 1 && fragments[0].getOffset() is 0 && fragments[0].getLength() is 0))
+                    return new Region(0, fMasterDocument.getLength());
+            }
+            return new Region(toOriginOffset(imageOffset), 0);
+        }
+
+        int originOffset= toOriginOffset(imageOffset);
+        int inclusiveImageEndOffset= imageOffset + imageLength -1;
+        int inclusiveOriginEndOffset= toOriginOffset(inclusiveImageEndOffset);
+
+        return new Region(originOffset, (inclusiveOriginEndOffset + 1) - originOffset);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMapping#toOriginLines(int)
+     */
+    public IRegion toOriginLines(int imageLine)  {
+        IRegion imageRegion= fSlaveDocument.getLineInformation(imageLine);
+        IRegion originRegion= toOriginRegion(imageRegion);
+
+        int originStartLine= fMasterDocument.getLineOfOffset(originRegion.getOffset());
+        if (originRegion.getLength() is 0)
+            return new Region(originStartLine, 1);
+
+        int originEndLine= fMasterDocument.getLineOfOffset(inclusiveEnd(originRegion));
+        return new Region(originStartLine, (originEndLine + 1) - originStartLine);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMapping#toOriginLine(int)
+     */
+    public int toOriginLine(int imageLine)  {
+        IRegion lines= toOriginLines(imageLine);
+        return (lines.getLength() > 1 ? -1 : lines.getOffset());
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMapping#toImageOffset(int)
+     */
+    public int toImageOffset(int originOffset)  {
+        Fragment fragment= findFragment(originOffset);
+        if (fragment !is null) {
+            int relative= originOffset - fragment.offset;
+            return fragment.segment.offset + relative;
+        }
+        return -1;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMappingExtension#toExactImageRegion(dwtx.jface.text.IRegion)
+     */
+    public IRegion toExactImageRegion(IRegion originRegion)  {
+        return toImageRegion(originRegion, true, false);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMapping#toImageRegion(dwtx.jface.text.IRegion)
+     */
+    public IRegion toImageRegion(IRegion originRegion)  {
+        return toImageRegion(originRegion, false, false);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMappingExtension2#toClosestImageRegion(dwtx.jface.text.IRegion)
+     * @since 3.1
+     */
+    public IRegion toClosestImageRegion(IRegion originRegion)  {
+        return toImageRegion(originRegion, false, true);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMapping#toImageLine(int)
+     */
+    public int toImageLine(int originLine)  {
+        IRegion originRegion= fMasterDocument.getLineInformation(originLine);
+        IRegion imageRegion= toImageRegion(originRegion);
+        if (imageRegion is null) {
+            int imageOffset= toImageOffset(originRegion.getOffset());
+            if (imageOffset > -1)
+                imageRegion= new Region(imageOffset, 0);
+            else
+                return -1;
+        }
+
+        int startLine= fSlaveDocument.getLineOfOffset(imageRegion.getOffset());
+        if (imageRegion.getLength() is 0)
+            return startLine;
+
+        int endLine= fSlaveDocument.getLineOfOffset(imageRegion.getOffset() + imageRegion.getLength());
+        if (endLine !is startLine)
+            throw new IllegalStateException();
+
+        return startLine;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMapping#toClosestImageLine(int)
+     */
+    public int toClosestImageLine(int originLine)  {
+        try {
+
+            int imageLine= toImageLine(originLine);
+            if (imageLine > -1)
+                return imageLine;
+
+            Position[] fragments= getFragments();
+            if (fragments.length is 0)
+                return -1;
+
+            IRegion originLineRegion= fMasterDocument.getLineInformation(originLine);
+            int index= fMasterDocument.computeIndexInCategory(fFragmentsCategory, originLineRegion.getOffset());
+
+            if (0 < index && index < fragments.length) {
+                Fragment left= cast(Fragment) fragments[index - 1];
+                int leftDistance= originLineRegion.getOffset() - (exclusiveEnd(left));
+                Fragment right= cast(Fragment) fragments[index];
+                int rightDistance= right.getOffset() - (exclusiveEnd(originLineRegion));
+
+                if (leftDistance <= rightDistance)
+                    originLine= fMasterDocument.getLineOfOffset(left.getOffset() + Math.max(left.getLength() - 1, 0));
+                else
+                    originLine= fMasterDocument.getLineOfOffset(right.getOffset());
+
+            } else if (index is 0) {
+                Fragment right= cast(Fragment) fragments[index];
+                originLine= fMasterDocument.getLineOfOffset(right.getOffset());
+            } else if (index is fragments.length) {
+                Fragment left= cast(Fragment) fragments[index - 1];
+                originLine= fMasterDocument.getLineOfOffset(exclusiveEnd(left));
+            }
+
+            return toImageLine(originLine);
+
+        } catch (BadPositionCategoryException x) {
+        }
+
+        return -1;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMappingExtension#toExactOriginRegions(dwtx.jface.text.IRegion)
+     */
+    public IRegion[] toExactOriginRegions(IRegion imageRegion)  {
+
+        if (imageRegion.getLength() is 0)
+            return [ new Region(toOriginOffset(imageRegion.getOffset()), 0) ];
+
+        int endOffset= exclusiveEnd(imageRegion);
+        Position[] segments= getSegments();
+        int firstIndex= findSegmentIndex(imageRegion.getOffset());
+        int lastIndex= findSegmentIndex(endOffset - 1);
+
+        int resultLength= lastIndex - firstIndex + 1;
+        IRegion[] result= new IRegion[resultLength];
+
+        // first
+        result[0]= createOriginStartRegion(cast(Segment) segments[firstIndex], imageRegion.getOffset() - segments[firstIndex].getOffset());
+        // middles
+        for (int i= 1; i < resultLength - 1; i++)
+            result[i]= createOriginRegion(cast(Segment) segments[firstIndex + i]);
+        // last
+        Segment last= cast(Segment) segments[lastIndex];
+        int segmentEndOffset= exclusiveEnd(last);
+        IRegion lastRegion= createOriginEndRegion(last, segmentEndOffset - endOffset);
+        if (resultLength > 1) {
+            // first !is last
+            result[resultLength - 1]= lastRegion;
+        } else {
+            // merge first and last
+            IRegion intersection= getIntersectingRegion(result[0], lastRegion);
+            if (intersection is null)
+                result= new IRegion[0];
+            else
+                result[0]= intersection;
+        }
+
+        return result;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMappingExtension#getImageLength()
+     */
+    public int getImageLength() {
+        Position[] segments= getSegments();
+        int length= 0;
+        for (int i= 0; i < segments.length; i++)
+            length += segments[i].length;
+        return length;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMappingExtension#toExactImageRegions(dwtx.jface.text.IRegion)
+     */
+    public IRegion[] toExactImageRegions(IRegion originRegion)  {
+
+        int offset= originRegion.getOffset();
+        if (originRegion.getLength() is 0) {
+            int imageOffset= toImageOffset(offset);
+            return imageOffset > -1 ? [ cast(IRegion) new Region(imageOffset, 0) ] : null;
+        }
+
+        int endOffset= exclusiveEnd(originRegion);
+        Position[] fragments= getFragments();
+        int firstIndex= findFragmentIndex(offset, RIGHT);
+        int lastIndex= findFragmentIndex(endOffset - 1, LEFT);
+
+        if (firstIndex is -1 || firstIndex > lastIndex)
+            return null;
+
+        int resultLength= lastIndex - firstIndex + 1;
+        IRegion[] result= new IRegion[resultLength];
+
+        // first
+        result[0]= createImageStartRegion(cast(Fragment) fragments[firstIndex], offset - fragments[firstIndex].getOffset());
+        // middles
+        for (int i= 1; i < resultLength - 1; i++)
+            result[i]= createImageRegion(cast(Fragment) fragments[firstIndex + i]);
+        // last
+        Fragment last= cast(Fragment) fragments[lastIndex];
+        int fragmentEndOffset= exclusiveEnd(last);
+        IRegion lastRegion= createImageEndRegion(last, fragmentEndOffset - endOffset);
+        if (resultLength > 1) {
+            // first !is last
+            result[resultLength - 1]= lastRegion;
+        } else {
+            // merge first and last
+            IRegion intersection= getIntersectingRegion(result[0], lastRegion);
+            if (intersection is null)
+                return null;
+            result[0]= intersection;
+        }
+
+        return result;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentInformationMappingExtension#getExactCoverage(dwtx.jface.text.IRegion)
+     */
+    public IRegion[] getExactCoverage(IRegion originRegion)  {
+
+        int originOffset= originRegion.getOffset();
+        int originLength= originRegion.getLength();
+
+        if (originLength is 0) {
+            int imageOffset= toImageOffset(originOffset);
+            return imageOffset > -1 ? [ cast(IRegion)new Region(originOffset, 0) ] : null;
+        }
+
+        int endOffset= originOffset + originLength;
+        Position[] fragments= getFragments();
+        int firstIndex= findFragmentIndex(originOffset, RIGHT);
+        int lastIndex= findFragmentIndex(endOffset - 1, LEFT);
+
+        if (firstIndex is -1 || firstIndex > lastIndex)
+            return null;
+
+        int resultLength= lastIndex - firstIndex + 1;
+        IRegion[] result= new IRegion[resultLength];
+
+        // first
+        result[0]= createOriginStartRegion(cast(Fragment) fragments[firstIndex], originOffset - fragments[firstIndex].getOffset());
+        // middles
+        for (int i= 1; i < resultLength - 1; i++)
+            result[i]= createOriginRegion(cast(Fragment) fragments[firstIndex + i]);
+        // last
+        Fragment last= cast(Fragment) fragments[lastIndex];
+        int fragmentEndOffset= exclusiveEnd(last);
+        IRegion lastRegion= createOriginEndRegion(last, fragmentEndOffset - endOffset);
+        if (resultLength > 1) {
+            // first !is last
+            result[resultLength - 1]= lastRegion;
+        } else {
+            // merge first and last
+            IRegion intersection= getIntersectingRegion(result[0], lastRegion);
+            if (intersection is null)
+                return null;
+            result[0]= intersection;
+        }
+
+        return result;
+    }
+
+    private final void checkOriginRegion(IRegion originRegion)  {
+        int offset= originRegion.getOffset();
+        int endOffset= inclusiveEnd(originRegion);
+        int max= fMasterDocument.getLength();
+        if (offset < 0 || offset > max || endOffset < 0 || endOffset > max)
+            throw new BadLocationException();
+    }
+
+    private final void checkOriginOffset(int originOffset)  {
+        if (originOffset < 0 || originOffset > fMasterDocument.getLength())
+            throw new BadLocationException();
+    }
+
+    private final void checkImageOffset(int imageOffset)  {
+        if (imageOffset < 0 || imageOffset > getImageLength())
+            throw new BadLocationException();
+    }
+
+    private final int exclusiveEnd(Position position) {
+        return position.offset + position.length;
+    }
+
+    private final int exclusiveEnd(IRegion region) {
+        return region.getOffset() + region.getLength();
+    }
+
+    private final int inclusiveEnd(IRegion region) {
+        int length= region.getLength();
+        if (length is 0)
+            return region.getOffset();
+        return region.getOffset() + length - 1;
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/projection/ProjectionTextStore.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,176 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.projection.ProjectionTextStore;
+
+import dwtx.jface.text.projection.ProjectionMapping; // packageimport
+import dwtx.jface.text.projection.ChildDocumentManager; // packageimport
+import dwtx.jface.text.projection.SegmentUpdater; // packageimport
+import dwtx.jface.text.projection.Segment; // packageimport
+import dwtx.jface.text.projection.ProjectionDocument; // packageimport
+import dwtx.jface.text.projection.FragmentUpdater; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport
+import dwtx.jface.text.projection.ChildDocument; // packageimport
+import dwtx.jface.text.projection.IMinimalMapping; // packageimport
+import dwtx.jface.text.projection.Fragment; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextStore;
+import dwtx.jface.text.Region;
+
+
+/**
+ * A text store representing the projection defined by the given document
+ * information mapping.
+ *
+ * @since 3.0
+ */
+class ProjectionTextStore : ITextStore {
+
+    /**
+     * Implementation of {@link IRegion} that can be reused
+     * by setting the offset and the length.
+     */
+    private static class ReusableRegion : IRegion {
+
+        private int fOffset;
+        private int fLength;
+
+        /*
+         * @see dwtx.jface.text.IRegion#getLength()
+         */
+        public int getLength() {
+            return fLength;
+        }
+
+        /*
+         * @see dwtx.jface.text.IRegion#getOffset()
+         */
+        public int getOffset() {
+            return fOffset;
+        }
+
+        /**
+         * Updates this region.
+         *
+         * @param offset the new offset
+         * @param length the new length
+         */
+        public void update(int offset, int length) {
+            fOffset= offset;
+            fLength= length;
+        }
+    }
+
+    /** The master document */
+    private IDocument fMasterDocument;
+    /** The document information mapping */
+    private IMinimalMapping fMapping;
+    /** Internal region used for querying the mapping. */
+    private ReusableRegion fReusableRegion;
+
+
+    /**
+     * Creates a new projection text store for the given master document and
+     * the given document information mapping.
+     *
+     * @param masterDocument the master document
+     * @param mapping the document information mapping
+     */
+    public this(IDocument masterDocument, IMinimalMapping mapping) {
+        fReusableRegion= new ReusableRegion();
+        fMasterDocument= masterDocument;
+        fMapping= mapping;
+    }
+
+    private void internalError() {
+        throw new IllegalStateException();
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#set(java.lang.String)
+     */
+    public void set(String contents) {
+
+        IRegion masterRegion= fMapping.getCoverage();
+        if (masterRegion is null)
+            internalError();
+
+        try {
+            fMasterDocument.replace(masterRegion.getOffset(), masterRegion.getLength(), contents);
+        } catch (BadLocationException e) {
+            internalError();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#replace(int, int, java.lang.String)
+     */
+    public void replace(int offset, int length, String text) {
+        fReusableRegion.update(offset, length);
+        try {
+            IRegion masterRegion= fMapping.toOriginRegion(fReusableRegion);
+            fMasterDocument.replace(masterRegion.getOffset(), masterRegion.getLength(), text);
+        } catch (BadLocationException e) {
+            internalError();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#getLength()
+     */
+    public int getLength() {
+        return fMapping.getImageLength();
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextStore#get(int)
+     */
+    public char get(int offset) {
+        try {
+            int originOffset= fMapping.toOriginOffset(offset);
+            return fMasterDocument.getChar(originOffset);
+        } catch (BadLocationException e) {
+            internalError();
+        }
+
+        // unreachable
+        return cast(wchar) 0;
+    }
+
+    /*
+     * @see ITextStore#get(int, int)
+     */
+    public String get(int offset, int length) {
+        try {
+            IRegion[] fragments= fMapping.toExactOriginRegions(new Region(offset, length));
+            StringBuffer buffer= new StringBuffer();
+            for (int i= 0; i < fragments.length; i++) {
+                IRegion fragment= fragments[i];
+                buffer.append(fMasterDocument.get(fragment.getOffset(), fragment.getLength()));
+            }
+            return buffer.toString();
+        } catch (BadLocationException e) {
+            internalError();
+        }
+
+        // unreachable
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/projection/Segment.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.projection.Segment;
+
+import dwtx.jface.text.projection.ProjectionMapping; // packageimport
+import dwtx.jface.text.projection.ChildDocumentManager; // packageimport
+import dwtx.jface.text.projection.SegmentUpdater; // packageimport
+import dwtx.jface.text.projection.ProjectionDocument; // packageimport
+import dwtx.jface.text.projection.FragmentUpdater; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport
+import dwtx.jface.text.projection.ChildDocument; // packageimport
+import dwtx.jface.text.projection.IMinimalMapping; // packageimport
+import dwtx.jface.text.projection.Fragment; // packageimport
+import dwtx.jface.text.projection.ProjectionTextStore; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.Position;
+
+
+/**
+ * Internal class. Do not use. Only public for testing purposes.
+ * <p>
+ * A segment is the image of a master document fragment in a projection
+ * document.
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Segment : Position {
+
+    /** The corresponding fragment for this segment. */
+    public Fragment fragment;
+    /** A flag indicating that the segment updater should stretch this segment when a change happens at its boundaries. */
+    public bool isMarkedForStretch_;
+    /** A flag indicating that the segment updater should shift this segment when a change happens at its boundaries. */
+    public bool isMarkedForShift_;
+
+    /**
+     * Creates a new segment covering the given range.
+     *
+     * @param offset the offset of the segment
+     * @param length the length of the segment
+     */
+    public this(int offset, int length) {
+        super(offset, length);
+    }
+
+    /**
+     * Sets the stretching flag.
+     */
+    public void markForStretch() {
+        isMarkedForStretch_= true;
+    }
+
+    /**
+     * Returns <code>true</code> if the stretching flag is set, <code>false</code> otherwise.
+     * @return <code>true</code> if the stretching flag is set, <code>false</code> otherwise
+     */
+    public bool isMarkedForStretch() {
+        return isMarkedForStretch_;
+    }
+    public bool isMarkedForStretch(bool v) {
+        isMarkedForStretch_ = v;
+        return isMarkedForStretch();
+    }
+
+    /**
+     * Sets the shifting flag.
+     */
+    public void markForShift() {
+        isMarkedForShift_= true;
+    }
+
+    /**
+     * Returns <code>true</code> if the shifting flag is set, <code>false</code> otherwise.
+     * @return <code>true</code> if the shifting flag is set, <code>false</code> otherwise
+     */
+    public bool isMarkedForShift() {
+        return isMarkedForShift_;
+    }
+    public bool isMarkedForShift(bool v) {
+        isMarkedForShift_ = v;
+        return isMarkedForShift();
+    }
+
+    /**
+     * Clears the shifting and the stretching flag.
+     */
+    public void clearMark() {
+        isMarkedForStretch_= false;
+        isMarkedForShift_= false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/projection/SegmentUpdater.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,146 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.projection.SegmentUpdater;
+
+import dwtx.jface.text.projection.ProjectionMapping; // packageimport
+import dwtx.jface.text.projection.ChildDocumentManager; // packageimport
+import dwtx.jface.text.projection.Segment; // packageimport
+import dwtx.jface.text.projection.ProjectionDocument; // packageimport
+import dwtx.jface.text.projection.FragmentUpdater; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentEvent; // packageimport
+import dwtx.jface.text.projection.ChildDocument; // packageimport
+import dwtx.jface.text.projection.IMinimalMapping; // packageimport
+import dwtx.jface.text.projection.Fragment; // packageimport
+import dwtx.jface.text.projection.ProjectionTextStore; // packageimport
+import dwtx.jface.text.projection.ProjectionDocumentManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DefaultPositionUpdater;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.Position;
+
+
+/**
+ * The position updater used to adapt the segments of a projection document to
+ * changes of the master document. Depending on the flags set on a segment, a
+ * segment is either extended to shifted if an insertion happens at a segment's
+ * offset. The last segment is extended if an insert operation happens at the
+ * end of the segment.
+ *
+ * @since 3.0
+ */
+class SegmentUpdater : DefaultPositionUpdater {
+
+    private Segment fNextSegment= null;
+    private bool fIsProjectionChange= false;
+
+    /**
+     * Creates the segment updater for the given category.
+     *
+     * @param segmentCategory the position category used for managing the segments of a projection document
+     */
+    /+protected+/ this(String segmentCategory) {
+        super(segmentCategory);
+    }
+
+    /*
+     * @see dwtx.jface.text.IPositionUpdater#update(dwtx.jface.text.DocumentEvent)
+     */
+    public void update(DocumentEvent event) {
+
+        Assert.isTrue( null !is cast(ProjectionDocumentEvent)event );
+        fIsProjectionChange= (cast(ProjectionDocumentEvent) event).getChangeType() is ProjectionDocumentEvent.PROJECTION_CHANGE;
+
+        try {
+
+            Position[] category= event.getDocument().getPositions(getCategory());
+
+            fOffset= event.getOffset();
+            fLength= event.getLength();
+            fReplaceLength= (event.getText() is null ? 0 : event.getText().length());
+            fDocument= event.getDocument();
+
+            for (int i= 0; i < category.length; i++) {
+
+                fPosition= category[i];
+                Assert.isTrue( null !is cast(Segment)fPosition );
+
+                if (i < category.length - 1)
+                    fNextSegment= cast(Segment) category[i + 1];
+                else
+                    fNextSegment= null;
+
+                fOriginalPosition.offset= fPosition.offset;
+                fOriginalPosition.length= fPosition.length;
+
+                if (notDeleted())
+                    adaptToReplace();
+
+            }
+
+        } catch (BadPositionCategoryException x) {
+            // do nothing
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.DefaultPositionUpdater#adaptToInsert()
+     */
+    protected void adaptToInsert() {
+
+        Segment segment= cast(Segment) fPosition;
+        int myStart= segment.offset;
+        int myEnd= segment.offset + segment.length - (segment.isMarkedForStretch || fNextSegment is null || isAffectingReplace() ? 0 : 1);
+        myEnd= Math.max(myStart, myEnd);
+        int yoursStart= fOffset;
+
+        try {
+
+            if (myEnd < yoursStart)
+                return;
+
+            if (segment.isMarkedForStretch) {
+                Assert.isTrue(fIsProjectionChange);
+                segment.isMarkedForShift= false;
+                if (fNextSegment !is null) {
+                    fNextSegment.isMarkedForShift= true;
+                    fNextSegment.isMarkedForStretch= false;
+                }
+            }
+
+            if (fLength <= 0) {
+
+                if (myStart < (yoursStart + (segment.isMarkedForShift ? 0 : 1)))
+                    fPosition.length += fReplaceLength;
+                else
+                    fPosition.offset += fReplaceLength;
+
+            } else {
+
+                if (myStart <= yoursStart && fOriginalPosition.offset <= yoursStart)
+                    fPosition.length += fReplaceLength;
+                else
+                    fPosition.offset += fReplaceLength;
+            }
+
+        } finally {
+            segment.clearMark();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/quickassist/IQuickAssistAssistant.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.quickassist.IQuickAssistAssistant;
+
+import dwtx.jface.text.quickassist.QuickAssistAssistant; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistAssistantExtension; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistInvocationContext; // packageimport
+import dwtx.jface.text.quickassist.IQuickFixableAnnotation; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistProcessor; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+import dwt.graphics.Color;
+import dwtx.jface.preference.JFacePreferences;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.contentassist.ICompletionListener;
+import dwtx.jface.text.source.Annotation;
+import dwtx.jface.text.source.ISourceViewer;
+import dwtx.jface.text.source.ISourceViewerExtension3;
+
+
+/**
+ * An <code>IQuickAssistAssistant</code> provides support for quick fixes and quick
+ * assists.
+ * The quick assist assistant is a {@link ISourceViewer} add-on. Its
+ * purpose is to propose, display, and insert quick assists and quick fixes
+ * available at the current source viewer's quick assist invocation context.
+ * <p>
+ * The quick assist assistant can be configured with a {@link IQuickAssistProcessor}
+ * which provides the possible quick assist and quick fix completions.
+ * </p>
+ * In order to provide backward compatibility for clients of
+ * <code>IQuickAssistAssistant</code>, extension interfaces are used to
+ * provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link IQuickAssistAssistantExtension} since version 3.4 introducing the
+ * following function:
+ * <ul>
+ *  <li>allows to get a handler for the given command identifier</li>
+ *  <li>allows to enable support for colored labels in the proposal popup</li>
+ * </ul>
+ * </li>
+ * </p>
+ * <p>
+ * The interface can be implemented by clients. By default, clients use
+ * {@link QuickAssistAssistant} as the standard
+ * implementer of this interface.
+ * </p>
+ *
+ * @see ISourceViewer
+ * @see IQuickAssistProcessor
+ * @see IQuickAssistAssistantExtension
+ * @since 3.2
+ */
+ public interface IQuickAssistAssistant {
+
+    /**
+     * Installs quick assist support on the given source viewer.
+     * <p>
+     * <strong>Note:</strong> This quick assist assistant will only be able to query the invocation context
+     * if <code>sourceViewer</code> also implements {@link ISourceViewerExtension3}.
+     * </p>
+     *
+     * @param sourceViewer the source viewer on which quick assist will work
+     */
+    void install(ISourceViewer sourceViewer);
+
+    /**
+     * Sets the information control creator for the additional information control.
+     *
+     * @param creator the information control creator for the additional information control
+     */
+    void setInformationControlCreator(IInformationControlCreator creator);
+
+    /**
+     * Uninstalls quick assist support from the source viewer it has
+     * previously be installed on.
+     */
+    void uninstall();
+
+    /**
+     * Shows all possible quick fixes and quick assists at the viewer's cursor position.
+     *
+     * @return an optional error message if no proposals can be computed
+     */
+    String showPossibleQuickAssists();
+    
+    /**
+     * Registers a given quick assist processor for a particular content type. If there is already
+     * a processor registered, the new processor is registered instead of the old one.
+     *
+     * @param processor the quick assist processor to register, or <code>null</code> to remove
+     *        an existing one
+     */
+    void setQuickAssistProcessor(IQuickAssistProcessor processor);
+    
+    /**
+     * Returns the quick assist processor to be used for the given content type.
+     *
+     * @return the quick assist processor or <code>null</code> if none exists
+     */
+    IQuickAssistProcessor getQuickAssistProcessor();
+    
+    /**
+     * Tells whether this assistant has a fix for the given annotation.
+     * <p>
+     * <strong>Note:</strong> This test must be fast and optimistic i.e. it is OK to return
+     * <code>true</code> even though there might be no quick fix.
+     * </p>
+     * 
+     * @param annotation the annotation
+     * @return <code>true</code> if the assistant has a fix for the given annotation
+     */
+    bool canFix(Annotation annotation);
+    
+    /**
+     * Tells whether this assistant has assists for the given invocation context.
+     * 
+     * @param invocationContext the invocation context
+     * @return <code>true</code> if the assistant has a fix for the given annotation
+     */
+    bool canAssist(IQuickAssistInvocationContext invocationContext);
+    
+    /**
+     * Sets the proposal selector's background color.
+     * <p>
+     * <strong>Note:</strong> As of 3.4, you should only call this
+     * method if you want to override the {@link JFacePreferences#CONTENT_ASSIST_BACKGROUND_COLOR}.
+     * </p>
+     *
+     * @param background the background color
+     */
+    void setProposalSelectorBackground(Color background);
+
+    /**
+     * Sets the proposal's foreground color.
+     * <p>
+     * <strong>Note:</strong> As of 3.4, you should only call this
+     * method if you want to override the {@link JFacePreferences#CONTENT_ASSIST_FOREGROUND_COLOR}.
+     * </p>
+     *
+     * @param foreground the foreground color
+     */
+    void setProposalSelectorForeground(Color foreground);
+    
+    /**
+     * Adds a completion listener that will be informed before proposals are computed.
+     * 
+     * @param listener the listener
+     */
+    void addCompletionListener(ICompletionListener listener);
+
+    /**
+     * Removes a completion listener.
+     * 
+     * @param listener the listener to remove
+     */
+    void removeCompletionListener(ICompletionListener listener);
+    
+    /**
+     * Enables displaying a status line below the proposal popup. The default is not to show the
+     * status line. The contents of the status line may be set via {@link #setStatusMessage(String)}.
+     * 
+     * @param show <code>true</code> to show a message line, <code>false</code> to not show one.
+     */
+    public void setStatusLineVisible(bool show);
+
+    /**
+     * Sets the caption message displayed at the bottom of the completion proposal popup.
+     * 
+     * @param message the message
+     */
+    public void setStatusMessage(String message);
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/quickassist/IQuickAssistAssistantExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright (c) 2007, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.quickassist.IQuickAssistAssistantExtension;
+
+import dwtx.jface.text.quickassist.QuickAssistAssistant; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistAssistant; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistInvocationContext; // packageimport
+import dwtx.jface.text.quickassist.IQuickFixableAnnotation; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistProcessor; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.commands.IHandler;
+import dwtx.jface.text.contentassist.ICompletionProposalExtension6;
+
+
+/**
+ * Extends {@link IQuickAssistAssistant} with the following function:
+ * <ul>
+ *  <li>allows to get a handler for the given command identifier</li>
+ *  <li>allows to enable support for colored labels in the proposal popup</li>
+ * </ul>
+ * 
+ * @since 3.4
+ */
+public interface IQuickAssistAssistantExtension {
+
+    /**
+     * Returns the handler for the given command identifier.
+     * <p>
+     * The same handler instance will be returned when called a more than once
+     * with the same command identifier.
+     * </p>
+     * 
+     * @param commandId the command identifier
+     * @return the handler for the given command identifier
+     * @throws IllegalArgumentException if the command is not supported by this
+     *             content assistant
+     * @throws IllegalStateException if called when this content assistant is
+     *             uninstalled
+     */
+    IHandler getHandler(String commandId);
+
+    /**
+     * Enables the support for colored labels in the proposal popup.
+     * <p>Completion proposals can implement {@link ICompletionProposalExtension6}
+     * to provide colored proposal labels.</p>
+     * 
+     * @param isEnabled if <code>true</code> the support for colored labels is enabled in the proposal popup
+     * @since 3.4
+     */
+    void enableColoredLabels(bool isEnabled);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/quickassist/IQuickAssistInvocationContext.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.quickassist.IQuickAssistInvocationContext;
+
+import dwtx.jface.text.quickassist.QuickAssistAssistant; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistAssistant; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistAssistantExtension; // packageimport
+import dwtx.jface.text.quickassist.IQuickFixableAnnotation; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistProcessor; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.source.ISourceViewer;
+
+
+/**
+ * Context information for quick fix and quick assist processors.
+ * <p>
+ * This interface can be implemented by clients.</p>
+ * 
+ * @since 3.2
+ */
+public interface IQuickAssistInvocationContext {
+
+    /**
+     * Returns the offset where quick assist was invoked.
+     * 
+     * @return the invocation offset or <code>-1</code> if unknown
+     */
+    int getOffset();
+
+    /**
+     * Returns the length of the selection at the invocation offset.
+     * 
+     * @return the length of the current selection or <code>-1</code> if none or unknown
+     */
+    int getLength();
+    
+    /**
+     * Returns the viewer for this context.
+     * 
+     * @return the viewer or <code>null</code> if not available
+     */
+    ISourceViewer getSourceViewer();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/quickassist/IQuickAssistProcessor.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.quickassist.IQuickAssistProcessor;
+
+import dwtx.jface.text.quickassist.QuickAssistAssistant; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistAssistant; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistAssistantExtension; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistInvocationContext; // packageimport
+import dwtx.jface.text.quickassist.IQuickFixableAnnotation; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.contentassist.ICompletionProposal;
+import dwtx.jface.text.source.Annotation;
+
+
+/**
+ * Quick assist processor for quick fixes and quick assists.
+ * <p>
+ * A processor can provide just quick fixes, just quick assists
+ * or both.
+ * </p>
+ * <p>
+ * This interface can be implemented by clients.</p>
+ * 
+ * @since 3.2
+ */
+public interface IQuickAssistProcessor {
+
+    /**
+     * Returns the reason why this quick assist processor
+     * was unable to produce any completion proposals.
+     *
+     * @return an error message or <code>null</code> if no error occurred
+     */
+    String getErrorMessage();
+
+    /**
+     * Tells whether this processor has a fix for the given annotation.
+     * <p>
+     * <strong>Note:</strong> This test must be fast and optimistic i.e. it is OK to return
+     * <code>true</code> even though there might be no quick fix.
+     * </p>
+     * 
+     * @param annotation the annotation
+     * @return <code>true</code> if the assistant has a fix for the given annotation
+     */
+    bool canFix(Annotation annotation);
+    
+    /**
+     * Tells whether this assistant has assists for the given invocation context.
+     * 
+     * @param invocationContext the invocation context
+     * @return <code>true</code> if the assistant has a fix for the given annotation
+     */
+    bool canAssist(IQuickAssistInvocationContext invocationContext);
+    
+    /**
+     * Returns a list of quick assist and quick fix proposals for the
+     * given invocation context.
+     *
+     * @param invocationContext the invocation context
+     * @return an array of completion proposals or <code>null</code> if no proposals are available
+     */
+    ICompletionProposal[] computeQuickAssistProposals(IQuickAssistInvocationContext invocationContext);
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/quickassist/IQuickFixableAnnotation.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.quickassist.IQuickFixableAnnotation;
+
+import dwtx.jface.text.quickassist.QuickAssistAssistant; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistAssistant; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistAssistantExtension; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistInvocationContext; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistProcessor; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.AssertionFailedException;
+import dwtx.jface.text.source.Annotation;
+
+
+/**
+ * Allows an annotation to tell whether there are quick fixes
+ * for it and to cache that state.
+ * <p>
+ * Caching the state is important to improve overall performance as calling
+ * {@link dwtx.jface.text.quickassist.IQuickAssistAssistant#canFix(Annotation)}
+ * can be expensive.
+ * </p>
+ * <p>
+ * This interface can be implemented by clients.</p>
+ * 
+ * @since 3.2
+ */
+public interface IQuickFixableAnnotation {
+
+    /**
+     * Sets whether there are quick fixes available for
+     * this annotation.
+     * 
+     * @param state <code>true</code> if there are quick fixes available, false otherwise
+     */
+    void setQuickFixable(bool state);
+
+    /**
+     * Tells whether the quick fixable state has been set.
+     * <p>
+     * Normally this means {@link #setQuickFixable(bool)} has been
+     * called at least once but it can also be hard-coded, e.g. always
+     * return <code>true</code>.
+     * </p>
+     * 
+     * @return <code>true</code> if the state has been set
+     */
+    bool isQuickFixableStateSet();
+
+    /**
+     * Tells whether there are quick fixes for this annotation.
+     * <p>
+     * <strong>Note:</strong> This method must only be called
+     * if {@link #isQuickFixableStateSet()} returns <code>true</code>.</p>
+     * 
+     * @return <code>true</code> if this annotation offers quick fixes
+     * @throws AssertionFailedException if called when {@link #isQuickFixableStateSet()} is <code>false</code>
+     */
+    bool isQuickFixable() ;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/quickassist/QuickAssistAssistant.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,270 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.quickassist.QuickAssistAssistant;
+
+import dwtx.jface.text.quickassist.IQuickAssistAssistant; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistAssistantExtension; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistInvocationContext; // packageimport
+import dwtx.jface.text.quickassist.IQuickFixableAnnotation; // packageimport
+import dwtx.jface.text.quickassist.IQuickAssistProcessor; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+import dwt.graphics.Color;
+import dwtx.core.commands.IHandler;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.contentassist.ContentAssistant;
+import dwtx.jface.text.contentassist.ICompletionListener;
+import dwtx.jface.text.contentassist.ICompletionProposal;
+import dwtx.jface.text.contentassist.IContentAssistProcessor;
+import dwtx.jface.text.contentassist.IContextInformation;
+import dwtx.jface.text.contentassist.IContextInformationValidator;
+import dwtx.jface.text.source.Annotation;
+import dwtx.jface.text.source.ISourceViewer;
+import dwtx.jface.text.source.TextInvocationContext;
+
+
+/**
+ * Default implementation of <code>IQuickAssistAssistant</code>.
+ *
+ * @since 3.2
+ */
+public class QuickAssistAssistant : IQuickAssistAssistant, IQuickAssistAssistantExtension {
+
+
+    private static final class QuickAssistAssistantImpl : ContentAssistant {
+        /*
+         * @see dwtx.jface.text.contentassist.ContentAssistant#possibleCompletionsClosed()
+         */
+        public void possibleCompletionsClosed() {
+            super.possibleCompletionsClosed();
+        }
+
+        /*
+         * @see dwtx.jface.text.contentassist.ContentAssistant#hide()
+         * @since 3.4
+         */
+        protected void hide() {
+            super.hide();
+        }
+    }
+
+
+    private static final class ContentAssistProcessor : IContentAssistProcessor {
+
+        private IQuickAssistProcessor fQuickAssistProcessor;
+
+        this(IQuickAssistProcessor processor) {
+            fQuickAssistProcessor= processor;
+        }
+
+        /*
+         * @see dwtx.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(dwtx.jface.text.ITextViewer, int)
+         */
+        public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+            // panic code - should not happen
+            if (!( cast(ISourceViewer)viewer ))
+                return null;
+
+            return fQuickAssistProcessor.computeQuickAssistProposals(new TextInvocationContext(cast(ISourceViewer)viewer, offset, -1));
+        }
+
+        /*
+         * @see dwtx.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(dwtx.jface.text.ITextViewer, int)
+         */
+        public IContextInformation[] computeContextInformation(ITextViewer viewer, int offset) {
+            return null;
+        }
+
+        /*
+         * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+         */
+        public char[] getCompletionProposalAutoActivationCharacters() {
+            return null;
+        }
+
+        /*
+         * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters()
+         */
+        public char[] getContextInformationAutoActivationCharacters() {
+            return null;
+        }
+
+        /*
+         * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getErrorMessage()
+         */
+        public String getErrorMessage() {
+            return null;
+        }
+
+        /*
+         * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator()
+         */
+        public IContextInformationValidator getContextInformationValidator() {
+            return null;
+        }
+
+    }
+
+    private QuickAssistAssistantImpl fQuickAssistAssistantImpl;
+    private IQuickAssistProcessor fQuickAssistProcessor;
+
+    public this() {
+        fQuickAssistAssistantImpl= new QuickAssistAssistantImpl();
+        fQuickAssistAssistantImpl.enableAutoActivation(false);
+        fQuickAssistAssistantImpl.enableAutoInsert(false);
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#showPossibleQuickAssists()
+     */
+    public String showPossibleQuickAssists() {
+        return fQuickAssistAssistantImpl.showPossibleCompletions();
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#getQuickAssistProcessor(java.lang.String)
+     */
+    public IQuickAssistProcessor getQuickAssistProcessor() {
+        return fQuickAssistProcessor;
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#setQuickAssistProcessor(dwtx.jface.text.quickassist.IQuickAssistProcessor)
+     */
+    public void setQuickAssistProcessor(IQuickAssistProcessor processor) {
+        fQuickAssistProcessor= processor;
+        fQuickAssistAssistantImpl.setDocumentPartitioning("__" ~ this.classinfo.name ~ "_partitioning"); //$NON-NLS-1$ //$NON-NLS-2$
+        fQuickAssistAssistantImpl.setContentAssistProcessor(new ContentAssistProcessor(processor), IDocument.DEFAULT_CONTENT_TYPE);
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#canFix(dwtx.jface.text.source.Annotation)
+     */
+    public bool canFix(Annotation annotation) {
+        return fQuickAssistProcessor !is null && fQuickAssistProcessor.canFix(annotation);
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#canAssist(dwtx.jface.text.quickassist.IQuickAssistInvocationContext)
+     */
+    public bool canAssist(IQuickAssistInvocationContext invocationContext) {
+        return fQuickAssistProcessor !is null && fQuickAssistProcessor.canAssist(invocationContext);
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#install(dwtx.jface.text.ITextViewer)
+     */
+    public void install(ISourceViewer sourceViewer) {
+        fQuickAssistAssistantImpl.install(sourceViewer);
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#setInformationControlCreator(dwtx.jface.text.IInformationControlCreator)
+     */
+    public void setInformationControlCreator(IInformationControlCreator creator) {
+        fQuickAssistAssistantImpl.setInformationControlCreator(creator);
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#uninstall()
+     */
+    public void uninstall() {
+        fQuickAssistAssistantImpl.uninstall();
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#setProposalSelectorBackground(dwt.graphics.Color)
+     */
+    public void setProposalSelectorBackground(Color background) {
+        fQuickAssistAssistantImpl.setProposalSelectorBackground(background);
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#setProposalSelectorForeground(dwt.graphics.Color)
+     */
+    public void setProposalSelectorForeground(Color foreground) {
+        fQuickAssistAssistantImpl.setProposalSelectorForeground(foreground);
+    }
+
+    /**
+     * Callback to signal this quick assist assistant that the presentation of the
+     * possible completions has been stopped.
+     */
+    protected void possibleCompletionsClosed() {
+        fQuickAssistAssistantImpl.possibleCompletionsClosed();
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#addCompletionListener(dwtx.jface.text.contentassist.ICompletionListener)
+     */
+    public void addCompletionListener(ICompletionListener listener) {
+        fQuickAssistAssistantImpl.addCompletionListener(listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#removeCompletionListener(dwtx.jface.text.contentassist.ICompletionListener)
+     */
+    public void removeCompletionListener(ICompletionListener listener) {
+        fQuickAssistAssistantImpl.removeCompletionListener(listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#setStatusLineVisible(bool)
+     */
+    public void setStatusLineVisible(bool show) {
+        fQuickAssistAssistantImpl.setStatusLineVisible(show);
+
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistAssistant#setStatusMessage(java.lang.String)
+     */
+    public void setStatusMessage(String message) {
+        fQuickAssistAssistantImpl.setStatusMessage(message);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 3.4
+     */
+    public final IHandler getHandler(String commandId) {
+        return fQuickAssistAssistantImpl.getHandler(commandId);
+    }
+
+    /**
+     * Hides any open pop-ups.
+     *
+     * @since 3.4
+     */
+    protected void hide() {
+        fQuickAssistAssistantImpl.hide();
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 3.4
+     */
+    public void enableColoredLabels(bool isEnabled) {
+        fQuickAssistAssistantImpl.enableColoredLabels(isEnabled);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/reconciler/AbstractReconcileStep.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.reconciler.AbstractReconcileStep;
+
+import dwtx.jface.text.reconciler.IReconciler; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport
+import dwtx.jface.text.reconciler.MonoReconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport
+import dwtx.jface.text.reconciler.Reconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegion; // packageimport
+import dwtx.jface.text.reconciler.IReconcileResult; // packageimport
+import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.IProgressMonitor;
+import dwtx.jface.text.IRegion;
+
+
+/**
+ * Abstract implementation of a reconcile step.
+ *
+ * @since 3.0
+ */
+public abstract class AbstractReconcileStep : IReconcileStep {
+
+    private IReconcileStep fNextStep;
+    private IReconcileStep fPreviousStep;
+    private IProgressMonitor fProgressMonitor;
+    protected IReconcilableModel fInputModel;
+
+    /**
+     * Creates an intermediate reconcile step which adds
+     * the given step to the pipe.
+     *
+     * @param step the reconcile step
+     */
+    public this(IReconcileStep step) {
+        Assert.isNotNull(cast(Object)step);
+        fNextStep= step;
+        fNextStep.setPreviousStep(this);
+    }
+
+    /**
+     * Creates the last reconcile step of the pipe.
+     */
+    public this() {
+    }
+
+    public bool isLastStep() {
+        return fNextStep is null;
+    }
+
+    public bool isFirstStep() {
+        return fPreviousStep is null;
+    }
+
+    /*
+     * @see dwtx.text.reconcilerpipe.IReconcilerResultCollector#setProgressMonitor(dwtx.core.runtime.IProgressMonitor)
+     */
+    public void setProgressMonitor(IProgressMonitor monitor) {
+        fProgressMonitor= monitor;
+
+        if (!isLastStep())
+            fNextStep.setProgressMonitor(monitor);
+    }
+
+    /*
+     * @see dwtx.jface.text.reconciler.IReconcileStep#getProgressMonitor()
+     */
+    public IProgressMonitor getProgressMonitor() {
+        return fProgressMonitor;
+    }
+
+    /*
+     * @see IReconcileStep#reconcile(IRegion)
+     */
+    public final IReconcileResult[] reconcile(IRegion partition) {
+        IReconcileResult[] result= reconcileModel(null, partition);
+        if (!isLastStep()) {
+            fNextStep.setInputModel(getModel());
+            IReconcileResult[] nextResult= fNextStep.reconcile(partition);
+            return merge(result, convertToInputModel(nextResult));
+        }
+        return result;
+    }
+
+    /*
+     * @see IReconcileStep#reconcile(dwtx.jface.text.reconciler.DirtyRegion, dwtx.jface.text.IRegion)
+     */
+    public final IReconcileResult[] reconcile(DirtyRegion dirtyRegion, IRegion subRegion) {
+        IReconcileResult[] result= reconcileModel(dirtyRegion, subRegion);
+        if (!isLastStep()) {
+            fNextStep.setInputModel(getModel());
+            IReconcileResult[] nextResult= fNextStep.reconcile(dirtyRegion, subRegion);
+            return merge(result, convertToInputModel(nextResult));
+        }
+        return result;
+    }
+
+
+    /**
+     * Reconciles the model of this reconcile step. The
+     * result is based on the input model.
+     *
+     * @param dirtyRegion the document region which has been changed
+     * @param subRegion the sub region in the dirty region which should be reconciled
+     * @return an array with reconcile results
+     */
+    abstract protected IReconcileResult[] reconcileModel(DirtyRegion dirtyRegion, IRegion subRegion);
+
+    /**
+     * Adapts the given an array with reconcile results to
+     * this step's input model and returns it.
+     *
+     * @param inputResults an array with reconcile results
+     * @return an array with the reconcile results adapted to the input model
+     */
+    protected IReconcileResult[] convertToInputModel(IReconcileResult[] inputResults) {
+        return inputResults;
+    }
+
+    /**
+     * Merges the two reconcile result arrays.
+     *
+     * @param results1 an array with reconcile results
+     * @param results2 an array with reconcile results
+     * @return an array with the merged reconcile results
+     */
+    private IReconcileResult[] merge(IReconcileResult[] results1, IReconcileResult[] results2) {
+        if (results1 is null)
+            return results2;
+
+        if (results2 is null)
+            return results1;
+
+        // XXX: not yet performance optimized
+        Collection collection= new ArrayList(Arrays.asList(arraycast!(Object)(results1)));
+        collection.addAll(Arrays.asList(arraycast!(Object)(results2)));
+        return arraycast!(IReconcileResult)(collection.toArray());
+    }
+
+    /*
+     * @see IProgressMonitor#isCanceled()
+     */
+    protected final bool isCanceled() {
+        return fProgressMonitor !is null && fProgressMonitor.isCanceled();
+    }
+
+    /*
+     * @see IReconcileStep#setPreviousStep(IReconcileStep)
+     */
+    public void setPreviousStep(IReconcileStep step) {
+        Assert.isNotNull(cast(Object)step);
+        Assert.isTrue(fPreviousStep is null);
+        fPreviousStep= step;
+    }
+
+    /*
+     * @see IReconcileStep#setInputModel(Object)
+     */
+    public void setInputModel(IReconcilableModel inputModel) {
+        fInputModel= inputModel;
+
+        if (!isLastStep())
+            fNextStep.setInputModel(getModel());
+    }
+
+    /**
+     * Returns the reconcilable input model.
+     *
+     * @return the reconcilable input model.
+     */
+    public IReconcilableModel getInputModel() {
+        return fInputModel;
+    }
+
+    /**
+     * Returns the reconcilable model.
+     *
+     * @return the reconcilable model
+     */
+    abstract public IReconcilableModel getModel();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/reconciler/AbstractReconciler.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,635 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.reconciler.AbstractReconciler;
+
+import dwtx.jface.text.reconciler.IReconciler; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport
+import dwtx.jface.text.reconciler.MonoReconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.Reconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegion; // packageimport
+import dwtx.jface.text.reconciler.IReconcileResult; // packageimport
+import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+import tango.core.Thread;
+
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.IProgressMonitor;
+import dwtx.core.runtime.NullProgressMonitor;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentListener;
+import dwtx.jface.text.ITextInputListener;
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * Abstract implementation of {@link IReconciler}. The reconciler
+ * listens to input document changes as well as changes of
+ * the input document of the text viewer it is installed on. Depending on
+ * its configuration it manages the received change notifications in a
+ * queue folding neighboring or overlapping changes together. The reconciler
+ * processes the dirty regions as a background activity after having waited for further
+ * changes for the configured duration of time. A reconciler is started using the
+ * {@link #install(ITextViewer)} method.  As a first step {@link #initialProcess()} is
+ * executed in the background. Then, the reconciling thread waits for changes that
+ * need to be reconciled. A reconciler can be resumed by calling {@link #forceReconciling()}
+ * independent from the existence of actual changes. This mechanism is for subclasses only.
+ * It is the clients responsibility to stop a reconciler using its {@link #uninstall()}
+ * method. Unstopped reconcilers do not free their resources.
+ * <p>
+ * It is subclass responsibility to specify how dirty regions are processed.
+ * </p>
+ *
+ * @see dwtx.jface.text.IDocumentListener
+ * @see dwtx.jface.text.ITextInputListener
+ * @see dwtx.jface.text.reconciler.DirtyRegion
+ * @since 2.0
+ */
+abstract public class AbstractReconciler : IReconciler {
+
+
+    /**
+     * Background thread for the reconciling activity.
+     */
+    class BackgroundThread {
+        Thread thread;
+
+        /** Has the reconciler been canceled. */
+        private bool fCanceled= false;
+        /** Has the reconciler been reset. */
+        private bool fReset= false;
+        /** Some changes need to be processed. */
+        private bool fIsDirty= false;
+        /** Is a reconciling strategy active. */
+        private bool fIsActive= false;
+
+        /**
+         * Creates a new background thread. The thread
+         * runs with minimal priority.
+         *
+         * @param name the thread's name
+         */
+        public this(String name) {
+            thread = new Thread( &run );
+            thread.name = name;
+            thread.priority = Thread.PRIORITY_MIN;
+            thread.isDaemon(true);
+        }
+
+        public void start(){
+            thread.start();
+        }
+        public bool isAlive(){
+            return thread.isRunning();
+        }
+        public Thread getThread(){
+            return thread;
+        }
+        /**
+         * Returns whether a reconciling strategy is active right now.
+         *
+         * @return <code>true</code> if a activity is active
+         */
+        public bool isActive() {
+            return fIsActive;
+        }
+
+        /**
+         * Returns whether some changes need to be processed.
+         *
+         * @return <code>true</code> if changes wait to be processed
+         * @since 3.0
+         */
+        public synchronized bool isDirty() {
+            return fIsDirty;
+        }
+
+        /**
+         * Cancels the background thread.
+         */
+        public void cancel() {
+            fCanceled= true;
+            IProgressMonitor pm= fProgressMonitor;
+            if (pm !is null)
+                pm.setCanceled(true);
+            synchronized (fDirtyRegionQueue) {
+                fDirtyRegionQueue.notifyAll();
+            }
+        }
+
+        /**
+         * Suspends the caller of this method until this background thread has
+         * emptied the dirty region queue.
+         */
+        public void suspendCallerWhileDirty() {
+            bool isDirty;
+            do {
+                synchronized (fDirtyRegionQueue) {
+                    isDirty= fDirtyRegionQueue.getSize() > 0;
+                    if (isDirty) {
+                        try {
+                            fDirtyRegionQueue.wait();
+                        } catch (InterruptedException x) {
+                        }
+                    }
+                }
+            } while (isDirty);
+        }
+
+        /**
+         * Reset the background thread as the text viewer has been changed,
+         */
+        public void reset() {
+
+            if (fDelay > 0) {
+
+                synchronized (this) {
+                    fIsDirty= true;
+                    fReset= true;
+                }
+
+            } else {
+
+                synchronized (this) {
+                    fIsDirty= true;
+                }
+
+                synchronized (fDirtyRegionQueue) {
+                    fDirtyRegionQueue.notifyAll();
+                }
+            }
+
+            reconcilerReset();
+        }
+
+        /**
+         * The background activity. Waits until there is something in the
+         * queue managing the changes that have been applied to the text viewer.
+         * Removes the first change from the queue and process it.
+         * <p>
+         * Calls {@link AbstractReconciler#initialProcess()} on entrance.
+         * </p>
+         */
+        public void run() {
+
+            synchronized (fDirtyRegionQueue) {
+                try {
+                    fDirtyRegionQueue.wait(fDelay);
+                } catch (InterruptedException x) {
+                }
+            }
+
+            if (fCanceled)
+                return;
+
+            initialProcess();
+
+            while (!fCanceled) {
+
+                synchronized (fDirtyRegionQueue) {
+                    try {
+                        fDirtyRegionQueue.wait(fDelay);
+                    } catch (InterruptedException x) {
+                    }
+                }
+
+                if (fCanceled)
+                    break;
+
+                if (!isDirty())
+                    continue;
+
+                synchronized (this) {
+                    if (fReset) {
+                        fReset= false;
+                        continue;
+                    }
+                }
+
+                DirtyRegion r= null;
+                synchronized (fDirtyRegionQueue) {
+                    r= fDirtyRegionQueue.removeNextDirtyRegion();
+                }
+
+                fIsActive= true;
+
+                fProgressMonitor.setCanceled(false);
+
+                process(r);
+
+                synchronized (fDirtyRegionQueue) {
+                    if (0 is fDirtyRegionQueue.getSize()) {
+                        synchronized (this) {
+                            fIsDirty= fProgressMonitor.isCanceled();
+                        }
+                        fDirtyRegionQueue.notifyAll();
+                    }
+                }
+
+                fIsActive= false;
+            }
+        }
+    }
+
+    /**
+     * Internal document listener and text input listener.
+     */
+    class Listener : IDocumentListener, ITextInputListener {
+
+        /*
+         * @see IDocumentListener#documentAboutToBeChanged(DocumentEvent)
+         */
+        public void documentAboutToBeChanged(DocumentEvent e) {
+        }
+
+        /*
+         * @see IDocumentListener#documentChanged(DocumentEvent)
+         */
+        public void documentChanged(DocumentEvent e) {
+
+            if (!fThread.isDirty() && fThread.isAlive()) {
+                if (!fIsAllowedToModifyDocument && Thread.getThis() is fThread.getThread())
+                    throw new UnsupportedOperationException("The reconciler thread is not allowed to modify the document"); //$NON-NLS-1$
+                aboutToBeReconciled();
+            }
+
+            /*
+             * The second OR condition handles the case when the document
+             * gets changed while still inside initialProcess().
+             */
+            if (fThread.isActive() || fThread.isDirty() && fThread.isAlive())
+                fProgressMonitor.setCanceled(true);
+
+            if (fIsIncrementalReconciler)
+                createDirtyRegion(e);
+
+            fThread.reset();
+
+        }
+
+        /*
+         * @see ITextInputListener#inputDocumentAboutToBeChanged(IDocument, IDocument)
+         */
+        public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
+
+            if (oldInput is fDocument) {
+
+                if (fDocument !is null)
+                    fDocument.removeDocumentListener(this);
+
+                if (fIsIncrementalReconciler) {
+                    synchronized (fDirtyRegionQueue) {
+                        fDirtyRegionQueue.purgeQueue();
+                    }
+                    if (fDocument !is null && fDocument.getLength() > 0 && fThread.isDirty() && fThread.isAlive()) {
+                        DocumentEvent e= new DocumentEvent(fDocument, 0, fDocument.getLength(), ""); //$NON-NLS-1$
+                        createDirtyRegion(e);
+                        fThread.reset();
+                        fThread.suspendCallerWhileDirty();
+                    }
+                }
+
+                fDocument= null;
+            }
+        }
+
+        /*
+         * @see ITextInputListener#inputDocumentChanged(IDocument, IDocument)
+         */
+        public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+
+            fDocument= newInput;
+            if (fDocument is null)
+                return;
+
+
+            reconcilerDocumentChanged(fDocument);
+
+            fDocument.addDocumentListener(this);
+
+            if (!fThread.isDirty())
+                aboutToBeReconciled();
+
+            startReconciling();
+        }
+    }
+
+    /** Queue to manage the changes applied to the text viewer. */
+    private DirtyRegionQueue fDirtyRegionQueue;
+    /** The background thread. */
+    private BackgroundThread fThread;
+    /** Internal document and text input listener. */
+    private Listener fListener;
+    /** The background thread delay. */
+    private int fDelay= 500;
+    /** Are there incremental reconciling strategies? */
+    private bool fIsIncrementalReconciler= true;
+    /** The progress monitor used by this reconciler. */
+    private IProgressMonitor fProgressMonitor;
+    /**
+     * Tells whether this reconciler is allowed to modify the document.
+     * @since 3.2
+     */
+    private bool fIsAllowedToModifyDocument= true;
+
+
+    /** The text viewer's document. */
+    private IDocument fDocument;
+    /** The text viewer */
+    private ITextViewer fViewer;
+
+
+    /**
+     * Processes a dirty region. If the dirty region is <code>null</code> the whole
+     * document is consider being dirty. The dirty region is partitioned by the
+     * document and each partition is handed over to a reconciling strategy registered
+     * for the partition's content type.
+     *
+     * @param dirtyRegion the dirty region to be processed
+     */
+    abstract protected void process(DirtyRegion dirtyRegion);
+
+    /**
+     * Hook called when the document whose contents should be reconciled
+     * has been changed, i.e., the input document of the text viewer this
+     * reconciler is installed on. Usually, subclasses use this hook to
+     * inform all their reconciling strategies about the change.
+     *
+     * @param newDocument the new reconciler document
+     */
+    abstract protected void reconcilerDocumentChanged(IDocument newDocument);
+
+
+    /**
+     * Creates a new reconciler without configuring it.
+     */
+    protected this() {
+        fProgressMonitor= new NullProgressMonitor();
+    }
+
+    /**
+     * Tells the reconciler how long it should wait for further text changes before
+     * activating the appropriate reconciling strategies.
+     *
+     * @param delay the duration in milliseconds of a change collection period.
+     */
+    public void setDelay(int delay) {
+        fDelay= delay;
+    }
+
+    /**
+     * Tells the reconciler whether any of the available reconciling strategies
+     * is interested in getting detailed dirty region information or just in the
+     * fact that the document has been changed. In the second case, the reconciling
+     * can not incrementally be pursued.
+     *
+     * @param isIncremental indicates whether this reconciler will be configured with
+     *      incremental reconciling strategies
+     *
+     * @see DirtyRegion
+     * @see IReconcilingStrategy
+     */
+    public void setIsIncrementalReconciler(bool isIncremental) {
+        fIsIncrementalReconciler= isIncremental;
+    }
+
+    /**
+     * Tells the reconciler whether it is allowed to change the document
+     * inside its reconciler thread.
+     * <p>
+     * If this is set to <code>false</code> an {@link UnsupportedOperationException}
+     * will be thrown when this restriction will be violated.
+     * </p>
+     *
+     * @param isAllowedToModify indicates whether this reconciler is allowed to modify the document
+     * @since 3.2
+     */
+    public void setIsAllowedToModifyDocument(bool isAllowedToModify) {
+        fIsAllowedToModifyDocument= isAllowedToModify;
+    }
+
+    /**
+     * Sets the progress monitor of this reconciler.
+     *
+     * @param monitor the monitor to be used
+     */
+    public void setProgressMonitor(IProgressMonitor monitor) {
+        Assert.isLegal(monitor !is null);
+        fProgressMonitor= monitor;
+    }
+
+    /**
+     * Returns whether any of the reconciling strategies is interested in
+     * detailed dirty region information.
+     *
+     * @return whether this reconciler is incremental
+     *
+     * @see IReconcilingStrategy
+     */
+    protected bool isIncrementalReconciler() {
+        return fIsIncrementalReconciler;
+    }
+
+    /**
+     * Returns the input document of the text viewer this reconciler is installed on.
+     *
+     * @return the reconciler document
+     */
+    protected IDocument getDocument() {
+        return fDocument;
+    }
+
+    /**
+     * Returns the text viewer this reconciler is installed on.
+     *
+     * @return the text viewer this reconciler is installed on
+     */
+    protected ITextViewer getTextViewer() {
+        return fViewer;
+    }
+
+    /**
+     * Returns the progress monitor of this reconciler.
+     *
+     * @return the progress monitor of this reconciler
+     */
+    protected IProgressMonitor getProgressMonitor() {
+        return fProgressMonitor;
+    }
+
+    /*
+     * @see IReconciler#install(ITextViewer)
+     */
+    public void install(ITextViewer textViewer) {
+
+        Assert.isNotNull(cast(Object)textViewer);
+        fViewer= textViewer;
+
+        synchronized (this) {
+            if (fThread !is null)
+                return;
+            fThread= new BackgroundThread(this.classinfo.name);
+        }
+
+        fDirtyRegionQueue= new DirtyRegionQueue();
+
+        fListener= new Listener();
+        fViewer.addTextInputListener(fListener);
+
+        // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=67046
+        // if the reconciler gets installed on a viewer that already has a document
+        // (e.g. when reusing editors), we force the listener to register
+        // itself as document listener, because there will be no input change
+        // on the viewer.
+        // In order to do that, we simulate an input change.
+        IDocument document= textViewer.getDocument();
+        if (document !is null) {
+            fListener.inputDocumentAboutToBeChanged(fDocument, document);
+            fListener.inputDocumentChanged(fDocument, document);
+        }
+    }
+
+    /*
+     * @see IReconciler#uninstall()
+     */
+    public void uninstall() {
+        if (fListener !is null) {
+
+            fViewer.removeTextInputListener(fListener);
+            if (fDocument !is null) {
+                fListener.inputDocumentAboutToBeChanged(fDocument, null);
+                fListener.inputDocumentChanged(fDocument, null);
+            }
+            fListener= null;
+
+            synchronized (this) {
+                // http://dev.eclipse.org/bugs/show_bug.cgi?id=19135
+                BackgroundThread bt= fThread;
+                fThread= null;
+                bt.cancel();
+            }
+        }
+    }
+
+    /**
+     * Creates a dirty region for a document event and adds it to the queue.
+     *
+     * @param e the document event for which to create a dirty region
+     */
+    private void createDirtyRegion(DocumentEvent e) {
+        synchronized (fDirtyRegionQueue) {
+            if (e.getLength() is 0 && e.getText() !is null) {
+                // Insert
+                fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getText().length(), DirtyRegion.INSERT, e.getText()));
+
+            } else if (e.getText() is null || e.getText().length() is 0) {
+                // Remove
+                fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getLength(), DirtyRegion.REMOVE, null));
+
+            } else {
+                // Replace (Remove + Insert)
+                fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getLength(), DirtyRegion.REMOVE, null));
+                fDirtyRegionQueue.addDirtyRegion(new DirtyRegion(e.getOffset(), e.getText().length(), DirtyRegion.INSERT, e.getText()));
+            }
+        }
+    }
+
+    /**
+     * Hook for subclasses which want to perform some
+     * action as soon as reconciliation is needed.
+     * <p>
+     * Default implementation is to do nothing.
+     * </p>
+     *
+     * @since 3.0
+     */
+    protected void aboutToBeReconciled() {
+    }
+
+    /**
+     * This method is called on startup of the background activity. It is called only
+     * once during the life time of the reconciler. Clients may reimplement this method.
+     */
+    protected void initialProcess() {
+    }
+
+    /**
+     * Forces the reconciler to reconcile the structure of the whole document.
+     * Clients may extend this method.
+     */
+    protected void forceReconciling() {
+
+        if (fDocument !is null) {
+
+            if (!fThread.isDirty()&& fThread.isAlive())
+                aboutToBeReconciled();
+
+            if (fThread.isActive())
+                fProgressMonitor.setCanceled(true);
+
+            if (fIsIncrementalReconciler) {
+                DocumentEvent e= new DocumentEvent(fDocument, 0, fDocument.getLength(), fDocument.get());
+                createDirtyRegion(e);
+            }
+
+            startReconciling();
+        }
+    }
+
+    /**
+     * Starts the reconciler to reconcile the queued dirty-regions.
+     * Clients may extend this method.
+     */
+    protected synchronized void startReconciling() {
+        if (fThread is null)
+            return;
+
+        if (!fThread.isAlive()) {
+// DWT
+//             try {
+                fThread.start();
+//             } catch (IllegalThreadStateException e) {
+                // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=40549
+                // This is the only instance where the thread is started; since
+                // we checked that it is not alive, it must be dead already due
+                // to a run-time exception or error. Exit.
+//             }
+        } else {
+            fThread.reset();
+        }
+    }
+
+    /**
+     * Hook that is called after the reconciler thread has been reset.
+     */
+    protected void reconcilerReset() {
+    }
+
+    /**
+     * Tells whether the code is running in this reconciler's
+     * background thread.
+     *
+     * @return <code>true</code> if running in this reconciler's background thread
+     * @since 3.4
+     */
+    protected bool isRunningInReconcilerThread() {
+        return Thread.getThis() is fThread.getThread();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/reconciler/DirtyRegion.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.reconciler.DirtyRegion;
+
+import dwtx.jface.text.reconciler.IReconciler; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport
+import dwtx.jface.text.reconciler.MonoReconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport
+import dwtx.jface.text.reconciler.Reconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport
+import dwtx.jface.text.reconciler.IReconcileResult; // packageimport
+import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.ITypedRegion;
+
+
+/**
+ * A dirty region describes a document range which has been changed.
+ */
+public class DirtyRegion : ITypedRegion {
+
+    /**
+     * Identifies an insert operation.
+     */
+    final static public String INSERT= "__insert"; //$NON-NLS-1$
+    /**
+     * Identifies a remove operation.
+     */
+    final static public String REMOVE= "__remove"; //$NON-NLS-1$
+
+    /** The region's offset. */
+    private int fOffset;
+    /** The region's length. */
+    private int fLength;
+    /** Indicates the type of the applied change. */
+    private String fType;
+    /** The text which has been inserted. */
+    private String fText;
+
+    /**
+     * Creates a new dirty region.
+     *
+     * @param offset the offset within the document where the change occurred
+     * @param length the length of the text within the document that changed
+     * @param type the type of change that this region represents: {@link #INSERT} {@link #REMOVE}
+     * @param text the substitution text
+     */
+    public this(int offset, int length, String type, String text) {
+        fOffset= offset;
+        fLength= length;
+        fType= normalizeTypeValue(type);
+        fText= text;
+    }
+
+    /**
+     * Computes the normalized type value to ensure that the implementation can use object identity rather
+     * than equality.
+     *
+     * @param type the type value
+     * @return the normalized type value or <code>null</code>
+     * @since 3.1
+     */
+    private String normalizeTypeValue(String type) {
+        if (INSERT.equals(type))
+            return INSERT;
+        if (REMOVE.equals(type))
+            return REMOVE;
+        return null;
+    }
+
+    /*
+     * @see ITypedRegion#getOffset()
+     */
+    public int getOffset() {
+        return fOffset;
+    }
+
+    /*
+     * @see ITypedRegion#getLength()
+     */
+    public int getLength() {
+        return fLength;
+    }
+
+    /*
+     * @see ITypedRegion#getType
+     */
+    public String getType() {
+        return fType;
+    }
+
+    /**
+     * Returns the text that changed as part of the region change.
+     *
+     * @return the changed text
+     */
+    public String getText() {
+        return fText;
+    }
+
+    /**
+     * Modify the receiver so that it encompasses the region specified by the dirty region.
+     *
+     * @param dr the dirty region with which to merge
+     */
+    void mergeWith(DirtyRegion dr) {
+        int start= Math.min(fOffset, dr.fOffset);
+        int end= Math.max(fOffset + fLength, dr.fOffset + dr.fLength);
+        fOffset= start;
+        fLength= end - start;
+        fText= (dr.fText is null ? fText : (fText is null) ? dr.fText : fText ~ dr.fText);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/reconciler/DirtyRegionQueue.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.reconciler.DirtyRegionQueue;
+
+import dwtx.jface.text.reconciler.IReconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport
+import dwtx.jface.text.reconciler.MonoReconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport
+import dwtx.jface.text.reconciler.Reconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegion; // packageimport
+import dwtx.jface.text.reconciler.IReconcileResult; // packageimport
+import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+import tango.core.sync.Mutex;
+import tango.core.sync.Condition;
+
+/**
+ * Queue used by {@link dwtx.jface.text.reconciler.AbstractReconciler} to manage
+ * dirty regions. When a dirty region is inserted into the queue, the queue tries
+ * to fold it into the neighboring dirty region.
+ *
+ * @see dwtx.jface.text.reconciler.AbstractReconciler
+ * @see dwtx.jface.text.reconciler.DirtyRegion
+ */
+class DirtyRegionQueue : Mutex {
+
+    /** The list of dirty regions. */
+    private List fDirtyRegions;
+    private Condition cond;
+    /**
+     * Creates a new empty dirty region.
+     */
+    public this() {
+        //super();
+        fDirtyRegions= new ArrayList();
+        cond = new Condition(this);
+    }
+
+    public void wait(){
+        cond.wait();
+    }
+    public void wait(int delay){
+        cond.wait(delay/1000.0);
+    }
+    public void notifyAll(){
+        cond.notifyAll();
+    }
+
+    /**
+     * Adds a dirty region to the end of the dirty-region queue.
+     *
+     * @param dr the dirty region to add
+     */
+    public void addDirtyRegion(DirtyRegion dr) {
+        // If the dirty region being added is directly after the last dirty
+        // region on the queue then merge the two dirty regions together.
+        DirtyRegion lastDR= getLastDirtyRegion();
+        bool wasMerged= false;
+        if (lastDR !is null)
+            if (lastDR.getType() is dr.getType())
+                if (lastDR.getType() is DirtyRegion.INSERT) {
+                    if (lastDR.getOffset() + lastDR.getLength() is dr.getOffset()) {
+                        lastDR.mergeWith(dr);
+                        wasMerged= true;
+                    }
+                } else if (lastDR.getType() is DirtyRegion.REMOVE) {
+                    if (dr.getOffset() + dr.getLength() is lastDR.getOffset()) {
+                        lastDR.mergeWith(dr);
+                        wasMerged= true;
+                    }
+                }
+
+        if (!wasMerged)
+            // Don't merge- just add the new one onto the queue.
+            fDirtyRegions.add(dr);
+    }
+
+    /**
+     * Returns the last dirty region that was added to the queue.
+     *
+     * @return the last DirtyRegion on the queue
+     */
+    private DirtyRegion getLastDirtyRegion() {
+        int size= fDirtyRegions.size();
+        return (size is 0 ? null : cast(DirtyRegion) fDirtyRegions.get(size - 1));
+    }
+
+    /**
+     * Returns the number of regions in the queue.
+     *
+     * @return the dirty-region queue-size
+     */
+    public int getSize() {
+        return fDirtyRegions.size();
+    }
+
+    /**
+     * Throws away all entries in the queue.
+     */
+    public void purgeQueue() {
+        fDirtyRegions.clear();
+    }
+
+    /**
+     * Removes and returns the first dirty region in the queue
+     *
+     * @return the next dirty region on the queue
+     */
+    public DirtyRegion removeNextDirtyRegion() {
+        if (fDirtyRegions.size() is 0)
+            return null;
+        DirtyRegion dr= cast(DirtyRegion) fDirtyRegions.get(0);
+        fDirtyRegions.remove(0);
+        return dr;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/reconciler/IReconcilableModel.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.reconciler.IReconcilableModel;
+
+import dwtx.jface.text.reconciler.IReconciler; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport
+import dwtx.jface.text.reconciler.MonoReconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport
+import dwtx.jface.text.reconciler.Reconciler; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegion; // packageimport
+import dwtx.jface.text.reconciler.IReconcileResult; // packageimport
+import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Tagging interface for a model that can get reconciled during a
+ * {@linkplain dwtx.jface.text.reconciler.IReconcileStep reconcile step}.
+ * <p>
+ * This model is not directly used by a {@linkplain dwtx.jface.text.reconciler.IReconciler reconciler}
+ * or a {@linkplain dwtx.jface.text.reconciler.IReconcilingStrategy reconciling strategy}.
+ * </p>
+ *
+ * <p>
+ * This interface must be implemented by clients that want to use one of
+ * their models as a reconcile step's input model.
+ * </p>
+ *
+ * @see dwtx.jface.text.reconciler.IReconcileStep#setInputModel(IReconcilableModel)
+ * @since 3.0
+ */
+public interface IReconcilableModel {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/reconciler/IReconcileResult.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.reconciler.IReconcileResult;
+
+import dwtx.jface.text.reconciler.IReconciler; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport
+import dwtx.jface.text.reconciler.MonoReconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport
+import dwtx.jface.text.reconciler.Reconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegion; // packageimport
+import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Tagging interface for the {@linkplain dwtx.jface.text.reconciler.IReconcileStep reconcile step}
+ * result's array element type.
+ * <p>
+ * This interface must be implemented by clients that want to
+ * let one of their model elements be part of a reconcile step result.
+ * </p>
+ *
+ * @see dwtx.jface.text.reconciler.IReconcileStep
+ * @since 3.0
+ */
+public interface IReconcileResult {
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/reconciler/IReconcileStep.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,147 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.reconciler.IReconcileStep;
+
+import dwtx.jface.text.reconciler.IReconciler; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport
+import dwtx.jface.text.reconciler.MonoReconciler; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport
+import dwtx.jface.text.reconciler.Reconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegion; // packageimport
+import dwtx.jface.text.reconciler.IReconcileResult; // packageimport
+import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.IProgressMonitor;
+import dwtx.jface.text.IRegion;
+
+
+/**
+ * A reconcile step is one of several steps of a
+ * {@linkplain dwtx.jface.text.reconciler.IReconcilingStrategy reconcile strategy}
+ * that consists of several steps. This relationship is not coded into an interface but
+ * should be used by clients who's reconcile strategy consists of several steps.
+ * <p>
+ * If a reconcile step has an {@linkplain dwtx.jface.text.reconciler.IReconcilableModel input model}
+ * it will compute the correct model for the next step in the chain and set the next steps
+ * input model before <code>reconcile</code> gets called on that next step. After the last
+ * step has reconciled the {@linkplain dwtx.jface.text.reconciler.IReconcileResult reconcile result}
+ * array gets returned to the previous step. Each step in the chain adapts the result to its
+ * input model and returns it to its previous step.
+ * </p>
+ * <p>
+ * Example: Assume a strategy consists of steps A, B and C. And the main model is M.
+ * The strategy will set M to be A's input model. What will happen is:
+ * <ol>
+ *  <li>A.setInputModel(M)</li>
+ *  <li>A.reconcile: A reconciles M</li>
+ *  <li>A computes the model for B =&gt; MB</li>
+ *  <li>B.setInputModel(MB)</li>
+ *  <li>B.reconcile: B reconciles MB</li>
+ *  <li>B computes the model for C =&gt; MC</li>
+ *  <li>C.setInputModel(MC)</li>
+ *  <li>C.reconcile: C reconciles MC</li>
+ *  <li>C returns result RC to step B</li>
+ *  <li>B adapts the RC to MB and merges with its own results</li>
+ *  <li>B returns result RB to step A</li>
+ *  <li>A adapts the result to M and merges with its own results</li>
+ *  <li>A returns the result to the reconcile strategy</li>
+ * </ol>
+ * </p>
+ * <p>
+ * This interface must be implemented by clients.
+ * </p>
+ * @since 3.0
+ */
+public interface IReconcileStep {
+
+    /**
+     * Returns whether this is the last reconcile step or not.
+     *
+     * @return <code>true</code> iff this is the last reconcile step
+     */
+    bool isLastStep();
+
+    /**
+     * Returns whether this is the first reconcile step or not.
+     *
+     * @return <code>true</code> iff this is the first reconcile step
+     */
+    bool isFirstStep();
+
+    /**
+     * Sets the step which is in front of this step in the pipe.
+     * <p>
+     * Note: This method must be called at most once per reconcile step.
+     * </p>
+     *
+     * @param step the previous step
+     * @throws RuntimeException if called more than once
+     */
+    void setPreviousStep(IReconcileStep step);
+
+    /**
+     * Activates incremental reconciling of the specified dirty region.
+     * As a dirty region might span multiple content types, the segment of the
+     * dirty region which should be investigated is also provided to this
+     * reconciling strategy. The given regions refer to the document passed into
+     * the most recent call of {@link IReconcilingStrategy#setDocument(dwtx.jface.text.IDocument)}.
+     *
+     * @param dirtyRegion the document region which has been changed
+     * @param subRegion the sub region in the dirty region which should be reconciled
+     * @return an array with reconcile results
+     */
+    IReconcileResult[] reconcile(DirtyRegion dirtyRegion, IRegion subRegion);
+
+    /**
+     * Activates non-incremental reconciling. The reconciling strategy is just told
+     * that there are changes and that it should reconcile the given partition of the
+     * document most recently passed into {@link IReconcilingStrategy#setDocument(dwtx.jface.text.IDocument)}.
+     *
+     * @param partition the document partition to be reconciled
+     * @return an array with reconcile results
+     */
+    IReconcileResult[] reconcile(IRegion partition);
+
+    /**
+     * Sets the progress monitor for this reconcile step.
+     *
+     * @param monitor the progress monitor to be used
+     */
+    void setProgressMonitor(IProgressMonitor monitor);
+
+    /**
+     * Returns the progress monitor used to report progress.
+     *
+     * @return a progress monitor or <code>null</code> if no progress monitor is available
+     */
+    public IProgressMonitor getProgressMonitor();
+
+    /**
+     * Tells this reconcile step on which model it will
+     * work. This method will be called before any other method
+     * and can be called multiple times. The regions passed to the
+     * other methods always refer to the most recent model
+     * passed into this method.
+     *
+     * @param inputModel the model on which this step will work
+     */
+    void setInputModel(IReconcilableModel inputModel);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/reconciler/IReconciler.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.reconciler.IReconciler;
+
+import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport
+import dwtx.jface.text.reconciler.MonoReconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport
+import dwtx.jface.text.reconciler.Reconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegion; // packageimport
+import dwtx.jface.text.reconciler.IReconcileResult; // packageimport
+import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * An <code>IReconciler</code> defines and maintains a model of the content
+ * of the text  viewer's document in the presence of changes applied to this
+ * document. An <code>IReconciler</code> is a {@link dwtx.jface.text.ITextViewer} add-on.
+ * <p>
+ * Reconcilers are assumed to be asynchronous, i.e. they allow a certain
+ * temporal window of inconsistency between the document and the model of
+ * the content of this document.
+ * </p>
+ * <p>
+ * Reconcilers have a list of {@link dwtx.jface.text.reconciler.IReconcilingStrategy}
+ * objects each of which is registered for a  particular document content type.
+ * The reconciler uses the strategy objects to react on the changes applied
+ * to the text viewer's document.
+ *</p>
+ * <p>
+ * In order to provide backward compatibility for clients of <code>IReconciler</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.reconciler.IReconcilerExtension} since version 3.0 introducing
+ *      the ability to be aware of documents with multiple partitionings.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * The interface can be implemented by clients. By default, clients use
+ * {@link dwtx.jface.text.reconciler.MonoReconciler} or
+ * {@link dwtx.jface.text.reconciler.Reconciler} as the standard
+ * implementers of this interface.
+ * </p>
+ *
+ * @see ITextViewer
+ * @see IReconcilingStrategy
+ */
+public interface IReconciler {
+
+    /**
+     * Installs the reconciler on the given text viewer. After this method has been
+     * finished, the reconciler is operational, i.e., it works without requesting
+     * further client actions until <code>uninstall</code> is called.
+     *
+     * @param textViewer the viewer on which the reconciler is installed
+     */
+    void install(ITextViewer textViewer);
+
+    /**
+     * Removes the reconciler from the text viewer it has
+     * previously been installed on.
+     */
+    void uninstall();
+
+    /**
+     * Returns the reconciling strategy registered with the reconciler
+     * for the specified content type.
+     *
+     * @param contentType the content type for which to determine the reconciling strategy
+     * @return the reconciling strategy registered for the given content type, or
+     *      <code>null</code> if there is no such strategy
+     */
+    IReconcilingStrategy getReconcilingStrategy(String contentType);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/reconciler/IReconcilerExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.reconciler.IReconcilerExtension;
+
+import dwtx.jface.text.reconciler.IReconciler; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport
+import dwtx.jface.text.reconciler.MonoReconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport
+import dwtx.jface.text.reconciler.Reconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegion; // packageimport
+import dwtx.jface.text.reconciler.IReconcileResult; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extends {@link dwtx.jface.text.reconciler.IReconciler} with
+ * the ability to be aware of documents with multiple partitionings.
+ *
+ * @since 3.0
+ */
+public interface IReconcilerExtension {
+
+    /**
+     * Returns the partitioning this reconciler is using.
+     *
+     * @return the partitioning this reconciler is using
+     */
+    String getDocumentPartitioning();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/reconciler/IReconcilingStrategy.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.reconciler.IReconcilingStrategy;
+
+import dwtx.jface.text.reconciler.IReconciler; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport
+import dwtx.jface.text.reconciler.MonoReconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport
+import dwtx.jface.text.reconciler.Reconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegion; // packageimport
+import dwtx.jface.text.reconciler.IReconcileResult; // packageimport
+import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+
+
+/**
+ * A reconciling strategy is used by an reconciler to reconcile a model
+ * based on text of a particular content type. It provides methods for
+ * incremental as well as non-incremental reconciling.
+ * <p>
+ * If a reconcile strategy consists of several steps between which
+ * model transformation is desired the each step should implement
+ * {@link dwtx.jface.text.reconciler.IReconcileStep}.
+ * </p>
+ * <p>
+ * In order to provide backward compatibility for clients of <code>IReconcilingStrategy</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.reconciler.IReconcilingStrategyExtension} since version 2.0 introducing
+ *      the following functions:
+ *          <ul>
+ *              <li>usage of a progress monitor</li>
+ *              <li>initial reconciling step: if a reconciler runs as periodic activity in the background, this
+ *                  methods offers the reconciler a chance for initializing its strategies and achieving a
+ *                  reconciled state before the periodic activity starts.</li>
+ *          </ul>
+ * </li>
+ * </ul>
+ * </p>
+ * <p>
+ * This interface must be implemented by clients. Implementers should be
+ * registered with a reconciler in order get involved in the reconciling
+ * process.
+ * </p>
+ */
+public interface IReconcilingStrategy {
+
+    /**
+     * Tells this reconciling strategy on which document it will
+     * work. This method will be called before any other method
+     * and can be called multiple times. The regions passed to the
+     * other methods always refer to the most recent document
+     * passed into this method.
+     *
+     * @param document the document on which this strategy will work
+     */
+    void setDocument(IDocument document);
+
+    /**
+     * Activates incremental reconciling of the specified dirty region.
+     * As a dirty region might span multiple content types, the segment of the
+     * dirty region which should be investigated is also provided to this
+     * reconciling strategy. The given regions refer to the document passed into
+     * the most recent call of {@link #setDocument(IDocument)}.
+     *
+     * @param dirtyRegion the document region which has been changed
+     * @param subRegion the sub region in the dirty region which should be reconciled
+     */
+    void reconcile(DirtyRegion dirtyRegion, IRegion subRegion);
+
+    /**
+     * Activates non-incremental reconciling. The reconciling strategy is just told
+     * that there are changes and that it should reconcile the given partition of the
+     * document most recently passed into {@link #setDocument(IDocument)}.
+     *
+     * @param partition the document partition to be reconciled
+     */
+    void reconcile(IRegion partition);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/reconciler/IReconcilingStrategyExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.reconciler.IReconcilingStrategyExtension;
+
+import dwtx.jface.text.reconciler.IReconciler; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.MonoReconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport
+import dwtx.jface.text.reconciler.Reconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegion; // packageimport
+import dwtx.jface.text.reconciler.IReconcileResult; // packageimport
+import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.IProgressMonitor;
+
+
+/**
+ * Extends {@link dwtx.jface.text.reconciler.IReconcilingStrategy}
+ * with the following functions:
+ * <ul>
+ *  <li>usage of a progress monitor</li>
+ *  <li>initial reconciling step: if a reconciler runs as periodic activity in the background, this
+ *      methods offers the reconciler a chance for initializing its strategies and achieving a
+ *      reconciled state before the periodic activity starts.</li>
+ * </ul>
+ *
+ * @since 2.0
+ */
+public interface IReconcilingStrategyExtension {
+
+    /**
+     * Tells this reconciling strategy with which progress monitor
+     * it will work. This method will be called before any other
+     * method and can be called multiple times.
+     *
+     * @param monitor the progress monitor with which this strategy will work
+     */
+    void setProgressMonitor(IProgressMonitor monitor);
+
+    /**
+     * Called only once in the life time of this reconciling strategy.
+     */
+    void initialReconcile();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/reconciler/MonoReconciler.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,126 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.reconciler.MonoReconciler;
+
+import dwtx.jface.text.reconciler.IReconciler; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport
+import dwtx.jface.text.reconciler.IReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport
+import dwtx.jface.text.reconciler.Reconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegion; // packageimport
+import dwtx.jface.text.reconciler.IReconcileResult; // packageimport
+import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.IProgressMonitor;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.Region;
+
+
+/**
+ * Standard implementation of {@link dwtx.jface.text.reconciler.IReconciler}.
+ * The reconciler is configured with a single {@linkplain dwtx.jface.text.reconciler.IReconcilingStrategy reconciling strategy}
+ * that is used independently from where a dirty region is located in the reconciler's
+ * document.
+ * <p>
+ * Usually, clients instantiate this class and configure it before using it.
+ * </p>
+ *
+ * @see dwtx.jface.text.IDocumentListener
+ * @see dwtx.jface.text.ITextInputListener
+ * @see dwtx.jface.text.reconciler.DirtyRegion
+ * @since 2.0
+ */
+public class MonoReconciler : AbstractReconciler {
+
+
+    /** The reconciling strategy. */
+    private IReconcilingStrategy fStrategy;
+
+
+    /**
+     * Creates a new reconciler that uses the same reconciling strategy to
+     * reconcile its document independent of the type of the document's contents.
+     *
+     * @param strategy the reconciling strategy to be used
+     * @param isIncremental the indication whether strategy is incremental or not
+     */
+    public this(IReconcilingStrategy strategy, bool isIncremental) {
+        Assert.isNotNull(cast(Object)strategy);
+        fStrategy= strategy;
+        if ( cast(IReconcilingStrategyExtension)fStrategy ) {
+            IReconcilingStrategyExtension extension= cast(IReconcilingStrategyExtension)fStrategy;
+            extension.setProgressMonitor(getProgressMonitor());
+        }
+
+        setIsIncrementalReconciler(isIncremental);
+    }
+
+    /*
+     * @see IReconciler#getReconcilingStrategy(String)
+     */
+    public IReconcilingStrategy getReconcilingStrategy(String contentType) {
+        Assert.isNotNull(contentType);
+        return fStrategy;
+    }
+
+    /*
+     * @see AbstractReconciler#process(DirtyRegion)
+     */
+    protected void process(DirtyRegion dirtyRegion) {
+
+        if(dirtyRegion !is null)
+            fStrategy.reconcile(dirtyRegion, dirtyRegion);
+        else {
+            IDocument document= getDocument();
+            if (document !is null)
+                fStrategy.reconcile(new Region(0, document.getLength()));
+        }
+    }
+
+    /*
+     * @see AbstractReconciler#reconcilerDocumentChanged(IDocument)
+     */
+    protected void reconcilerDocumentChanged(IDocument document) {
+        fStrategy.setDocument(document);
+    }
+
+    /*
+     * @see AbstractReconciler#setProgressMonitor(IProgressMonitor)
+     */
+    public void setProgressMonitor(IProgressMonitor monitor) {
+        super.setProgressMonitor(monitor);
+        if ( cast(IReconcilingStrategyExtension)fStrategy ) {
+            IReconcilingStrategyExtension extension= cast(IReconcilingStrategyExtension) fStrategy;
+            extension.setProgressMonitor(monitor);
+        }
+    }
+
+    /*
+     * @see AbstractReconciler#initialProcess()
+     */
+    protected void initialProcess() {
+        if ( cast(IReconcilingStrategyExtension)fStrategy ) {
+            IReconcilingStrategyExtension extension= cast(IReconcilingStrategyExtension) fStrategy;
+            extension.initialReconcile();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/reconciler/Reconciler.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,243 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.reconciler.Reconciler;
+
+import dwtx.jface.text.reconciler.IReconciler; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegionQueue; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategy; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.IReconcilingStrategyExtension; // packageimport
+import dwtx.jface.text.reconciler.MonoReconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcileStep; // packageimport
+import dwtx.jface.text.reconciler.AbstractReconciler; // packageimport
+import dwtx.jface.text.reconciler.IReconcilableModel; // packageimport
+import dwtx.jface.text.reconciler.DirtyRegion; // packageimport
+import dwtx.jface.text.reconciler.IReconcileResult; // packageimport
+import dwtx.jface.text.reconciler.IReconcilerExtension; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.IProgressMonitor;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentExtension3;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITypedRegion;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextUtilities;
+import dwtx.jface.text.TypedRegion;
+
+
+/**
+ * Standard implementation of {@link dwtx.jface.text.reconciler.IReconciler}.
+ * The reconciler is configured with a set of {@linkplain dwtx.jface.text.reconciler.IReconcilingStrategy reconciling strategies}
+ * each of which is responsible for a particular content type.
+ * <p>
+ * Usually, clients instantiate this class and configure it before using it.
+ * </p>
+ *
+ * @see dwtx.jface.text.IDocumentListener
+ * @see dwtx.jface.text.ITextInputListener
+ * @see dwtx.jface.text.reconciler.DirtyRegion
+ */
+public class Reconciler : AbstractReconciler , IReconcilerExtension {
+
+    /** The map of reconciling strategies. */
+    private Map fStrategies;
+
+    /**
+     * The partitioning this reconciler uses.
+     *@since 3.0
+     */
+    private String fPartitioning;
+
+    /**
+     * Creates a new reconciler with the following configuration: it is
+     * an incremental reconciler with a standard delay of 500 milliseconds. There
+     * are no predefined reconciling strategies. The partitioning it uses
+     * is the default partitioning {@link IDocumentExtension3#DEFAULT_PARTITIONING}.
+     */
+    public this() {
+        super();
+        fPartitioning= IDocumentExtension3.DEFAULT_PARTITIONING;
+    }
+
+    /**
+     * Sets the document partitioning for this reconciler.
+     *
+     * @param partitioning the document partitioning for this reconciler
+     * @since 3.0
+     */
+    public void setDocumentPartitioning(String partitioning) {
+        Assert.isNotNull(partitioning);
+        fPartitioning= partitioning;
+    }
+
+    /*
+     * @see dwtx.jface.text.reconciler.IReconcilerExtension#getDocumentPartitioning()
+     * @since 3.0
+     */
+    public String getDocumentPartitioning() {
+        return fPartitioning;
+    }
+
+    /**
+     * Registers a given reconciling strategy for a particular content type.
+     * If there is already a strategy registered for this type, the new strategy
+     * is registered instead of the old one.
+     *
+     * @param strategy the reconciling strategy to register, or <code>null</code> to remove an existing one
+     * @param contentType the content type under which to register
+     */
+    public void setReconcilingStrategy(IReconcilingStrategy strategy, String contentType) {
+
+        Assert.isNotNull(contentType);
+
+        if (fStrategies is null)
+            fStrategies= new HashMap();
+
+        if (strategy is null)
+            fStrategies.remove(contentType);
+        else {
+            fStrategies.put(contentType, cast(Object)strategy);
+            if (cast(IReconcilingStrategyExtension )strategy && getProgressMonitor() !is null) {
+                IReconcilingStrategyExtension extension= cast(IReconcilingStrategyExtension) strategy;
+                extension.setProgressMonitor(getProgressMonitor());
+            }
+        }
+    }
+
+    /*
+     * @see IReconciler#getReconcilingStrategy(String)
+     */
+    public IReconcilingStrategy getReconcilingStrategy(String contentType) {
+
+        Assert.isNotNull(contentType);
+
+        if (fStrategies is null)
+            return null;
+
+        return cast(IReconcilingStrategy) fStrategies.get(contentType);
+    }
+
+    /**
+     * Processes a dirty region. If the dirty region is <code>null</code> the whole
+     * document is consider being dirty. The dirty region is partitioned by the
+     * document and each partition is handed over to a reconciling strategy registered
+     * for the partition's content type.
+     *
+     * @param dirtyRegion the dirty region to be processed
+     * @see AbstractReconciler#process(DirtyRegion)
+     */
+    protected void process(DirtyRegion dirtyRegion) {
+
+        IRegion region= dirtyRegion;
+
+        if (region is null)
+            region= new Region(0, getDocument().getLength());
+
+        ITypedRegion[] regions= computePartitioning(region.getOffset(), region.getLength());
+
+        for (int i= 0; i < regions.length; i++) {
+            ITypedRegion r= regions[i];
+            IReconcilingStrategy s= getReconcilingStrategy(r.getType());
+            if (s is null)
+                continue;
+
+            if(dirtyRegion !is null)
+                s.reconcile(dirtyRegion, r);
+            else
+                s.reconcile(r);
+        }
+    }
+
+    /*
+     * @see AbstractReconciler#reconcilerDocumentChanged(IDocument)
+     * @since 2.0
+     */
+    protected void reconcilerDocumentChanged(IDocument document) {
+        if (fStrategies !is null) {
+            Iterator e= fStrategies.values().iterator();
+            while (e.hasNext()) {
+                IReconcilingStrategy strategy= cast(IReconcilingStrategy) e.next();
+                strategy.setDocument(document);
+            }
+        }
+    }
+
+    /*
+     * @see AbstractReconciler#setProgressMonitor(IProgressMonitor)
+     * @since 2.0
+     */
+    public void setProgressMonitor(IProgressMonitor monitor) {
+        super.setProgressMonitor(monitor);
+
+        if (fStrategies !is null) {
+            Iterator e= fStrategies.values().iterator();
+            while (e.hasNext()) {
+                IReconcilingStrategy strategy= cast(IReconcilingStrategy) e.next();
+                if ( cast(IReconcilingStrategyExtension)strategy ) {
+                    IReconcilingStrategyExtension extension= cast(IReconcilingStrategyExtension) strategy;
+                    extension.setProgressMonitor(monitor);
+                }
+            }
+        }
+    }
+
+    /*
+     * @see AbstractReconciler#initialProcess()
+     * @since 2.0
+     */
+    protected void initialProcess() {
+        ITypedRegion[] regions= computePartitioning(0, getDocument().getLength());
+        List contentTypes= new ArrayList(regions.length);
+        for (int i= 0; i < regions.length; i++) {
+            String contentType= regions[i].getType();
+            if( contentTypes.contains(contentType))
+                continue;
+            contentTypes.add(contentType);
+            IReconcilingStrategy s= getReconcilingStrategy(contentType);
+            if ( cast(IReconcilingStrategyExtension)s ) {
+                IReconcilingStrategyExtension e= cast(IReconcilingStrategyExtension) s;
+                e.initialReconcile();
+            }
+        }
+    }
+
+    /**
+     * Computes and returns the partitioning for the given region of the input document
+     * of the reconciler's connected text viewer.
+     *
+     * @param offset the region offset
+     * @param length the region length
+     * @return the computed partitioning
+     * @since 3.0
+     */
+    private ITypedRegion[] computePartitioning(int offset, int length) {
+        ITypedRegion[] regions= null;
+        try {
+            regions= TextUtilities.computePartitioning(getDocument(), getDocumentPartitioning(), offset, length, false);
+        } catch (BadLocationException x) {
+            regions= new ITypedRegion[0];
+        }
+        return regions;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/revisions/IRevisionListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.revisions.IRevisionListener;
+
+import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; // packageimport
+import dwtx.jface.text.revisions.RevisionRange; // packageimport
+import dwtx.jface.text.revisions.IRevisionRulerColumn; // packageimport
+import dwtx.jface.text.revisions.RevisionEvent; // packageimport
+import dwtx.jface.text.revisions.RevisionInformation; // packageimport
+import dwtx.jface.text.revisions.Revision; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/** 
+ * A listener which is notified when revision information changes.
+ *
+ * @see RevisionInformation
+ * @see IRevisionRulerColumnExtension
+ * @since 3.3
+ */
+public interface IRevisionListener {
+    /**
+     * Notifies the receiver that the revision information has been updated. This typically occurs
+     * when revision information is being displayed in an editor and the annotated document is
+     * modified.
+     * 
+     * @param e the revision event describing the change
+     */
+    void revisionInformationChanged(RevisionEvent e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/revisions/IRevisionRulerColumn.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.revisions.IRevisionRulerColumn;
+
+import dwtx.jface.text.revisions.IRevisionListener; // packageimport
+import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; // packageimport
+import dwtx.jface.text.revisions.RevisionRange; // packageimport
+import dwtx.jface.text.revisions.RevisionEvent; // packageimport
+import dwtx.jface.text.revisions.RevisionInformation; // packageimport
+import dwtx.jface.text.revisions.Revision; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.source.IVerticalRulerColumn;
+import dwtx.jface.text.source.IVerticalRulerInfo;
+import dwtx.jface.text.source.IVerticalRulerInfoExtension;
+
+/**
+ * A vertical ruler column capable of displaying revision (annotate) information.
+ *
+ * In order to provide backward compatibility for clients of
+ * <code>IRevisionRulerColumn</code>, extension interfaces are used as a means
+ * of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link IRevisionRulerColumnExtension} since
+ * version 3.3 allowing to register a selection listener on revisions and a configurable rendering mode.
+ * </li>
+ * </ul>
+ * 
+ * @since 3.2
+ * @see RevisionInformation
+ * @see IRevisionRulerColumnExtension
+ */
+public interface IRevisionRulerColumn : IVerticalRulerColumn, IVerticalRulerInfo, IVerticalRulerInfoExtension {
+    /**
+     * Sets the revision information.
+     * 
+     * @param info the new revision information, or <code>null</code> to reset the ruler
+     */
+    void setRevisionInformation(RevisionInformation info);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/revisions/IRevisionRulerColumnExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.revisions.IRevisionRulerColumnExtension;
+
+import dwtx.jface.text.revisions.IRevisionListener; // packageimport
+import dwtx.jface.text.revisions.RevisionRange; // packageimport
+import dwtx.jface.text.revisions.IRevisionRulerColumn; // packageimport
+import dwtx.jface.text.revisions.RevisionEvent; // packageimport
+import dwtx.jface.text.revisions.RevisionInformation; // packageimport
+import dwtx.jface.text.revisions.Revision; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.viewers.ISelectionProvider;
+
+    static this(){
+        IRevisionRulerColumnExtension_AUTHOR= new IRevisionRulerColumnExtension_RenderingMode("Author"); //$NON-NLS-1$
+        IRevisionRulerColumnExtension_AGE= new IRevisionRulerColumnExtension_RenderingMode("Age"); //$NON-NLS-1$
+        IRevisionRulerColumnExtension_AUTHOR_SHADED_BY_AGE= new IRevisionRulerColumnExtension_RenderingMode("Both"); //$NON-NLS-1$
+    }
+
+    /**
+     * Rendering mode type-safe enum.
+     */
+    final class RenderingMode {
+        private const String fName;
+        private this(String name) {
+            Assert.isLegal(name !is null);
+            fName= name;
+        }
+        /**
+         * Returns the name of the rendering mode.
+         * @return the name of the rendering mode
+         */
+        public String name() {
+            return fName;
+        }
+    }
+    alias RenderingMode IRevisionRulerColumnExtension_RenderingMode;
+
+
+    /**
+     * Rendering mode that assigns a unique color to each revision author.
+     */
+    static const RenderingMode IRevisionRulerColumnExtension_AUTHOR;
+    /**
+     * Rendering mode that assigns colors to revisions by their age.
+     * <p>
+     * Currently the most recent revision is red, the oldest is a faint yellow.
+     * The coloring scheme can change in future releases.
+     * </p>
+     */
+    static const RenderingMode IRevisionRulerColumnExtension_AGE;
+    /**
+     * Rendering mode that assigns unique colors per revision author and
+     * uses different color intensity depending on the age.
+     * <p>
+     * Currently it selects lighter colors for older revisions and more intense
+     * colors for more recent revisions.
+     * The coloring scheme can change in future releases.
+     * </p>
+     */
+    static const RenderingMode IRevisionRulerColumnExtension_AUTHOR_SHADED_BY_AGE;
+
+/**
+ * Extension interface for {@link IRevisionRulerColumn}.
+ * <p>
+ * Introduces the ability to register a selection listener on revisions and configurable rendering
+ * modes.
+ * </p>
+ *
+ * @see IRevisionRulerColumn
+ * @since 3.3
+ */
+public interface IRevisionRulerColumnExtension {
+
+    /**
+     * Changes the rendering mode and triggers redrawing if needed.
+     *
+     * @param mode the rendering mode
+     */
+    void setRevisionRenderingMode(RenderingMode mode);
+
+    /**
+     * Enables showing the revision id.
+     *
+     * @param show <code>true</code> to show the revision, <code>false</code> to hide it
+     */
+    void showRevisionId(bool show);
+
+    /**
+     * Enables showing the revision author.
+     *
+     * @param show <code>true</code> to show the author, <code>false</code> to hide it
+     */
+    void showRevisionAuthor(bool show);
+
+    /**
+     * Returns the revision selection provider.
+     *
+     * @return the revision selection provider
+     */
+    ISelectionProvider getRevisionSelectionProvider();
+
+    /**
+     * Adds a revision listener that will be notified when the displayed revision information
+     * changes.
+     *
+     * @param listener the listener to add
+     */
+    void addRevisionListener(IRevisionListener listener);
+
+    /**
+     * Removes a previously registered revision listener; nothing happens if <code>listener</code>
+     * was not registered with the receiver.
+     *
+     * @param listener the listener to remove
+     */
+    void removeRevisionListener(IRevisionListener listener);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/revisions/Revision.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.revisions.Revision;
+
+import dwtx.jface.text.revisions.IRevisionListener; // packageimport
+import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; // packageimport
+import dwtx.jface.text.revisions.RevisionRange; // packageimport
+import dwtx.jface.text.revisions.IRevisionRulerColumn; // packageimport
+import dwtx.jface.text.revisions.RevisionEvent; // packageimport
+import dwtx.jface.text.revisions.RevisionInformation; // packageimport
+
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import dwtx.dwtxhelper.Date;
+
+import dwt.graphics.RGB;
+import dwtx.jface.internal.text.revisions.ChangeRegion;
+import dwtx.jface.internal.text.revisions.Hunk;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.source.ILineRange;
+
+/**
+ * Describes a revision of a document. A revision consists of one ore more {@link ILineRange}s.
+ * <p>
+ * Clients may subclass.
+ * </p>
+ *
+ * @since 3.2
+ */
+public abstract class Revision {
+    /** The original list of change regions, element type: {@link ChangeRegion}. */
+    private const List fChangeRegions;
+    /**
+     * The cached list of adjusted ranges, element type: {@link RevisionRange}. <code>null</code>
+     * if the list must be re-computed. Unmodifiable.
+     *
+     * @since 3.3
+     */
+    private List fRanges= null;
+
+    /**
+     * Creates a new revision.
+     */
+    protected this() {
+        fChangeRegions= new ArrayList();
+    }
+
+    /**
+     * Adds a line range to this revision. The range must be non-empty and have a legal start line
+     * (not -1).
+     *
+     * @param range a line range that was changed with this revision
+     * @throws IndexOutOfBoundsException if the line range is empty or has a negative start line
+     */
+    public final void addRange(ILineRange range)  {
+        fChangeRegions.add(new ChangeRegion(this, range));
+    }
+
+    /**
+     * Returns the contained {@link RevisionRange}s adapted to the current diff state. The returned
+     * information is only valid at the moment it is returned, and may change as the annotated
+     * document is modified.
+     *
+     * @return an unmodifiable view of the contained ranges (element type: {@link RevisionRange})
+     */
+    public final List getRegions() {
+        if (fRanges is null) {
+            List ranges= new ArrayList(fChangeRegions.size());
+            for (Iterator it= fChangeRegions.iterator(); it.hasNext();) {
+                ChangeRegion region= cast(ChangeRegion) it.next();
+                for (Iterator inner= region.getAdjustedRanges().iterator(); inner.hasNext();) {
+                    ILineRange range= cast(ILineRange) inner.next();
+                    ranges.add(new RevisionRange(this, range));
+                }
+            }
+            fRanges= Collections.unmodifiableList(ranges);
+        }
+        return fRanges;
+    }
+
+    /**
+     * Adjusts the revision information to the given diff information. Any previous diff information
+     * is discarded.
+     *
+     * @param hunks the diff hunks to adjust the revision information to
+     * @since 3.3
+     */
+    final void applyDiff(Hunk[] hunks) {
+        fRanges= null; // mark for recomputation
+        for (Iterator regions= fChangeRegions.iterator(); regions.hasNext();) {
+            ChangeRegion region= cast(ChangeRegion) regions.next();
+            region.clearDiff();
+            for (int i= 0; i < hunks.length; i++) {
+                Hunk hunk= hunks[i];
+                region.adjustTo(hunk);
+            }
+        }
+    }
+
+    /**
+     * Returns the hover information that will be shown when the user hovers over the a change
+     * region of this revision.
+     * <p>
+     * <strong>Note:</strong> The hover information control which is used to display the information
+     * must be able process the given object. If the default information control creator is used
+     * the supported format is simple text, full HTML or an HTML fragment.
+     * </p>
+     *
+     * @return the hover information for this revision or <code>null</code> for no hover
+     * @see RevisionInformation#setHoverControlCreator(IInformationControlCreator)
+     */
+    public abstract Object getHoverInfo();
+
+    /**
+     * Returns the author color for this revision. This color can be used to visually distinguish
+     * one revision from another, for example as background color.
+     * <p>
+     * Revisions from the same author must return the same color and revisions from different authors
+     * must return distinct colors.</p>
+     *
+     * @return the RGB color for this revision's author
+     */
+    public abstract RGB getColor();
+
+    /**
+     * Returns the unique (within the document) id of this revision. This may be the version string
+     * or a different identifier.
+     *
+     * @return the id of this revision
+     */
+    public abstract String getId();
+
+    /**
+     * Returns the modification date of this revision.
+     *
+     * @return the modification date of this revision
+     */
+    public abstract Date getDate();
+
+    /*
+     * @see java.lang.Object#toString()
+     */
+    public override String toString() {
+        return "Revision " ~ getId(); //$NON-NLS-1$
+    }
+
+    /**
+     * Returns the display string for the author of this revision.
+     * <p>
+     * Subclasses should replace - the default implementation returns the empty string.
+     * </p>
+     *
+     * @return the author name
+     * @since 3.3
+     */
+    public String getAuthor() {
+        return ""; //$NON-NLS-1$
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/revisions/RevisionEvent.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.revisions.RevisionEvent;
+
+import dwtx.jface.text.revisions.IRevisionListener; // packageimport
+import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; // packageimport
+import dwtx.jface.text.revisions.RevisionRange; // packageimport
+import dwtx.jface.text.revisions.IRevisionRulerColumn; // packageimport
+import dwtx.jface.text.revisions.RevisionInformation; // packageimport
+import dwtx.jface.text.revisions.Revision; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Informs about a change of revision information.
+ * <p>
+ * Clients may use but not instantiate this class.
+ * </p>
+ * 
+ * @since 3.3
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class RevisionEvent {
+    
+    private const RevisionInformation fInformation;
+
+    /**
+     * Creates a new event.
+     * 
+     * @param information the revision info
+     */
+    public this(RevisionInformation information) {
+        Assert.isLegal(information !is null);
+        fInformation= information;
+    }
+
+    /**
+     * Returns the revision information that has changed.
+     * 
+     * @return the revision information that has changed
+     */
+    public RevisionInformation getRevisionInformation() {
+        return fInformation;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/revisions/RevisionInformation.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.revisions.RevisionInformation;
+
+import dwtx.jface.text.revisions.IRevisionListener; // packageimport
+import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; // packageimport
+import dwtx.jface.text.revisions.RevisionRange; // packageimport
+import dwtx.jface.text.revisions.IRevisionRulerColumn; // packageimport
+import dwtx.jface.text.revisions.RevisionEvent; // packageimport
+import dwtx.jface.text.revisions.Revision; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.internal.text.revisions.Hunk;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.ITextHoverExtension;
+import dwtx.jface.text.information.IInformationProviderExtension2;
+
+/**
+ * Encapsulates revision information for one line-based document.
+ * <p>
+ * Clients may instantiate.
+ * </p>
+ *
+ * @since 3.2
+ * @see Revision
+ */
+public final class RevisionInformation : ITextHoverExtension, IInformationProviderExtension2 {
+    /** The revisions, element type: {@link Revision}. */
+    private const List fRevisions;
+    /** A unmodifiable view of <code>fRevisions</code>. */
+    private const List fRORevisions;
+    /**
+     * The flattened list of {@link RevisionRange}s, unmodifiable. <code>null</code> if the list
+     * must be re-computed.
+     *
+     * @since 3.3
+     */
+    private List fRanges= null;
+
+    /**
+     * The hover control creator. Can be <code>null</code>.
+     *
+     * @since 3.3
+     */
+    private IInformationControlCreator fHoverControlCreator;
+
+    /**
+     * The information presenter control creator. Can be <code>null</code>.
+     *
+     * @since 3.3
+     */
+    private IInformationControlCreator fInformationPresenterControlCreator;
+
+    /**
+     * Creates a new revision information model.
+     */
+    public this() {
+        fRevisions= new ArrayList();
+        fRORevisions= Collections.unmodifiableList(fRevisions);
+    }
+
+    /**
+     * Adds a revision.
+     *
+     * @param revision a revision
+     */
+    public void addRevision(Revision revision) {
+        Assert.isLegal(revision !is null);
+        fRevisions.add(revision);
+    }
+
+    /**
+     * Returns the contained revisions.
+     *
+     * @return an unmodifiable view of the contained revisions (element type: {@link Revision})
+     */
+    public List getRevisions() {
+        return fRORevisions;
+    }
+
+    /**
+     * Returns the line ranges of this revision information. The returned information is only valid
+     * at the moment it is returned, and may change as the annotated document is modified. See
+     * {@link IRevisionListener} for a way to be informed when the revision information changes. The
+     * returned list is sorted by document offset.
+     *
+     * @return an unmodifiable view of the line ranges (element type: {@link RevisionRange})
+     * @see IRevisionListener
+     * @since 3.3
+     */
+    public List getRanges() {
+        if (fRanges is null) {
+            List ranges= new ArrayList(fRevisions.size() * 2); // wild size guess
+            for (Iterator it= fRevisions.iterator(); it.hasNext();) {
+                Revision revision= cast(Revision) it.next();
+                ranges.addAll(revision.getRegions());
+            }
+
+            // sort by start line
+            Collections.sort(ranges, new class()  Comparator {
+                public int compare(Object o1, Object o2) {
+                    RevisionRange r1= cast(RevisionRange) o1;
+                    RevisionRange r2= cast(RevisionRange) o2;
+
+                    return r1.getStartLine() - r2.getStartLine();
+                }
+            });
+
+            fRanges= Collections.unmodifiableList(ranges);
+        }
+        return fRanges;
+    }
+
+    /**
+     * Adjusts the revision information to the given diff information. Any previous diff information is discarded. <strong>Note</strong>: This is an internal framework method and must not be called by clients.
+     *
+     * @param hunks the diff hunks to adjust the revision information to
+     * @since 3.3
+     * @noreference This method is not intended to be referenced by clients.
+     */
+    public void applyDiff(Hunk[] hunks) {
+        fRanges= null; // mark for recomputation
+        for (Iterator revisions= getRevisions().iterator(); revisions.hasNext();)
+            (cast(Revision) revisions.next()).applyDiff(hunks);
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextHoverExtension#getHoverControlCreator()
+     * @since 3.3
+     */
+    public IInformationControlCreator getHoverControlCreator() {
+        return fHoverControlCreator;
+    }
+
+    /**
+     * {@inheritDoc}
+     * @return the information control creator or <code>null</code>
+     * @since 3.3
+     */
+    public IInformationControlCreator getInformationPresenterControlCreator() {
+        return fInformationPresenterControlCreator;
+    }
+
+    /**
+     * Sets the hover control creator.
+     * <p>
+     * <strong>Note:</strong> The created information control must be able to display the object
+     * returned by the concrete implementation of {@link Revision#getHoverInfo()}.
+     * </p>
+     *
+     * @param creator the control creator
+     * @since 3.3
+     */
+    public void setHoverControlCreator(IInformationControlCreator creator) {
+        fHoverControlCreator= creator;
+    }
+
+    /**
+     * Sets the information presenter control creator.
+     *
+     * @param creator the control creator
+     * @since 3.3
+     */
+    public void setInformationPresenterControlCreator(IInformationControlCreator creator) {
+        fInformationPresenterControlCreator= creator;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/revisions/RevisionRange.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.revisions.RevisionRange;
+
+import dwtx.jface.text.revisions.IRevisionListener; // packageimport
+import dwtx.jface.text.revisions.IRevisionRulerColumnExtension; // packageimport
+import dwtx.jface.text.revisions.IRevisionRulerColumn; // packageimport
+import dwtx.jface.text.revisions.RevisionEvent; // packageimport
+import dwtx.jface.text.revisions.RevisionInformation; // packageimport
+import dwtx.jface.text.revisions.Revision; // packageimport
+
+
+import dwt.dwthelper.utils;
+import tango.text.convert.Format;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.source.ILineRange;
+
+
+/**
+ * An unmodifiable line range that belongs to a {@link Revision}.
+ *
+ * @since 3.3
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class RevisionRange : ILineRange {
+    private const Revision fRevision;
+    private const int fStartLine;
+    private const int fNumberOfLines;
+
+    this(Revision revision, ILineRange range) {
+        Assert.isLegal(revision !is null);
+        fRevision= revision;
+        fStartLine= range.getStartLine();
+        fNumberOfLines= range.getNumberOfLines();
+    }
+
+    /**
+     * Returns the revision that this range belongs to.
+     *
+     * @return the revision that this range belongs to
+     */
+    public Revision getRevision() {
+        return fRevision;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ILineRange#getStartLine()
+     */
+    public int getStartLine() {
+        return fStartLine;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ILineRange#getNumberOfLines()
+     */
+    public int getNumberOfLines() {
+        return fNumberOfLines;
+    }
+
+    /*
+     * @see java.lang.Object#toString()
+     */
+    public override String toString() {
+        return Format("RevisionRange [{}, [{}+{})]", fRevision.toString(), getStartLine(), getNumberOfLines()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/BufferedRuleBasedScanner.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,170 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.rules.BufferedRuleBasedScanner;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+
+/**
+ * A buffered rule based scanner. The buffer always contains a section
+ * of a fixed size of the document to be scanned. Completely adheres to
+ * the contract of <code>RuleBasedScanner</code>.
+ */
+public class BufferedRuleBasedScanner : RuleBasedScanner {
+
+    /** The default buffer size. Value = 500 */
+    private const static int DEFAULT_BUFFER_SIZE= 500;
+    /** The actual size of the buffer. Initially set to <code>DEFAULT_BUFFER_SIZE</code> */
+    private int fBufferSize= DEFAULT_BUFFER_SIZE;
+    /** The buffer */
+    private char[] fBuffer;
+    /** The offset of the document at which the buffer starts */
+    private int fStart;
+    /** The offset of the document at which the buffer ends */
+    private int fEnd;
+    /** The cached length of the document */
+    private int fDocumentLength;
+
+
+    /**
+     * Creates a new buffered rule based scanner which does
+     * not have any rule and a default buffer size of 500 characters.
+     */
+    protected this() {
+        super();
+        fBuffer= new char[DEFAULT_BUFFER_SIZE];
+        fBuffer[] = 0;
+    }
+
+    /**
+     * Creates a new buffered rule based scanner which does
+     * not have any rule. The buffer size is set to the given
+     * number of characters.
+     *
+     * @param size the buffer size
+     */
+    public this(int size) {
+        super();
+        fBuffer= new char[DEFAULT_BUFFER_SIZE];
+        fBuffer[] = 0;
+        setBufferSize(size);
+    }
+
+    /**
+     * Sets the buffer to the given number of characters.
+     *
+     * @param size the buffer size
+     */
+    protected void setBufferSize(int size) {
+        Assert.isTrue(size > 0);
+        fBufferSize= size;
+        fBuffer= new char[size];
+        fBuffer[] = 0;
+    }
+
+    /**
+     * Shifts the buffer so that the buffer starts at the
+     * given document offset.
+     *
+     * @param offset the document offset at which the buffer starts
+     */
+    private void shiftBuffer(int offset) {
+
+        fStart= offset;
+        fEnd= fStart + fBufferSize;
+        if (fEnd > fDocumentLength)
+            fEnd= fDocumentLength;
+
+        try {
+
+            String content= fDocument.get(fStart, fEnd - fStart);
+            content.getChars(0, fEnd - fStart, fBuffer, 0);
+
+        } catch (BadLocationException x) {
+        }
+    }
+
+    /*
+     * @see RuleBasedScanner#setRange(IDocument, int, int)
+     */
+    public void setRange(IDocument document, int offset, int length) {
+
+        super.setRange(document, offset, length);
+
+        fDocumentLength= document.getLength();
+        shiftBuffer(offset);
+    }
+
+    /*
+     * @see RuleBasedScanner#read()
+     */
+    public int read() {
+        fColumn= UNDEFINED;
+        if (fOffset >= fRangeEnd) {
+            ++ fOffset;
+            return EOF;
+        }
+
+        if (fOffset is fEnd)
+            shiftBuffer(fEnd);
+        else if (fOffset < fStart || fEnd < fOffset)
+            shiftBuffer(fOffset);
+
+        return fBuffer[fOffset++ - fStart];
+    }
+
+    /*
+     * @see RuleBasedScanner#unread()
+     */
+    public void unread() {
+
+        if (fOffset is fStart)
+            shiftBuffer(Math.max(0, fStart - (fBufferSize / 2)));
+
+        --fOffset;
+        fColumn= UNDEFINED;
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/DefaultDamagerRepairer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,259 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.rules.DefaultDamagerRepairer;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+
+
+
+import dwt.DWT;
+import dwt.custom.StyleRange;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITypedRegion;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextAttribute;
+import dwtx.jface.text.TextPresentation;
+import dwtx.jface.text.presentation.IPresentationDamager;
+import dwtx.jface.text.presentation.IPresentationRepairer;
+
+
+/**
+ * A standard implementation of a syntax driven presentation damager
+ * and presentation repairer. It uses a token scanner to scan
+ * the document and to determine its damage and new text presentation.
+ * The tokens returned by the scanner are supposed to return text attributes
+ * as their data.
+ *
+ * @see ITokenScanner
+ * @since 2.0
+ */
+public class DefaultDamagerRepairer : IPresentationDamager, IPresentationRepairer {
+
+
+    /** The document this object works on */
+    protected IDocument fDocument;
+    /** The scanner it uses */
+    protected ITokenScanner fScanner;
+    /** The default text attribute if non is returned as data by the current token */
+    protected TextAttribute fDefaultTextAttribute;
+
+    /**
+     * Creates a damager/repairer that uses the given scanner and returns the given default
+     * text attribute if the current token does not carry a text attribute.
+     *
+     * @param scanner the token scanner to be used
+     * @param defaultTextAttribute the text attribute to be returned if non is specified by the current token,
+     *          may not be <code>null</code>
+     *
+     * @deprecated use DefaultDamagerRepairer(ITokenScanner) instead
+     */
+    public this(ITokenScanner scanner, TextAttribute defaultTextAttribute) {
+
+        Assert.isNotNull(defaultTextAttribute);
+
+        fScanner= scanner;
+        fDefaultTextAttribute= defaultTextAttribute;
+    }
+
+    /**
+     * Creates a damager/repairer that uses the given scanner. The scanner may not be <code>null</code>
+     * and is assumed to return only token that carry text attributes.
+     *
+     * @param scanner the token scanner to be used, may not be <code>null</code>
+     */
+    public this(ITokenScanner scanner) {
+
+        Assert.isNotNull(cast(Object)scanner);
+
+        fScanner= scanner;
+        fDefaultTextAttribute= new TextAttribute(null);
+    }
+
+    /*
+     * @see IPresentationDamager#setDocument(IDocument)
+     * @see IPresentationRepairer#setDocument(IDocument)
+     */
+    public void setDocument(IDocument document) {
+        fDocument= document;
+    }
+
+
+    //---- IPresentationDamager
+
+    /**
+     * Returns the end offset of the line that contains the specified offset or
+     * if the offset is inside a line delimiter, the end offset of the next line.
+     *
+     * @param offset the offset whose line end offset must be computed
+     * @return the line end offset for the given offset
+     * @exception BadLocationException if offset is invalid in the current document
+     */
+    protected int endOfLineOf(int offset)  {
+
+        IRegion info= fDocument.getLineInformationOfOffset(offset);
+        if (offset <= info.getOffset() + info.getLength())
+            return info.getOffset() + info.getLength();
+
+        int line= fDocument.getLineOfOffset(offset);
+        try {
+            info= fDocument.getLineInformation(line + 1);
+            return info.getOffset() + info.getLength();
+        } catch (BadLocationException x) {
+            return fDocument.getLength();
+        }
+    }
+
+    /*
+     * @see IPresentationDamager#getDamageRegion(ITypedRegion, DocumentEvent, bool)
+     */
+    public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent e, bool documentPartitioningChanged) {
+
+        if (!documentPartitioningChanged) {
+            try {
+
+                IRegion info= fDocument.getLineInformationOfOffset(e.getOffset());
+                int start= Math.max(partition.getOffset(), info.getOffset());
+
+                int end= e.getOffset() + (e.getText() is null ? e.getLength() : e.getText().length());
+
+                if (info.getOffset() <= end && end <= info.getOffset() + info.getLength()) {
+                    // optimize the case of the same line
+                    end= info.getOffset() + info.getLength();
+                } else
+                    end= endOfLineOf(end);
+
+                end= Math.min(partition.getOffset() + partition.getLength(), end);
+                return new Region(start, end - start);
+
+            } catch (BadLocationException x) {
+            }
+        }
+
+        return partition;
+    }
+
+    //---- IPresentationRepairer
+
+    /*
+     * @see IPresentationRepairer#createPresentation(TextPresentation, ITypedRegion)
+     */
+    public void createPresentation(TextPresentation presentation, ITypedRegion region) {
+
+        if (fScanner is null) {
+            // will be removed if deprecated constructor will be removed
+            addRange(presentation, region.getOffset(), region.getLength(), fDefaultTextAttribute);
+            return;
+        }
+
+        int lastStart= region.getOffset();
+        int length= 0;
+        bool firstToken= true;
+        IToken lastToken= Token.UNDEFINED;
+        TextAttribute lastAttribute= getTokenTextAttribute(lastToken);
+
+        fScanner.setRange(fDocument, lastStart, region.getLength());
+
+        while (true) {
+            IToken token= fScanner.nextToken();
+            if (token.isEOF())
+                break;
+
+            TextAttribute attribute= getTokenTextAttribute(token);
+            if (lastAttribute !is null && lastAttribute.equals(attribute)) {
+                length += fScanner.getTokenLength();
+                firstToken= false;
+            } else {
+                if (!firstToken)
+                    addRange(presentation, lastStart, length, lastAttribute);
+                firstToken= false;
+                lastToken= token;
+                lastAttribute= attribute;
+                lastStart= fScanner.getTokenOffset();
+                length= fScanner.getTokenLength();
+            }
+        }
+
+        addRange(presentation, lastStart, length, lastAttribute);
+    }
+
+    /**
+     * Returns a text attribute encoded in the given token. If the token's
+     * data is not <code>null</code> and a text attribute it is assumed that
+     * it is the encoded text attribute. It returns the default text attribute
+     * if there is no encoded text attribute found.
+     *
+     * @param token the token whose text attribute is to be determined
+     * @return the token's text attribute
+     */
+    protected TextAttribute getTokenTextAttribute(IToken token) {
+        Object data= token.getData();
+        if ( cast(TextAttribute)data )
+            return cast(TextAttribute) data;
+        return fDefaultTextAttribute;
+    }
+
+    /**
+     * Adds style information to the given text presentation.
+     *
+     * @param presentation the text presentation to be extended
+     * @param offset the offset of the range to be styled
+     * @param length the length of the range to be styled
+     * @param attr the attribute describing the style of the range to be styled
+     */
+    protected void addRange(TextPresentation presentation, int offset, int length, TextAttribute attr) {
+        if (attr !is null) {
+            int style= attr.getStyle();
+            int fontStyle= style & (DWT.ITALIC | DWT.BOLD | DWT.NORMAL);
+            StyleRange styleRange= new StyleRange(offset, length, attr.getForeground(), attr.getBackground(), fontStyle);
+            styleRange.strikeout= (style & TextAttribute.STRIKETHROUGH) !is 0;
+            styleRange.underline= (style & TextAttribute.UNDERLINE) !is 0;
+            styleRange.font= attr.getFont();
+            presentation.addStyleRange(styleRange);
+        }
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/DefaultPartitioner.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,760 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.rules.DefaultPartitioner;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DefaultPositionUpdater;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.DocumentRewriteSession;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentPartitioner;
+import dwtx.jface.text.IDocumentPartitionerExtension;
+import dwtx.jface.text.IDocumentPartitionerExtension2;
+import dwtx.jface.text.IDocumentPartitionerExtension3;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITypedRegion;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextUtilities;
+import dwtx.jface.text.TypedPosition;
+import dwtx.jface.text.TypedRegion;
+
+
+
+/**
+ * A standard implementation of a document partitioner. It uses a partition
+ * token scanner to scan the document and to determine the document's
+ * partitioning. The tokens returned by the scanner are supposed to return the
+ * partition type as their data. The partitioner remembers the document's
+ * partitions in the document itself rather than maintaining its own data
+ * structure.
+ *
+ * @see IPartitionTokenScanner
+ * @since 2.0
+ * @deprecated As of 3.1, replaced by {@link dwtx.jface.text.rules.FastPartitioner} instead
+ */
+public class DefaultPartitioner : IDocumentPartitioner, IDocumentPartitionerExtension, IDocumentPartitionerExtension2, IDocumentPartitionerExtension3 {
+
+    /**
+     * The position category this partitioner uses to store the document's partitioning information.
+     * @deprecated As of 3.0, use <code>getManagingPositionCategories()</code> instead.
+     */
+    public const static String CONTENT_TYPES_CATEGORY= "__content_types_category"; //$NON-NLS-1$
+
+
+    /** The partitioner's scanner */
+    protected IPartitionTokenScanner fScanner;
+    /** The legal content types of this partitioner */
+    protected String[] fLegalContentTypes;
+    /** The partitioner's document */
+    protected IDocument fDocument;
+    /** The document length before a document change occurred */
+    protected int fPreviousDocumentLength;
+    /** The position updater used to for the default updating of partitions */
+    protected DefaultPositionUpdater fPositionUpdater;
+    /** The offset at which the first changed partition starts */
+    protected int fStartOffset;
+    /** The offset at which the last changed partition ends */
+    protected int fEndOffset;
+    /**The offset at which a partition has been deleted */
+    protected int fDeleteOffset;
+    /**
+     * The position category this partitioner uses to store the document's partitioning information.
+     * @since 3.0
+     */
+    private String fPositionCategory;
+    /**
+     * The active document rewrite session.
+     * @since 3.1
+     */
+    private DocumentRewriteSession fActiveRewriteSession;
+    /**
+     * Flag indicating whether this partitioner has been initialized.
+     * @since 3.1
+     */
+    private bool fIsInitialized= false;
+
+    /**
+     * Creates a new partitioner that uses the given scanner and may return
+     * partitions of the given legal content types.
+     *
+     * @param scanner the scanner this partitioner is supposed to use
+     * @param legalContentTypes the legal content types of this partitioner
+     */
+    public this(IPartitionTokenScanner scanner, String[] legalContentTypes) {
+        fScanner= scanner;
+        fLegalContentTypes= TextUtilities.copy(legalContentTypes);
+        fPositionCategory= CONTENT_TYPES_CATEGORY ~ Integer.toString(toHash());
+        fPositionUpdater= new DefaultPositionUpdater(fPositionCategory);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension2#getManagingPositionCategories()
+     * @since 3.0
+     */
+    public String[] getManagingPositionCategories() {
+        return [ fPositionCategory ];
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitioner#connect(dwtx.jface.text.IDocument)
+     */
+    public void connect(IDocument document) {
+        connect(document, false);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension3#connect(dwtx.jface.text.IDocument, bool)
+     * @since 3.1
+     */
+    public void connect(IDocument document, bool delayInitialization) {
+        Assert.isNotNull(cast(Object)document);
+        Assert.isTrue(!document.containsPositionCategory(fPositionCategory));
+
+        fDocument= document;
+        fDocument.addPositionCategory(fPositionCategory);
+
+        fIsInitialized= false;
+        if (!delayInitialization)
+            checkInitialization();
+    }
+
+    /*
+     * @since 3.1
+     */
+    protected final void checkInitialization() {
+        if (!fIsInitialized)
+            initialize();
+    }
+
+    /**
+     * Performs the initial partitioning of the partitioner's document.
+     */
+    protected void initialize() {
+        fIsInitialized= true;
+        fScanner.setRange(fDocument, 0, fDocument.getLength());
+
+        try {
+            IToken token= fScanner.nextToken();
+            while (!token.isEOF()) {
+
+                String contentType= getTokenContentType(token);
+
+                if (isSupportedContentType(contentType)) {
+                    TypedPosition p= new TypedPosition(fScanner.getTokenOffset(), fScanner.getTokenLength(), contentType);
+                    fDocument.addPosition(fPositionCategory, p);
+                }
+
+                token= fScanner.nextToken();
+            }
+        } catch (BadLocationException x) {
+            // cannot happen as offsets come from scanner
+        } catch (BadPositionCategoryException x) {
+            // cannot happen if document has been connected before
+        }
+    }
+
+    /*
+     * @see IDocumentPartitioner#disconnect()
+     */
+    public void disconnect() {
+
+        Assert.isTrue(fDocument.containsPositionCategory(fPositionCategory));
+
+        try {
+            fDocument.removePositionCategory(fPositionCategory);
+        } catch (BadPositionCategoryException x) {
+            // can not happen because of Assert
+        }
+    }
+
+    /*
+     * @see IDocumentPartitioner#documentAboutToBeChanged(DocumentEvent)
+     */
+    public void documentAboutToBeChanged(DocumentEvent e) {
+        if (fIsInitialized) {
+
+            Assert.isTrue(e.getDocument() is fDocument);
+
+            fPreviousDocumentLength= e.getDocument().getLength();
+            fStartOffset= -1;
+            fEndOffset= -1;
+            fDeleteOffset= -1;
+        }
+    }
+
+    /*
+     * @see IDocumentPartitioner#documentChanged(DocumentEvent)
+     */
+    public bool documentChanged(DocumentEvent e) {
+        if (fIsInitialized) {
+            IRegion region= documentChanged2(e);
+            return (region !is null);
+        }
+        return false;
+    }
+
+    /**
+     * Helper method for tracking the minimal region containing all partition changes.
+     * If <code>offset</code> is smaller than the remembered offset, <code>offset</code>
+     * will from now on be remembered. If <code>offset  + length</code> is greater than
+     * the remembered end offset, it will be remembered from now on.
+     *
+     * @param offset the offset
+     * @param length the length
+     */
+    private void rememberRegion(int offset, int length) {
+        // remember start offset
+        if (fStartOffset is -1)
+            fStartOffset= offset;
+        else if (offset < fStartOffset)
+            fStartOffset= offset;
+
+        // remember end offset
+        int endOffset= offset + length;
+        if (fEndOffset is -1)
+            fEndOffset= endOffset;
+        else if (endOffset > fEndOffset)
+            fEndOffset= endOffset;
+    }
+
+    /**
+     * Remembers the given offset as the deletion offset.
+     *
+     * @param offset the offset
+     */
+    private void rememberDeletedOffset(int offset) {
+        fDeleteOffset= offset;
+    }
+
+    /**
+     * Creates the minimal region containing all partition changes using the
+     * remembered offset, end offset, and deletion offset.
+     *
+     * @return the minimal region containing all the partition changes
+     */
+    private IRegion createRegion() {
+        if (fDeleteOffset is -1) {
+            if (fStartOffset is -1 || fEndOffset is -1)
+                return null;
+            return new Region(fStartOffset, fEndOffset - fStartOffset);
+        } else if (fStartOffset is -1 || fEndOffset is -1) {
+            return new Region(fDeleteOffset, 0);
+        } else {
+            int offset= Math.min(fDeleteOffset, fStartOffset);
+            int endOffset= Math.max(fDeleteOffset, fEndOffset);
+            return new Region(offset, endOffset - offset);
+        }
+    }
+
+    /*
+     * @see IDocumentPartitionerExtension#documentChanged2(DocumentEvent)
+     * @since 2.0
+     */
+    public IRegion documentChanged2(DocumentEvent e) {
+
+        if (!fIsInitialized)
+            return null;
+
+        try {
+
+            IDocument d= e.getDocument();
+            Position[] category= d.getPositions(fPositionCategory);
+            IRegion line= d.getLineInformationOfOffset(e.getOffset());
+            int reparseStart= line.getOffset();
+            int partitionStart= -1;
+            String contentType= null;
+            int newLength= e.getText() is null ? 0 : e.getText().length();
+
+            int first= d.computeIndexInCategory(fPositionCategory, reparseStart);
+            if (first > 0)  {
+                TypedPosition partition= cast(TypedPosition) category[first - 1];
+                if (partition.includes(reparseStart)) {
+                    partitionStart= partition.getOffset();
+                    contentType= partition.getType();
+                    if (e.getOffset() is partition.getOffset() + partition.getLength())
+                        reparseStart= partitionStart;
+                    -- first;
+                } else if (reparseStart is e.getOffset() && reparseStart is partition.getOffset() + partition.getLength()) {
+                    partitionStart= partition.getOffset();
+                    contentType= partition.getType();
+                    reparseStart= partitionStart;
+                    -- first;
+                } else {
+                    partitionStart= partition.getOffset() + partition.getLength();
+                    contentType= IDocument.DEFAULT_CONTENT_TYPE;
+                }
+            }
+
+            fPositionUpdater.update(e);
+            for (int i= first; i < category.length; i++) {
+                Position p= category[i];
+                if (p.isDeleted) {
+                    rememberDeletedOffset(e.getOffset());
+                    break;
+                }
+            }
+            category= d.getPositions(fPositionCategory);
+
+            fScanner.setPartialRange(d, reparseStart, d.getLength() - reparseStart, contentType, partitionStart);
+
+            int lastScannedPosition= reparseStart;
+            IToken token= fScanner.nextToken();
+
+            while (!token.isEOF()) {
+
+                contentType= getTokenContentType(token);
+
+                if (!isSupportedContentType(contentType)) {
+                    token= fScanner.nextToken();
+                    continue;
+                }
+
+                int start= fScanner.getTokenOffset();
+                int length= fScanner.getTokenLength();
+
+                lastScannedPosition= start + length - 1;
+
+                // remove all affected positions
+                while (first < category.length) {
+                    TypedPosition p= cast(TypedPosition) category[first];
+                    if (lastScannedPosition >= p.offset + p.length ||
+                            (p.overlapsWith(start, length) &&
+                                (!d.containsPosition(fPositionCategory, start, length) ||
+                                 !contentType.equals(p.getType())))) {
+
+                        rememberRegion(p.offset, p.length);
+                        d.removePosition(fPositionCategory, p);
+                        ++ first;
+
+                    } else
+                        break;
+                }
+
+                // if position already exists and we have scanned at least the
+                // area covered by the event, we are done
+                if (d.containsPosition(fPositionCategory, start, length)) {
+                    if (lastScannedPosition >= e.getOffset() + newLength)
+                        return createRegion();
+                    ++ first;
+                } else {
+                    // insert the new type position
+                    try {
+                        d.addPosition(fPositionCategory, new TypedPosition(start, length, contentType));
+                        rememberRegion(start, length);
+                    } catch (BadPositionCategoryException x) {
+                    } catch (BadLocationException x) {
+                    }
+                }
+
+                token= fScanner.nextToken();
+            }
+
+
+            // remove all positions behind lastScannedPosition since there aren't any further types
+            if (lastScannedPosition !is reparseStart) {
+                // if this condition is not met, nothing has been scanned because of a deletion
+                ++ lastScannedPosition;
+            }
+            first= d.computeIndexInCategory(fPositionCategory, lastScannedPosition);
+            category= d.getPositions(fPositionCategory);
+
+            TypedPosition p;
+            while (first < category.length) {
+                p= cast(TypedPosition) category[first++];
+                d.removePosition(fPositionCategory, p);
+                rememberRegion(p.offset, p.length);
+            }
+
+        } catch (BadPositionCategoryException x) {
+            // should never happen on connected documents
+        } catch (BadLocationException x) {
+        }
+
+        return createRegion();
+    }
+
+
+    /**
+     * Returns the position in the partitoner's position category which is
+     * close to the given offset. This is, the position has either an offset which
+     * is the same as the given offset or an offset which is smaller than the given
+     * offset. This method profits from the knowledge that a partitioning is
+     * a ordered set of disjoint position.
+     *
+     * @param offset the offset for which to search the closest position
+     * @return the closest position in the partitioner's category
+     */
+    protected TypedPosition findClosestPosition(int offset) {
+
+        try {
+
+            int index= fDocument.computeIndexInCategory(fPositionCategory, offset);
+            Position[] category= fDocument.getPositions(fPositionCategory);
+
+            if (category.length is 0)
+                return null;
+
+            if (index < category.length) {
+                if (offset is category[index].offset)
+                    return cast(TypedPosition) category[index];
+            }
+
+            if (index > 0)
+                index--;
+
+            return cast(TypedPosition) category[index];
+
+        } catch (BadPositionCategoryException x) {
+        } catch (BadLocationException x) {
+        }
+
+        return null;
+    }
+
+
+    /*
+     * @see IDocumentPartitioner#getContentType(int)
+     */
+    public String getContentType(int offset) {
+        checkInitialization();
+
+        TypedPosition p= findClosestPosition(offset);
+        if (p !is null && p.includes(offset))
+            return p.getType();
+
+        return IDocument.DEFAULT_CONTENT_TYPE;
+    }
+
+    /*
+     * @see IDocumentPartitioner#getPartition(int)
+     */
+    public ITypedRegion getPartition(int offset) {
+        checkInitialization();
+
+        try {
+
+            Position[] category = fDocument.getPositions(fPositionCategory);
+
+            if (category is null || category.length is 0)
+                return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE);
+
+            int index= fDocument.computeIndexInCategory(fPositionCategory, offset);
+
+            if (index < category.length) {
+
+                TypedPosition next= cast(TypedPosition) category[index];
+
+                if (offset is next.offset)
+                    return new TypedRegion(next.getOffset(), next.getLength(), next.getType());
+
+                if (index is 0)
+                    return new TypedRegion(0, next.offset, IDocument.DEFAULT_CONTENT_TYPE);
+
+                TypedPosition previous= cast(TypedPosition) category[index - 1];
+                if (previous.includes(offset))
+                    return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType());
+
+                int endOffset= previous.getOffset() + previous.getLength();
+                return new TypedRegion(endOffset, next.getOffset() - endOffset, IDocument.DEFAULT_CONTENT_TYPE);
+            }
+
+            TypedPosition previous= cast(TypedPosition) category[category.length - 1];
+            if (previous.includes(offset))
+                return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType());
+
+            int endOffset= previous.getOffset() + previous.getLength();
+            return new TypedRegion(endOffset, fDocument.getLength() - endOffset, IDocument.DEFAULT_CONTENT_TYPE);
+
+        } catch (BadPositionCategoryException x) {
+        } catch (BadLocationException x) {
+        }
+
+        return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE);
+    }
+
+    /*
+     * @see IDocumentPartitioner#computePartitioning(int, int)
+     */
+    public ITypedRegion[] computePartitioning(int offset, int length) {
+        return computePartitioning(offset, length, false);
+    }
+
+    /*
+     * @see IDocumentPartitioner#getLegalContentTypes()
+     */
+    public String[] getLegalContentTypes() {
+        return TextUtilities.copy(fLegalContentTypes);
+    }
+
+    /**
+     * Returns whether the given type is one of the legal content types.
+     *
+     * @param contentType the content type to check
+     * @return <code>true</code> if the content type is a legal content type
+     */
+    protected bool isSupportedContentType(String contentType) {
+        if (contentType !is null) {
+            for (int i= 0; i < fLegalContentTypes.length; i++) {
+                if (fLegalContentTypes[i].equals(contentType))
+                    return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns a content type encoded in the given token. If the token's
+     * data is not <code>null</code> and a string it is assumed that
+     * it is the encoded content type.
+     *
+     * @param token the token whose content type is to be determined
+     * @return the token's content type
+     */
+    protected String getTokenContentType(IToken token) {
+        Object data= token.getData();
+        if ( auto str = cast(ArrayWrapperString)data )
+            return str.array;
+        return null;
+    }
+
+    /* zero-length partition support */
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension2#getContentType(int)
+     * @since 3.0
+     */
+    public String getContentType(int offset, bool preferOpenPartitions) {
+        return getPartition(offset, preferOpenPartitions).getType();
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension2#getPartition(int)
+     * @since 3.0
+     */
+    public ITypedRegion getPartition(int offset, bool preferOpenPartitions) {
+        ITypedRegion region= getPartition(offset);
+        if (preferOpenPartitions) {
+            if (region.getOffset() is offset && !region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) {
+                if (offset > 0) {
+                    region= getPartition(offset - 1);
+                    if (region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE))
+                        return region;
+                }
+                return new TypedRegion(offset, 0, IDocument.DEFAULT_CONTENT_TYPE);
+            }
+        }
+        return region;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension2#computePartitioning(int, int, bool)
+     * @since 3.0
+     */
+    public ITypedRegion[] computePartitioning(int offset, int length, bool includeZeroLengthPartitions) {
+        checkInitialization();
+        List list= new ArrayList();
+
+        try {
+
+            int endOffset= offset + length;
+
+            Position[] category= fDocument.getPositions(fPositionCategory);
+
+            TypedPosition previous= null, current= null;
+            int start, end, gapOffset;
+            Position gap= new Position(0);
+
+            int startIndex= getFirstIndexEndingAfterOffset(category, offset);
+            int endIndex= getFirstIndexStartingAfterOffset(category, endOffset);
+            for (int i= startIndex; i < endIndex; i++) {
+
+                current= cast(TypedPosition) category[i];
+
+                gapOffset= (previous !is null) ? previous.getOffset() + previous.getLength() : 0;
+                gap.setOffset(gapOffset);
+                gap.setLength(current.getOffset() - gapOffset);
+                if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) ||
+                        (gap.getLength() > 0 && gap.overlapsWith(offset, length))) {
+                    start= Math.max(offset, gapOffset);
+                    end= Math.min(endOffset, gap.getOffset() + gap.getLength());
+                    list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE));
+                }
+
+                if (current.overlapsWith(offset, length)) {
+                    start= Math.max(offset, current.getOffset());
+                    end= Math.min(endOffset, current.getOffset() + current.getLength());
+                    list.add(new TypedRegion(start, end - start, current.getType()));
+                }
+
+                previous= current;
+            }
+
+            if (previous !is null) {
+                gapOffset= previous.getOffset() + previous.getLength();
+                gap.setOffset(gapOffset);
+                gap.setLength(fDocument.getLength() - gapOffset);
+                if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) ||
+                        (gap.getLength() > 0 && gap.overlapsWith(offset, length))) {
+                    start= Math.max(offset, gapOffset);
+                    end= Math.min(endOffset, fDocument.getLength());
+                    list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE));
+                }
+            }
+
+            if (list.isEmpty())
+                list.add(new TypedRegion(offset, length, IDocument.DEFAULT_CONTENT_TYPE));
+
+        } catch (BadPositionCategoryException x) {
+        }
+
+        return arraycast!(ITypedRegion)(list.toArray());
+    }
+
+    /**
+     * Returns <code>true</code> if the given ranges overlap with or touch each other.
+     *
+     * @param gap the first range
+     * @param offset the offset of the second range
+     * @param length the length of the second range
+     * @return <code>true</code> if the given ranges overlap with or touch each other
+     * @since 3.0
+     */
+    private bool overlapsOrTouches(Position gap, int offset, int length) {
+        return gap.getOffset() <= offset + length && offset <= gap.getOffset() + gap.getLength();
+    }
+
+    /**
+     * Returns the index of the first position which ends after the given offset.
+     *
+     * @param positions the positions in linear order
+     * @param offset the offset
+     * @return the index of the first position which ends after the offset
+     *
+     * @since 3.0
+     */
+    private int getFirstIndexEndingAfterOffset(Position[] positions, int offset) {
+        int i= -1, j= positions.length;
+        while (j - i > 1) {
+            int k= (i + j) >> 1;
+            Position p= positions[k];
+            if (p.getOffset() + p.getLength() > offset)
+                j= k;
+            else
+                i= k;
+        }
+        return j;
+    }
+
+    /**
+     * Returns the index of the first position which starts at or after the given offset.
+     *
+     * @param positions the positions in linear order
+     * @param offset the offset
+     * @return the index of the first position which starts after the offset
+     *
+     * @since 3.0
+     */
+    private int getFirstIndexStartingAfterOffset(Position[] positions, int offset) {
+        int i= -1, j= positions.length;
+        while (j - i > 1) {
+            int k= (i + j) >> 1;
+            Position p= positions[k];
+            if (p.getOffset() >= offset)
+                j= k;
+            else
+                i= k;
+        }
+        return j;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension3#startRewriteSession(dwtx.jface.text.DocumentRewriteSession)
+     * @since 3.1
+     */
+    public void startRewriteSession(DocumentRewriteSession session)  {
+        if (fActiveRewriteSession !is null)
+            throw new IllegalStateException();
+        fActiveRewriteSession= session;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension3#stopRewriteSession(dwtx.jface.text.DocumentRewriteSession)
+     * @since 3.1
+     */
+    public void stopRewriteSession(DocumentRewriteSession session) {
+        if (fActiveRewriteSession is session)
+            flushRewriteSession();
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension3#getActiveRewriteSession()
+     * @since 3.1
+     */
+    public DocumentRewriteSession getActiveRewriteSession() {
+        return fActiveRewriteSession;
+    }
+
+    /**
+     * Flushes the active rewrite session.
+     *
+     * @since 3.1
+     */
+    protected final void flushRewriteSession() {
+        fActiveRewriteSession= null;
+
+        // remove all position belonging to the partitioner position category
+        try {
+            fDocument.removePositionCategory(fPositionCategory);
+        } catch (BadPositionCategoryException x) {
+        }
+        fDocument.addPositionCategory(fPositionCategory);
+
+        fIsInitialized= false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/EndOfLineRule.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Christopher Lenz (cmlenz@gmx.de) - support for line continuation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.rules.EndOfLineRule;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A specific configuration of a single line rule
+ * whereby the pattern begins with a specific sequence but
+ * is only ended by a line delimiter.
+ */
+public class EndOfLineRule : SingleLineRule {
+
+    /**
+     * Creates a rule for the given starting sequence
+     * which, if detected, will return the specified token.
+     *
+     * @param startSequence the pattern's start sequence
+     * @param token the token to be returned on success
+     */
+    public this(String startSequence, IToken token) {
+        this(startSequence, token, cast(wchar) 0);
+    }
+
+    /**
+     * Creates a rule for the given starting sequence
+     * which, if detected, will return the specified token.
+     * Any character which follows the given escape character
+     * will be ignored.
+     *
+     * @param startSequence the pattern's start sequence
+     * @param token the token to be returned on success
+     * @param escapeCharacter the escape character
+     */
+    public this(String startSequence, IToken token, char escapeCharacter) {
+        super(startSequence, null, token, escapeCharacter, true);
+    }
+
+    /**
+     * Creates a rule for the given starting sequence
+     * which, if detected, will return the specified token.
+     * Any character which follows the given escape character
+     * will be ignored. In addition, an escape character
+     * immediately before an end of line can be set to continue
+     * the line.
+     *
+     * @param startSequence the pattern's start sequence
+     * @param token the token to be returned on success
+     * @param escapeCharacter the escape character
+     * @param escapeContinuesLine indicates whether the specified escape
+     *        character is used for line continuation, so that an end of
+     *        line immediately after the escape character does not
+     *        terminate the line, even if <code>breakOnEOL</code> is true
+     * @since 3.0
+     */
+    public this(String startSequence, IToken token, char escapeCharacter, bool escapeContinuesLine) {
+        super(startSequence, null, token, escapeCharacter, true, escapeContinuesLine);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/FastPartitioner.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,858 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.rules.FastPartitioner;
+
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.text.convert.Format;
+
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.Platform;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DefaultPositionUpdater;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.DocumentRewriteSession;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentPartitioner;
+import dwtx.jface.text.IDocumentPartitionerExtension;
+import dwtx.jface.text.IDocumentPartitionerExtension2;
+import dwtx.jface.text.IDocumentPartitionerExtension3;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITypedRegion;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextUtilities;
+import dwtx.jface.text.TypedPosition;
+import dwtx.jface.text.TypedRegion;
+
+
+
+/**
+ * A standard implementation of a document partitioner. It uses an
+ * {@link IPartitionTokenScanner} to scan the document and to determine the
+ * document's partitioning. The tokens returned by the scanner must return the
+ * partition type as their data. The partitioner remembers the document's
+ * partitions in the document itself rather than maintaining its own data
+ * structure.
+ * <p>
+ * To reduce array creations in {@link IDocument#getPositions(String)}, the
+ * positions get cached. The cache is cleared after updating the positions in
+ * {@link #documentChanged2(DocumentEvent)}. Subclasses need to call
+ * {@link #clearPositionCache()} after modifying the partitioner's positions.
+ * The cached positions may be accessed through {@link #getPositions()}.
+ * </p>
+ *
+ * @see IPartitionTokenScanner
+ * @since 3.1
+ */
+public class FastPartitioner : IDocumentPartitioner, IDocumentPartitionerExtension, IDocumentPartitionerExtension2, IDocumentPartitionerExtension3 {
+
+    /**
+     * The position category this partitioner uses to store the document's partitioning information.
+     */
+    private static const String CONTENT_TYPES_CATEGORY= "__content_types_category"; //$NON-NLS-1$
+    /** The partitioner's scanner */
+    protected final IPartitionTokenScanner fScanner;
+    /** The legal content types of this partitioner */
+    protected final String[] fLegalContentTypes;
+    /** The partitioner's document */
+    protected IDocument fDocument;
+    /** The document length before a document change occurred */
+    protected int fPreviousDocumentLength;
+    /** The position updater used to for the default updating of partitions */
+    protected final DefaultPositionUpdater fPositionUpdater;
+    /** The offset at which the first changed partition starts */
+    protected int fStartOffset;
+    /** The offset at which the last changed partition ends */
+    protected int fEndOffset;
+    /**The offset at which a partition has been deleted */
+    protected int fDeleteOffset;
+    /**
+     * The position category this partitioner uses to store the document's partitioning information.
+     */
+    private const String fPositionCategory;
+    /**
+     * The active document rewrite session.
+     */
+    private DocumentRewriteSession fActiveRewriteSession;
+    /**
+     * Flag indicating whether this partitioner has been initialized.
+     */
+    private bool fIsInitialized= false;
+    /**
+     * The cached positions from our document, so we don't create a new array every time
+     * someone requests partition information.
+     */
+    private Position[] fCachedPositions= null;
+    /** Debug option for cache consistency checking. */
+    private static bool CHECK_CACHE_CONSISTENCY_;
+    private static bool CHECK_CACHE_CONSISTENCY_init;
+    private static bool CHECK_CACHE_CONSISTENCY(){
+        if( !CHECK_CACHE_CONSISTENCY_init ){
+            synchronized(FastPartitioner.classinfo ){
+                if( !CHECK_CACHE_CONSISTENCY_init ){
+                    CHECK_CACHE_CONSISTENCY_init = true;
+                    CHECK_CACHE_CONSISTENCY_ = "true".equalsIgnoreCase(Platform.getDebugOption("dwtx.jface.text/debug/FastPartitioner/PositionCache"));  //$NON-NLS-1$//$NON-NLS-2$;
+                }
+            }
+        }
+        return CHECK_CACHE_CONSISTENCY_;
+    }
+
+    /**
+     * Creates a new partitioner that uses the given scanner and may return
+     * partitions of the given legal content types.
+     *
+     * @param scanner the scanner this partitioner is supposed to use
+     * @param legalContentTypes the legal content types of this partitioner
+     */
+    public this(IPartitionTokenScanner scanner, String[] legalContentTypes) {
+        fScanner= scanner;
+        fLegalContentTypes= TextUtilities.copy(legalContentTypes);
+        fPositionCategory= CONTENT_TYPES_CATEGORY ~ Integer.toString(toHash());
+        fPositionUpdater= new DefaultPositionUpdater(fPositionCategory);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension2#getManagingPositionCategories()
+     */
+    public String[] getManagingPositionCategories() {
+        return [ fPositionCategory ];
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitioner#connect(dwtx.jface.text.IDocument)
+     */
+    public final void connect(IDocument document) {
+        connect(document, false);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * May be extended by subclasses.
+     * </p>
+     */
+    public void connect(IDocument document, bool delayInitialization) {
+        Assert.isNotNull(cast(Object)document);
+        Assert.isTrue(!document.containsPositionCategory(fPositionCategory));
+
+        fDocument= document;
+        fDocument.addPositionCategory(fPositionCategory);
+
+        fIsInitialized= false;
+        if (!delayInitialization)
+            checkInitialization();
+    }
+
+    /**
+     * Calls {@link #initialize()} if the receiver is not yet initialized.
+     */
+    protected final void checkInitialization() {
+        if (!fIsInitialized)
+            initialize();
+    }
+
+    /**
+     * Performs the initial partitioning of the partitioner's document.
+     * <p>
+     * May be extended by subclasses.
+     * </p>
+     */
+    protected void initialize() {
+        fIsInitialized= true;
+        clearPositionCache();
+        fScanner.setRange(fDocument, 0, fDocument.getLength());
+
+        try {
+            IToken token= fScanner.nextToken();
+            while (!token.isEOF()) {
+
+                String contentType= getTokenContentType(token);
+
+                if (isSupportedContentType(contentType)) {
+                    TypedPosition p= new TypedPosition(fScanner.getTokenOffset(), fScanner.getTokenLength(), contentType);
+                    fDocument.addPosition(fPositionCategory, p);
+                }
+
+                token= fScanner.nextToken();
+            }
+        } catch (BadLocationException x) {
+            // cannot happen as offsets come from scanner
+        } catch (BadPositionCategoryException x) {
+            // cannot happen if document has been connected before
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * May be extended by subclasses.
+     * </p>
+     */
+    public void disconnect() {
+
+        Assert.isTrue(fDocument.containsPositionCategory(fPositionCategory));
+
+        try {
+            fDocument.removePositionCategory(fPositionCategory);
+        } catch (BadPositionCategoryException x) {
+            // can not happen because of Assert
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * May be extended by subclasses.
+     * </p>
+     */
+    public void documentAboutToBeChanged(DocumentEvent e) {
+        if (fIsInitialized) {
+
+            Assert.isTrue(e.getDocument() is fDocument);
+
+            fPreviousDocumentLength= e.getDocument().getLength();
+            fStartOffset= -1;
+            fEndOffset= -1;
+            fDeleteOffset= -1;
+        }
+    }
+
+    /*
+     * @see IDocumentPartitioner#documentChanged(DocumentEvent)
+     */
+    public final bool documentChanged(DocumentEvent e) {
+        if (fIsInitialized) {
+            IRegion region= documentChanged2(e);
+            return (region !is null);
+        }
+        return false;
+    }
+
+    /**
+     * Helper method for tracking the minimal region containing all partition changes.
+     * If <code>offset</code> is smaller than the remembered offset, <code>offset</code>
+     * will from now on be remembered. If <code>offset  + length</code> is greater than
+     * the remembered end offset, it will be remembered from now on.
+     *
+     * @param offset the offset
+     * @param length the length
+     */
+    private void rememberRegion(int offset, int length) {
+        // remember start offset
+        if (fStartOffset is -1)
+            fStartOffset= offset;
+        else if (offset < fStartOffset)
+            fStartOffset= offset;
+
+        // remember end offset
+        int endOffset= offset + length;
+        if (fEndOffset is -1)
+            fEndOffset= endOffset;
+        else if (endOffset > fEndOffset)
+            fEndOffset= endOffset;
+    }
+
+    /**
+     * Remembers the given offset as the deletion offset.
+     *
+     * @param offset the offset
+     */
+    private void rememberDeletedOffset(int offset) {
+        fDeleteOffset= offset;
+    }
+
+    /**
+     * Creates the minimal region containing all partition changes using the
+     * remembered offset, end offset, and deletion offset.
+     *
+     * @return the minimal region containing all the partition changes
+     */
+    private IRegion createRegion() {
+        if (fDeleteOffset is -1) {
+            if (fStartOffset is -1 || fEndOffset is -1)
+                return null;
+            return new Region(fStartOffset, fEndOffset - fStartOffset);
+        } else if (fStartOffset is -1 || fEndOffset is -1) {
+            return new Region(fDeleteOffset, 0);
+        } else {
+            int offset= Math.min(fDeleteOffset, fStartOffset);
+            int endOffset= Math.max(fDeleteOffset, fEndOffset);
+            return new Region(offset, endOffset - offset);
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * May be extended by subclasses.
+     * </p>
+     */
+    public IRegion documentChanged2(DocumentEvent e) {
+
+        if (!fIsInitialized)
+            return null;
+
+        try {
+            Assert.isTrue(e.getDocument() is fDocument);
+
+            Position[] category= getPositions();
+            IRegion line= fDocument.getLineInformationOfOffset(e.getOffset());
+            int reparseStart= line.getOffset();
+            int partitionStart= -1;
+            String contentType= null;
+            int newLength= e.getText() is null ? 0 : e.getText().length();
+
+            int first= fDocument.computeIndexInCategory(fPositionCategory, reparseStart);
+            if (first > 0)  {
+                TypedPosition partition= cast(TypedPosition) category[first - 1];
+                if (partition.includes(reparseStart)) {
+                    partitionStart= partition.getOffset();
+                    contentType= partition.getType();
+                    if (e.getOffset() is partition.getOffset() + partition.getLength())
+                        reparseStart= partitionStart;
+                    -- first;
+                } else if (reparseStart is e.getOffset() && reparseStart is partition.getOffset() + partition.getLength()) {
+                    partitionStart= partition.getOffset();
+                    contentType= partition.getType();
+                    reparseStart= partitionStart;
+                    -- first;
+                } else {
+                    partitionStart= partition.getOffset() + partition.getLength();
+                    contentType= IDocument.DEFAULT_CONTENT_TYPE;
+                }
+            }
+
+            fPositionUpdater.update(e);
+            for (int i= first; i < category.length; i++) {
+                Position p= category[i];
+                if (p.isDeleted) {
+                    rememberDeletedOffset(e.getOffset());
+                    break;
+                }
+            }
+            clearPositionCache();
+            category= getPositions();
+
+            fScanner.setPartialRange(fDocument, reparseStart, fDocument.getLength() - reparseStart, contentType, partitionStart);
+
+            int behindLastScannedPosition= reparseStart;
+            IToken token= fScanner.nextToken();
+
+            while (!token.isEOF()) {
+
+                contentType= getTokenContentType(token);
+
+                if (!isSupportedContentType(contentType)) {
+                    token= fScanner.nextToken();
+                    continue;
+                }
+
+                int start= fScanner.getTokenOffset();
+                int length= fScanner.getTokenLength();
+
+                behindLastScannedPosition= start + length;
+                int lastScannedPosition= behindLastScannedPosition - 1;
+
+                // remove all affected positions
+                while (first < category.length) {
+                    TypedPosition p= cast(TypedPosition) category[first];
+                    if (lastScannedPosition >= p.offset + p.length ||
+                            (p.overlapsWith(start, length) &&
+                                (!fDocument.containsPosition(fPositionCategory, start, length) ||
+                                 !contentType.equals(p.getType())))) {
+
+                        rememberRegion(p.offset, p.length);
+                        fDocument.removePosition(fPositionCategory, p);
+                        ++ first;
+
+                    } else
+                        break;
+                }
+
+                // if position already exists and we have scanned at least the
+                // area covered by the event, we are done
+                if (fDocument.containsPosition(fPositionCategory, start, length)) {
+                    if (lastScannedPosition >= e.getOffset() + newLength)
+                        return createRegion();
+                    ++ first;
+                } else {
+                    // insert the new type position
+                    try {
+                        fDocument.addPosition(fPositionCategory, new TypedPosition(start, length, contentType));
+                        rememberRegion(start, length);
+                    } catch (BadPositionCategoryException x) {
+                    } catch (BadLocationException x) {
+                    }
+                }
+
+                token= fScanner.nextToken();
+            }
+
+            first= fDocument.computeIndexInCategory(fPositionCategory, behindLastScannedPosition);
+
+            clearPositionCache();
+            category= getPositions();
+            TypedPosition p;
+            while (first < category.length) {
+                p= cast(TypedPosition) category[first++];
+                fDocument.removePosition(fPositionCategory, p);
+                rememberRegion(p.offset, p.length);
+            }
+
+        } catch (BadPositionCategoryException x) {
+            // should never happen on connected documents
+        } catch (BadLocationException x) {
+        } finally {
+            clearPositionCache();
+        }
+
+        return createRegion();
+    }
+
+    /**
+     * Returns the position in the partitoner's position category which is
+     * close to the given offset. This is, the position has either an offset which
+     * is the same as the given offset or an offset which is smaller than the given
+     * offset. This method profits from the knowledge that a partitioning is
+     * a ordered set of disjoint position.
+     * <p>
+     * May be extended or replaced by subclasses.
+     * </p>
+     * @param offset the offset for which to search the closest position
+     * @return the closest position in the partitioner's category
+     */
+    protected TypedPosition findClosestPosition(int offset) {
+
+        try {
+
+            int index= fDocument.computeIndexInCategory(fPositionCategory, offset);
+            Position[] category= getPositions();
+
+            if (category.length is 0)
+                return null;
+
+            if (index < category.length) {
+                if (offset is category[index].offset)
+                    return cast(TypedPosition) category[index];
+            }
+
+            if (index > 0)
+                index--;
+
+            return cast(TypedPosition) category[index];
+
+        } catch (BadPositionCategoryException x) {
+        } catch (BadLocationException x) {
+        }
+
+        return null;
+    }
+
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * May be replaced or extended by subclasses.
+     * </p>
+     */
+    public String getContentType(int offset) {
+        checkInitialization();
+
+        TypedPosition p= findClosestPosition(offset);
+        if (p !is null && p.includes(offset))
+            return p.getType();
+
+        return IDocument.DEFAULT_CONTENT_TYPE;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * May be replaced or extended by subclasses.
+     * </p>
+     */
+    public ITypedRegion getPartition(int offset) {
+        checkInitialization();
+
+        try {
+
+            Position[] category = getPositions();
+
+            if (category is null || category.length is 0)
+                return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE);
+
+            int index= fDocument.computeIndexInCategory(fPositionCategory, offset);
+
+            if (index < category.length) {
+
+                TypedPosition next= cast(TypedPosition) category[index];
+
+                if (offset is next.offset)
+                    return new TypedRegion(next.getOffset(), next.getLength(), next.getType());
+
+                if (index is 0)
+                    return new TypedRegion(0, next.offset, IDocument.DEFAULT_CONTENT_TYPE);
+
+                TypedPosition previous= cast(TypedPosition) category[index - 1];
+                if (previous.includes(offset))
+                    return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType());
+
+                int endOffset= previous.getOffset() + previous.getLength();
+                return new TypedRegion(endOffset, next.getOffset() - endOffset, IDocument.DEFAULT_CONTENT_TYPE);
+            }
+
+            TypedPosition previous= cast(TypedPosition) category[category.length - 1];
+            if (previous.includes(offset))
+                return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType());
+
+            int endOffset= previous.getOffset() + previous.getLength();
+            return new TypedRegion(endOffset, fDocument.getLength() - endOffset, IDocument.DEFAULT_CONTENT_TYPE);
+
+        } catch (BadPositionCategoryException x) {
+        } catch (BadLocationException x) {
+        }
+
+        return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE);
+    }
+
+    /*
+     * @see IDocumentPartitioner#computePartitioning(int, int)
+     */
+    public final ITypedRegion[] computePartitioning(int offset, int length) {
+        return computePartitioning(offset, length, false);
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * May be replaced or extended by subclasses.
+     * </p>
+     */
+    public String[] getLegalContentTypes() {
+        return TextUtilities.copy(fLegalContentTypes);
+    }
+
+    /**
+     * Returns whether the given type is one of the legal content types.
+     * <p>
+     * May be extended by subclasses.
+     * </p>
+     *
+     * @param contentType the content type to check
+     * @return <code>true</code> if the content type is a legal content type
+     */
+    protected bool isSupportedContentType(String contentType) {
+        if (contentType !is null) {
+            for (int i= 0; i < fLegalContentTypes.length; i++) {
+                if (fLegalContentTypes[i].equals(contentType))
+                    return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns a content type encoded in the given token. If the token's
+     * data is not <code>null</code> and a string it is assumed that
+     * it is the encoded content type.
+     * <p>
+     * May be replaced or extended by subclasses.
+     * </p>
+     *
+     * @param token the token whose content type is to be determined
+     * @return the token's content type
+     */
+    protected String getTokenContentType(IToken token) {
+        Object data= token.getData();
+        if ( auto str = cast(ArrayWrapperString)data )
+            return str.array;
+        return null;
+    }
+
+    /* zero-length partition support */
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * May be replaced or extended by subclasses.
+     * </p>
+     */
+    public String getContentType(int offset, bool preferOpenPartitions) {
+        return getPartition(offset, preferOpenPartitions).getType();
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * May be replaced or extended by subclasses.
+     * </p>
+     */
+    public ITypedRegion getPartition(int offset, bool preferOpenPartitions) {
+        ITypedRegion region= getPartition(offset);
+        if (preferOpenPartitions) {
+            if (region.getOffset() is offset && !region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) {
+                if (offset > 0) {
+                    region= getPartition(offset - 1);
+                    if (region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE))
+                        return region;
+                }
+                return new TypedRegion(offset, 0, IDocument.DEFAULT_CONTENT_TYPE);
+            }
+        }
+        return region;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * May be replaced or extended by subclasses.
+     * </p>
+     */
+    public ITypedRegion[] computePartitioning(int offset, int length, bool includeZeroLengthPartitions) {
+        checkInitialization();
+        List list= new ArrayList();
+
+        try {
+
+            int endOffset= offset + length;
+
+            Position[] category= getPositions();
+
+            TypedPosition previous= null, current= null;
+            int start, end, gapOffset;
+            Position gap= new Position(0);
+
+            int startIndex= getFirstIndexEndingAfterOffset(category, offset);
+            int endIndex= getFirstIndexStartingAfterOffset(category, endOffset);
+            for (int i= startIndex; i < endIndex; i++) {
+
+                current= cast(TypedPosition) category[i];
+
+                gapOffset= (previous !is null) ? previous.getOffset() + previous.getLength() : 0;
+                gap.setOffset(gapOffset);
+                gap.setLength(current.getOffset() - gapOffset);
+                if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) ||
+                        (gap.getLength() > 0 && gap.overlapsWith(offset, length))) {
+                    start= Math.max(offset, gapOffset);
+                    end= Math.min(endOffset, gap.getOffset() + gap.getLength());
+                    list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE));
+                }
+
+                if (current.overlapsWith(offset, length)) {
+                    start= Math.max(offset, current.getOffset());
+                    end= Math.min(endOffset, current.getOffset() + current.getLength());
+                    list.add(new TypedRegion(start, end - start, current.getType()));
+                }
+
+                previous= current;
+            }
+
+            if (previous !is null) {
+                gapOffset= previous.getOffset() + previous.getLength();
+                gap.setOffset(gapOffset);
+                gap.setLength(fDocument.getLength() - gapOffset);
+                if ((includeZeroLengthPartitions && overlapsOrTouches(gap, offset, length)) ||
+                        (gap.getLength() > 0 && gap.overlapsWith(offset, length))) {
+                    start= Math.max(offset, gapOffset);
+                    end= Math.min(endOffset, fDocument.getLength());
+                    list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE));
+                }
+            }
+
+            if (list.isEmpty())
+                list.add(new TypedRegion(offset, length, IDocument.DEFAULT_CONTENT_TYPE));
+
+        } catch (BadPositionCategoryException ex) {
+            // Make sure we clear the cache
+            clearPositionCache();
+        } catch (RuntimeException ex) {
+            // Make sure we clear the cache
+            clearPositionCache();
+            throw ex;
+        }
+
+        return arraycast!(ITypedRegion)(list.toArray());
+    }
+
+    /**
+     * Returns <code>true</code> if the given ranges overlap with or touch each other.
+     *
+     * @param gap the first range
+     * @param offset the offset of the second range
+     * @param length the length of the second range
+     * @return <code>true</code> if the given ranges overlap with or touch each other
+     */
+    private bool overlapsOrTouches(Position gap, int offset, int length) {
+        return gap.getOffset() <= offset + length && offset <= gap.getOffset() + gap.getLength();
+    }
+
+    /**
+     * Returns the index of the first position which ends after the given offset.
+     *
+     * @param positions the positions in linear order
+     * @param offset the offset
+     * @return the index of the first position which ends after the offset
+     */
+    private int getFirstIndexEndingAfterOffset(Position[] positions, int offset) {
+        int i= -1, j= positions.length;
+        while (j - i > 1) {
+            int k= (i + j) >> 1;
+            Position p= positions[k];
+            if (p.getOffset() + p.getLength() > offset)
+                j= k;
+            else
+                i= k;
+        }
+        return j;
+    }
+
+    /**
+     * Returns the index of the first position which starts at or after the given offset.
+     *
+     * @param positions the positions in linear order
+     * @param offset the offset
+     * @return the index of the first position which starts after the offset
+     */
+    private int getFirstIndexStartingAfterOffset(Position[] positions, int offset) {
+        int i= -1, j= positions.length;
+        while (j - i > 1) {
+            int k= (i + j) >> 1;
+            Position p= positions[k];
+            if (p.getOffset() >= offset)
+                j= k;
+            else
+                i= k;
+        }
+        return j;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension3#startRewriteSession(dwtx.jface.text.DocumentRewriteSession)
+     */
+    public void startRewriteSession(DocumentRewriteSession session)  {
+        if (fActiveRewriteSession !is null)
+            throw new IllegalStateException();
+        fActiveRewriteSession= session;
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * May be extended by subclasses.
+     * </p>
+     */
+    public void stopRewriteSession(DocumentRewriteSession session) {
+        if (fActiveRewriteSession is session)
+            flushRewriteSession();
+    }
+
+    /**
+     * {@inheritDoc}
+     * <p>
+     * May be extended by subclasses.
+     * </p>
+     */
+    public DocumentRewriteSession getActiveRewriteSession() {
+        return fActiveRewriteSession;
+    }
+
+    /**
+     * Flushes the active rewrite session.
+     */
+    protected final void flushRewriteSession() {
+        fActiveRewriteSession= null;
+
+        // remove all position belonging to the partitioner position category
+        try {
+            fDocument.removePositionCategory(fPositionCategory);
+        } catch (BadPositionCategoryException x) {
+        }
+        fDocument.addPositionCategory(fPositionCategory);
+
+        fIsInitialized= false;
+    }
+
+    /**
+     * Clears the position cache. Needs to be called whenever the positions have
+     * been updated.
+     */
+    protected final void clearPositionCache() {
+        if (fCachedPositions !is null) {
+            fCachedPositions= null;
+        }
+    }
+
+    /**
+     * Returns the partitioners positions.
+     *
+     * @return the partitioners positions
+     * @throws BadPositionCategoryException if getting the positions from the
+     *         document fails
+     */
+    protected final Position[] getPositions()  {
+        if (fCachedPositions is null) {
+            fCachedPositions= fDocument.getPositions(fPositionCategory);
+        } else if (CHECK_CACHE_CONSISTENCY) {
+            Position[] positions= fDocument.getPositions(fPositionCategory);
+            int len= Math.min(positions.length, fCachedPositions.length);
+            for (int i= 0; i < len; i++) {
+                if (!positions[i].opEquals(fCachedPositions[i]))
+                    System.err.println(Format("FastPartitioner.getPositions(): cached position is not up to date: from document: {} in cache: {}", toString(positions[i]), toString(fCachedPositions[i]))); //$NON-NLS-1$ //$NON-NLS-2$
+            }
+            for (int i= len; i < positions.length; i++)
+                System.err.println(Format("FastPartitioner.getPositions(): new position in document: {}", toString(positions[i]))); //$NON-NLS-1$
+            for (int i= len; i < fCachedPositions.length; i++)
+                System.err.println(Format("FastPartitioner.getPositions(): stale position in cache: {}", toString(fCachedPositions[i]))); //$NON-NLS-1$
+        }
+        return fCachedPositions;
+    }
+
+    /**
+     * Pretty print a <code>Position</code>.
+     *
+     * @param position the position to format
+     * @return a formatted string
+     */
+    private override String toString(Position position) {
+        return Format("P[{}+{}]", position.getOffset(), position.getLength() ); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/ICharacterScanner.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.rules.ICharacterScanner;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Defines the interface of a character scanner used by rules.
+ * Rules may request the next character or ask the character
+ * scanner to unread the last read character.
+ */
+public interface ICharacterScanner {
+
+    /**
+     * The value returned when this scanner has read EOF.
+     */
+    public static const int EOF= -1;
+
+    /**
+     * Provides rules access to the legal line delimiters. The returned
+     * object may not be modified by clients.
+     *
+     * @return the legal line delimiters
+     */
+    char[][] getLegalLineDelimiters();
+
+    /**
+     * Returns the column of the character scanner.
+     *
+     * @return the column of the character scanner
+     */
+    int getColumn();
+
+    /**
+     * Returns the next character or EOF if end of file has been reached
+     *
+     * @return the next character or EOF
+     */
+    int read();
+
+    /**
+     * Rewinds the scanner before the last read character.
+     */
+    void unread();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/IPartitionTokenScanner.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.rules.IPartitionTokenScanner;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.jface.text.IDocument;
+
+
+/**
+ * A partition token scanner returns tokens that represent partitions. For that reason,
+ * a partition token scanner is vulnerable in respect to the document offset it starts
+ * scanning. In a simple case, a partition token scanner must always start at a partition
+ * boundary. A partition token scanner can also start in the middle of a partition,
+ * if it knows the type of the partition.
+ *
+ * @since 2.0
+ */
+public interface IPartitionTokenScanner  : ITokenScanner {
+
+    /**
+     * Configures the scanner by providing access to the document range that should be scanned.
+     * The range may no only contain complete partitions but starts at the beginning of a line in the
+     * middle of a partition of the given content type. This requires that a partition delimiter can not
+     * contain a line delimiter.
+     *
+     * @param document the document to scan
+     * @param offset the offset of the document range to scan
+     * @param length the length of the document range to scan
+     * @param contentType the content type at the given offset
+     * @param partitionOffset the offset at which the partition of the given offset starts
+     */
+    void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/IPredicateRule.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.rules.IPredicateRule;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Defines the interface for a rule used in the scanning of text for the purpose of
+ * document partitioning or text styling. A predicate rule can only return one single
+ * token after having successfully detected content. This token is called success token.
+ * Also, it also returns a token indicating that this rule has not been successful.
+ *
+ * @see ICharacterScanner
+ * @since 2.0
+ */
+public interface IPredicateRule : IRule {
+
+    /**
+     * Returns the success token of this predicate rule.
+     *
+     * @return the success token of this rule
+     */
+    IToken getSuccessToken();
+
+    /**
+     * Evaluates the rule by examining the characters available from
+     * the provided character scanner. The token returned by this rule
+     * returns <code>true</code> when calling <code>isUndefined</code>,
+     * if the text that the rule investigated does not match the rule's requirements. Otherwise,
+     * this method returns this rule's success token. If this rules relies on a text pattern
+     * comprising a opening and a closing character sequence this method can also be called
+     * when the scanner is positioned already between the opening and the closing sequence.
+     * In this case, <code>resume</code> must be set to <code>true</code>.
+     *
+     * @param scanner the character scanner to be used by this rule
+     * @param resume indicates that the rule starts working between the opening and the closing character sequence
+     * @return the token computed by the rule
+     */
+    IToken evaluate(ICharacterScanner scanner, bool resume);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/IRule.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.rules.IRule;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Defines the interface for a rule used in the
+ * scanning of text for the purpose of document
+ * partitioning or text styling.
+ *
+ * @see ICharacterScanner
+ */
+public interface IRule {
+
+    /**
+     * Evaluates the rule by examining the characters available from
+     * the provided character scanner. The token returned by this rule
+     * returns <code>true</code> when calling <code>isUndefined</code>,
+     * if the text that the rule investigated does not match the rule's requirements
+     *
+     * @param scanner the character scanner to be used by this rule
+     * @return the token computed by the rule
+     */
+    IToken evaluate(ICharacterScanner scanner);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/IToken.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.rules.IToken;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A token to be returned by a rule.
+ */
+public interface IToken {
+
+    /**
+     * Return whether this token is undefined.
+     *
+     * @return <code>true</code>if this token is undefined
+     */
+    bool isUndefined();
+
+    /**
+     * Return whether this token represents a whitespace.
+     *
+     * @return <code>true</code>if this token represents a whitespace
+     */
+    bool isWhitespace();
+
+    /**
+     * Return whether this token represents End Of File.
+     *
+     * @return <code>true</code>if this token represents EOF
+     */
+    bool isEOF();
+
+    /**
+     * Return whether this token is neither undefined, nor whitespace, nor EOF.
+     *
+     * @return <code>true</code>if this token is not undefined, not a whitespace, and not EOF
+     */
+    bool isOther();
+
+    /**
+     * Return a data attached to this token. The semantics of this data kept undefined by this interface.
+     *
+     * @return the data attached to this token.
+     */
+    Object getData();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/ITokenScanner.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.rules.ITokenScanner;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.jface.text.IDocument;
+
+
+/**
+ * A token scanner scans a range of a document and reports about the token it finds.
+ * A scanner has state. When asked, the scanner returns the offset and the length of the
+ * last found token.
+ *
+ * @see dwtx.jface.text.rules.IToken
+ * @since 2.0
+ */
+public interface ITokenScanner {
+
+    /**
+     * Configures the scanner by providing access to the document range that should
+     * be scanned.
+     *
+     * @param document the document to scan
+     * @param offset the offset of the document range to scan
+     * @param length the length of the document range to scan
+     */
+    void setRange(IDocument document, int offset, int length);
+
+    /**
+     * Returns the next token in the document.
+     *
+     * @return the next token in the document
+     */
+    IToken nextToken();
+
+    /**
+     * Returns the offset of the last token read by this scanner.
+     *
+     * @return the offset of the last token read by this scanner
+     */
+    int getTokenOffset();
+
+    /**
+     * Returns the length of the last token read by this scanner.
+     *
+     * @return the length of the last token read by this scanner
+     */
+    int getTokenLength();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/IWhitespaceDetector.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.rules.IWhitespaceDetector;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Defines the interface by which <code>WhitespaceRule</code>
+ * determines whether a given character is to be considered
+ * whitespace in the current context.
+ */
+public interface IWhitespaceDetector {
+
+    /**
+     * Returns whether the specified character is whitespace.
+     *
+     * @param c the character to be checked
+     * @return <code>true</code> if the specified character is a whitespace char
+     */
+    bool isWhitespace(char c);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/IWordDetector.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.rules.IWordDetector;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Defines the interface by which <code>WordRule</code>
+ * determines whether a given character is valid as part
+ * of a word in the current context.
+ */
+public interface IWordDetector {
+
+    /**
+     * Returns whether the specified character is
+     * valid as the first character in a word.
+     *
+     * @param c the character to be checked
+     * @return <code>true</code> is a valid first character in a word, <code>false</code> otherwise
+     */
+    bool isWordStart(char c);
+
+    /**
+     * Returns whether the specified character is
+     * valid as a subsequent character in a word.
+     *
+     * @param c the character to be checked
+     * @return <code>true</code> if the character is a valid word part, <code>false</code> otherwise
+     */
+    bool isWordPart(char c);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/MultiLineRule.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.rules.MultiLineRule;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A rule for detecting patterns which begin with a given
+ * sequence and may end with a given sequence thereby spanning
+ * multiple lines.
+ */
+public class MultiLineRule : PatternRule {
+
+    /**
+     * Creates a rule for the given starting and ending sequence
+     * which, if detected, will return the specified token.
+     *
+     * @param startSequence the pattern's start sequence
+     * @param endSequence the pattern's end sequence
+     * @param token the token to be returned on success
+     */
+    public this(String startSequence, String endSequence, IToken token) {
+        this(startSequence, endSequence, token, cast(wchar) 0);
+    }
+
+    /**
+     * Creates a rule for the given starting and ending sequence
+     * which, if detected, will return the specific token.
+     * Any character which follows the given escape character will be ignored.
+     *
+     * @param startSequence the pattern's start sequence
+     * @param endSequence the pattern's end sequence
+     * @param token the token to be returned on success
+     * @param escapeCharacter the escape character
+     */
+    public this(String startSequence, String endSequence, IToken token, char escapeCharacter) {
+        this(startSequence, endSequence, token, escapeCharacter, false);
+    }
+
+    /**
+     * Creates a rule for the given starting and ending sequence
+     * which, if detected, will return the specific token. Any character that follows the
+     * given escape character will be ignored. <code>breakOnEOF</code> indicates whether
+     * EOF is equivalent to detecting the <code>endSequence</code>.
+     *
+     * @param startSequence the pattern's start sequence
+     * @param endSequence the pattern's end sequence
+     * @param token the token to be returned on success
+     * @param escapeCharacter the escape character
+     * @param breaksOnEOF indicates whether the end of the file terminates this rule successfully
+     * @since 2.1
+     */
+    public this(String startSequence, String endSequence, IToken token, char escapeCharacter, bool breaksOnEOF) {
+        super(startSequence, endSequence, token, escapeCharacter, false, breaksOnEOF);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/NumberRule.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.rules.NumberRule;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * An implementation of <code>IRule</code> detecting a numerical value.
+ */
+public class NumberRule : IRule {
+
+    /** Internal setting for the un-initialized column constraint */
+    protected static const int UNDEFINED= -1;
+    /** The token to be returned when this rule is successful */
+    protected IToken fToken;
+    /** The column constraint */
+    protected int fColumn= UNDEFINED;
+
+    /**
+     * Creates a rule which will return the specified
+     * token when a numerical sequence is detected.
+     *
+     * @param token the token to be returned
+     */
+    public this(IToken token) {
+        Assert.isNotNull(cast(Object)token);
+        fToken= token;
+    }
+
+    /**
+     * Sets a column constraint for this rule. If set, the rule's token
+     * will only be returned if the pattern is detected starting at the
+     * specified column. If the column is smaller then 0, the column
+     * constraint is considered removed.
+     *
+     * @param column the column in which the pattern starts
+     */
+    public void setColumnConstraint(int column) {
+        if (column < 0)
+            column= UNDEFINED;
+        fColumn= column;
+    }
+
+    /*
+     * @see IRule#evaluate(ICharacterScanner)
+     */
+    public IToken evaluate(ICharacterScanner scanner) {
+        int c= scanner.read();
+        if (Character.isDigit(cast(char)c)) {
+            if (fColumn is UNDEFINED || (fColumn is scanner.getColumn() - 1)) {
+                do {
+                    c= scanner.read();
+                } while (Character.isDigit(cast(char) c));
+                scanner.unread();
+                return fToken;
+            }
+        }
+
+        scanner.unread();
+        return Token.UNDEFINED;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/PatternRule.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,361 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Christopher Lenz (cmlenz@gmx.de) - support for line continuation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.rules.PatternRule;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.core.runtime.Assert;
+
+
+
+
+
+/**
+ * Standard implementation of <code>IPredicateRule</code>.
+ * Is is capable of detecting a pattern which begins with a given start
+ * sequence and ends with a given end sequence. If the end sequence is
+ * not specified, it can be either end of line, end or file, or both. Additionally,
+ * the pattern can be constrained to begin in a certain column. The rule can also
+ * be used to check whether the text to scan covers half of the pattern, i.e. contains
+ * the end sequence required by the rule.
+ */
+public class PatternRule : IPredicateRule {
+
+    /**
+     * Comparator that orders <code>char[]</code> in decreasing array lengths.
+     *
+     * @since 3.1
+     */
+    private static class DecreasingCharArrayLengthComparator : Comparator {
+        public int compare(Object o1, Object o2) {
+            return stringcast( o2).length - stringcast( o1).length;
+        }
+    }
+
+    /** Internal setting for the un-initialized column constraint */
+    protected static final int UNDEFINED= -1;
+
+    /** The token to be returned on success */
+    protected IToken fToken;
+    /** The pattern's start sequence */
+    protected char[] fStartSequence;
+    /** The pattern's end sequence */
+    protected char[] fEndSequence;
+    /** The pattern's column constrain */
+    protected int fColumn;
+    /** The pattern's escape character */
+    protected char fEscapeCharacter;
+    /**
+     * Indicates whether the escape character continues a line
+     * @since 3.0
+     */
+    protected bool fEscapeContinuesLine;
+    /** Indicates whether end of line terminates the pattern */
+    protected bool fBreaksOnEOL;
+    /** Indicates whether end of file terminates the pattern */
+    protected bool fBreaksOnEOF;
+
+    /**
+     * Line delimiter comparator which orders according to decreasing delimiter length.
+     * @since 3.1
+     */
+    private Comparator fLineDelimiterComparator;
+    /**
+     * Cached line delimiters.
+     * @since 3.1
+     */
+    private char[][] fLineDelimiters;
+    /**
+     * Cached sorted {@linkplain #fLineDelimiters}.
+     * @since 3.1
+     */
+    private char[][] fSortedLineDelimiters;
+
+    /**
+     * Creates a rule for the given starting and ending sequence.
+     * When these sequences are detected the rule will return the specified token.
+     * Alternatively, the sequence can also be ended by the end of the line.
+     * Any character which follows the given escapeCharacter will be ignored.
+     *
+     * @param startSequence the pattern's start sequence
+     * @param endSequence the pattern's end sequence, <code>null</code> is a legal value
+     * @param token the token which will be returned on success
+     * @param escapeCharacter any character following this one will be ignored
+     * @param breaksOnEOL indicates whether the end of the line also terminates the pattern
+     */
+    public this(String startSequence, String endSequence, IToken token, char escapeCharacter, bool breaksOnEOL) {
+        fColumn= UNDEFINED;
+        fLineDelimiterComparator= new DecreasingCharArrayLengthComparator();
+
+        Assert.isTrue(startSequence !is null && startSequence.length() > 0);
+        Assert.isTrue(endSequence !is null || breaksOnEOL);
+        Assert.isNotNull(cast(Object)token);
+
+        fStartSequence= startSequence.toCharArray();
+        fEndSequence= (endSequence is null ? new char[0] : endSequence.toCharArray());
+        fToken= token;
+        fEscapeCharacter= escapeCharacter;
+        fBreaksOnEOL= breaksOnEOL;
+    }
+
+    /**
+     * Creates a rule for the given starting and ending sequence.
+     * When these sequences are detected the rule will return the specified token.
+     * Alternatively, the sequence can also be ended by the end of the line or the end of the file.
+     * Any character which follows the given escapeCharacter will be ignored.
+     *
+     * @param startSequence the pattern's start sequence
+     * @param endSequence the pattern's end sequence, <code>null</code> is a legal value
+     * @param token the token which will be returned on success
+     * @param escapeCharacter any character following this one will be ignored
+     * @param breaksOnEOL indicates whether the end of the line also terminates the pattern
+     * @param breaksOnEOF indicates whether the end of the file also terminates the pattern
+     * @since 2.1
+     */
+    public this(String startSequence, String endSequence, IToken token, char escapeCharacter, bool breaksOnEOL, bool breaksOnEOF) {
+        this(startSequence, endSequence, token, escapeCharacter, breaksOnEOL);
+        fBreaksOnEOF= breaksOnEOF;
+    }
+
+    /**
+     * Creates a rule for the given starting and ending sequence.
+     * When these sequences are detected the rule will return the specified token.
+     * Alternatively, the sequence can also be ended by the end of the line or the end of the file.
+     * Any character which follows the given escapeCharacter will be ignored. An end of line
+     * immediately after the given <code>lineContinuationCharacter</code> will not cause the
+     * pattern to terminate even if <code>breakOnEOL</code> is set to true.
+     *
+     * @param startSequence the pattern's start sequence
+     * @param endSequence the pattern's end sequence, <code>null</code> is a legal value
+     * @param token the token which will be returned on success
+     * @param escapeCharacter any character following this one will be ignored
+     * @param breaksOnEOL indicates whether the end of the line also terminates the pattern
+     * @param breaksOnEOF indicates whether the end of the file also terminates the pattern
+     * @param escapeContinuesLine indicates whether the specified escape character is used for line
+     *        continuation, so that an end of line immediately after the escape character does not
+     *        terminate the pattern, even if <code>breakOnEOL</code> is set
+     * @since 3.0
+     */
+    public this(String startSequence, String endSequence, IToken token, char escapeCharacter, bool breaksOnEOL, bool breaksOnEOF, bool escapeContinuesLine) {
+        this(startSequence, endSequence, token, escapeCharacter, breaksOnEOL, breaksOnEOF);
+        fEscapeContinuesLine= escapeContinuesLine;
+    }
+
+    /**
+     * Sets a column constraint for this rule. If set, the rule's token
+     * will only be returned if the pattern is detected starting at the
+     * specified column. If the column is smaller then 0, the column
+     * constraint is considered removed.
+     *
+     * @param column the column in which the pattern starts
+     */
+    public void setColumnConstraint(int column) {
+        if (column < 0)
+            column= UNDEFINED;
+        fColumn= column;
+    }
+
+
+    /**
+     * Evaluates this rules without considering any column constraints.
+     *
+     * @param scanner the character scanner to be used
+     * @return the token resulting from this evaluation
+     */
+    protected IToken doEvaluate(ICharacterScanner scanner) {
+        return doEvaluate(scanner, false);
+    }
+
+    /**
+     * Evaluates this rules without considering any column constraints. Resumes
+     * detection, i.e. look sonly for the end sequence required by this rule if the
+     * <code>resume</code> flag is set.
+     *
+     * @param scanner the character scanner to be used
+     * @param resume <code>true</code> if detection should be resumed, <code>false</code> otherwise
+     * @return the token resulting from this evaluation
+     * @since 2.0
+     */
+    protected IToken doEvaluate(ICharacterScanner scanner, bool resume) {
+
+        if (resume) {
+
+            if (endSequenceDetected(scanner))
+                return fToken;
+
+        } else {
+
+            int c= scanner.read();
+            if (c is fStartSequence[0]) {
+                if (sequenceDetected(scanner, fStartSequence, false)) {
+                    if (endSequenceDetected(scanner))
+                        return fToken;
+                }
+            }
+        }
+
+        scanner.unread();
+        return Token.UNDEFINED;
+    }
+
+    /*
+     * @see IRule#evaluate(ICharacterScanner)
+     */
+    public IToken evaluate(ICharacterScanner scanner) {
+        return evaluate(scanner, false);
+    }
+
+    /**
+     * Returns whether the end sequence was detected. As the pattern can be considered
+     * ended by a line delimiter, the result of this method is <code>true</code> if the
+     * rule breaks on the end of the line, or if the EOF character is read.
+     *
+     * @param scanner the character scanner to be used
+     * @return <code>true</code> if the end sequence has been detected
+     */
+    protected bool endSequenceDetected(ICharacterScanner scanner) {
+
+        char[][] originalDelimiters= scanner.getLegalLineDelimiters();
+        int count= originalDelimiters.length;
+        if (fLineDelimiters is null || originalDelimiters.length !is count) {
+            fSortedLineDelimiters= new char[][](count);
+        } else {
+            while (count > 0 && fLineDelimiters[count-1] is originalDelimiters[count-1])
+                count--;
+        }
+        if (count !is 0) {
+            fLineDelimiters= originalDelimiters;
+            System.arraycopy(fLineDelimiters, 0, fSortedLineDelimiters, 0, fLineDelimiters.length);
+            Arrays.sort(fSortedLineDelimiters, fLineDelimiterComparator);
+        }
+
+        int readCount= 1;
+        int c;
+        while ((c= scanner.read()) !is ICharacterScanner.EOF) {
+            if (c is fEscapeCharacter) {
+                // Skip escaped character(s)
+                if (fEscapeContinuesLine) {
+                    c= scanner.read();
+                    for (int i= 0; i < fSortedLineDelimiters.length; i++) {
+                        if (c is fSortedLineDelimiters[i][0] && sequenceDetected(scanner, fSortedLineDelimiters[i], true))
+                            break;
+                    }
+                } else
+                    scanner.read();
+
+            } else if (fEndSequence.length > 0 && c is fEndSequence[0]) {
+                // Check if the specified end sequence has been found.
+                if (sequenceDetected(scanner, fEndSequence, true))
+                    return true;
+            } else if (fBreaksOnEOL) {
+                // Check for end of line since it can be used to terminate the pattern.
+                for (int i= 0; i < fSortedLineDelimiters.length; i++) {
+                    if (c is fSortedLineDelimiters[i][0] && sequenceDetected(scanner, fSortedLineDelimiters[i], true))
+                        return true;
+                }
+            }
+            readCount++;
+        }
+
+        if (fBreaksOnEOF)
+            return true;
+
+        for (; readCount > 0; readCount--)
+            scanner.unread();
+
+        return false;
+    }
+
+    /**
+     * Returns whether the next characters to be read by the character scanner
+     * are an exact match with the given sequence. No escape characters are allowed
+     * within the sequence. If specified the sequence is considered to be found
+     * when reading the EOF character.
+     *
+     * @param scanner the character scanner to be used
+     * @param sequence the sequence to be detected
+     * @param eofAllowed indicated whether EOF terminates the pattern
+     * @return <code>true</code> if the given sequence has been detected
+     */
+    protected bool sequenceDetected(ICharacterScanner scanner, char[] sequence, bool eofAllowed) {
+        for (int i= 1; i < sequence.length; i++) {
+            int c= scanner.read();
+            if (c is ICharacterScanner.EOF && eofAllowed) {
+                return true;
+            } else if (c !is sequence[i]) {
+                // Non-matching character detected, rewind the scanner back to the start.
+                // Do not unread the first character.
+                scanner.unread();
+                for (int j= i-1; j > 0; j--)
+                    scanner.unread();
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /*
+     * @see IPredicateRule#evaluate(ICharacterScanner, bool)
+     * @since 2.0
+     */
+    public IToken evaluate(ICharacterScanner scanner, bool resume) {
+        if (fColumn is UNDEFINED)
+            return doEvaluate(scanner, resume);
+
+        int c= scanner.read();
+        scanner.unread();
+        if (c is fStartSequence[0])
+            return (fColumn is scanner.getColumn() ? doEvaluate(scanner, resume) : Token.UNDEFINED);
+        return Token.UNDEFINED;
+    }
+
+    /*
+     * @see IPredicateRule#getSuccessToken()
+     * @since 2.0
+     */
+    public IToken getSuccessToken() {
+        return fToken;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/RuleBasedDamagerRepairer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.rules.RuleBasedDamagerRepairer;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.jface.text.TextAttribute;
+
+
+/**
+ * @deprecated use <code>DefaultDamagerRepairer</code>
+ */
+public class RuleBasedDamagerRepairer : DefaultDamagerRepairer {
+
+    /**
+     * Creates a damager/repairer that uses the given scanner and returns the given default
+     * text attribute if the current token does not carry a text attribute.
+     *
+     * @param scanner the rule based scanner to be used
+     * @param defaultTextAttribute the text attribute to be returned if none is specified by the current token,
+     *          may not be <code>null</code>
+     *
+     * @deprecated use RuleBasedDamagerRepairer(RuleBasedScanner) instead
+     */
+    public this(RuleBasedScanner scanner, TextAttribute defaultTextAttribute) {
+        super(scanner, defaultTextAttribute);
+    }
+
+    /**
+     * Creates a damager/repairer that uses the given scanner. The scanner may not be <code>null</code>
+     * and is assumed to return only token that carry text attributes.
+     *
+     * @param scanner the rule based scanner to be used, may not be <code>null</code>
+     * @since 2.0
+     */
+    public this(RuleBasedScanner scanner) {
+        super(scanner);
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/RuleBasedPartitionScanner.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.rules.RuleBasedPartitionScanner;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.jface.text.IDocument;
+
+
+/**
+ * Scanner that exclusively uses predicate rules.
+ * @since 2.0
+ */
+public class RuleBasedPartitionScanner : BufferedRuleBasedScanner , IPartitionTokenScanner {
+
+    /** The content type of the partition in which to resume scanning. */
+    protected String fContentType;
+    /** The offset of the partition inside which to resume. */
+    protected int fPartitionOffset;
+
+
+    /**
+     * Disallow setting the rules since this scanner
+     * exclusively uses predicate rules.
+     *
+     * @param rules the sequence of rules controlling this scanner
+     */
+    public void setRules(IRule[] rules) {
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * @see RuleBasedScanner#setRules(IRule[])
+     */
+    public void setPredicateRules(IPredicateRule[] rules) {
+        super.setRules(rules);
+    }
+
+    /*
+     * @see ITokenScanner#setRange(IDocument, int, int)
+     */
+    public void setRange(IDocument document, int offset, int length) {
+        setPartialRange(document, offset, length, null, -1);
+    }
+
+    /*
+     * @see IPartitionTokenScanner#setPartialRange(IDocument, int, int, String, int)
+     */
+    public void setPartialRange(IDocument document, int offset, int length, String contentType, int partitionOffset) {
+        fContentType= contentType;
+        fPartitionOffset= partitionOffset;
+        if (partitionOffset > -1) {
+            int delta= offset - partitionOffset;
+            if (delta > 0) {
+                super.setRange(document, partitionOffset, length + delta);
+                fOffset= offset;
+                return;
+            }
+        }
+        super.setRange(document, offset, length);
+    }
+
+    /*
+     * @see ITokenScanner#nextToken()
+     */
+    public IToken nextToken() {
+
+
+        if (fContentType is null || fRules is null) {
+            //don't try to resume
+            return super.nextToken();
+        }
+
+        // inside a partition
+
+        fColumn= UNDEFINED;
+        bool resume= (fPartitionOffset > -1 && fPartitionOffset < fOffset);
+        fTokenOffset= resume ? fPartitionOffset : fOffset;
+
+        IPredicateRule rule;
+        IToken token;
+
+        for (int i= 0; i < fRules.length; i++) {
+            rule= cast(IPredicateRule) fRules[i];
+            token= rule.getSuccessToken();
+            if (fContentType.equals(stringcast(token.getData()))) {
+                token= rule.evaluate(this, resume);
+                if (!token.isUndefined()) {
+                    fContentType= null;
+                    return token;
+                }
+            }
+        }
+
+        // haven't found any rule for this type of partition
+        fContentType= null;
+        if (resume)
+            fOffset= fPartitionOffset;
+        return super.nextToken();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/RuleBasedPartitioner.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,616 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.rules.RuleBasedPartitioner;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DefaultPositionUpdater;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentPartitioner;
+import dwtx.jface.text.IDocumentPartitionerExtension;
+import dwtx.jface.text.IDocumentPartitionerExtension2;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITypedRegion;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextUtilities;
+import dwtx.jface.text.TypedPosition;
+import dwtx.jface.text.TypedRegion;
+
+
+
+/**
+ * A standard implementation of a syntax driven document partitioner.
+ * It uses a rule based scanner to scan the document and to determine
+ * the document's partitioning. The tokens returned by the rules the
+ * scanner is configured with are supposed to return the partition type
+ * as their data. The partitioner remembers the document's partitions
+ * in the document itself rather than maintaining its own data structure.
+ *
+ * @see IRule
+ * @see RuleBasedScanner
+ *
+ * @deprecated use <code>FastPartitioner</code> instead
+ */
+public class RuleBasedPartitioner : IDocumentPartitioner, IDocumentPartitionerExtension, IDocumentPartitionerExtension2 {
+
+    /**
+     * The position category this partitioner uses to store the document's partitioning information
+     * @deprecated As of 3.0, use <code>getManagingPositionCategories()</code>.
+     */
+    public const static String CONTENT_TYPES_CATEGORY= "__content_types_category"; //$NON-NLS-1$
+
+
+    /** The partitioner's scanner */
+    protected RuleBasedScanner fScanner;
+    /** The legal content types of this partitioner */
+    protected String[] fLegalContentTypes;
+    /** The partitioner's document */
+    protected IDocument fDocument;
+    /** The document length before a document change occurred */
+    protected int fPreviousDocumentLength;
+    /** The position updater used to for the default updating of partitions */
+    protected DefaultPositionUpdater fPositionUpdater;
+    /** The offset at which the first changed partition starts */
+    protected int fStartOffset;
+    /** The offset at which the last changed partition ends */
+    protected int fEndOffset;
+    /**The offset at which a partition has been deleted */
+    protected int fDeleteOffset;
+    /**
+     * The position category for managing partitioning information.
+     * @since 3.0
+     */
+    private String fPositionCategory;
+
+
+    /**
+     * Creates a new partitioner that uses the given scanner and may return
+     * partitions of the given legal content types.
+     *
+     * @param scanner the scanner this partitioner is supposed to use
+     * @param legalContentTypes the legal content types of this partitioner
+     */
+    public this(RuleBasedScanner scanner, String[] legalContentTypes) {
+        fScanner= scanner;
+        fLegalContentTypes= TextUtilities.copy(legalContentTypes);
+        fPositionCategory= CONTENT_TYPES_CATEGORY ~ Integer.toString(toHash());
+        fPositionUpdater= new DefaultPositionUpdater(fPositionCategory);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension2#getManagingPositionCategories()
+     * @since 3.0
+     */
+    public String[] getManagingPositionCategories() {
+        return [ fPositionCategory ];
+    }
+
+    /*
+     * @see IDocumentPartitioner#connect
+     */
+    public void connect(IDocument document) {
+        Assert.isNotNull(cast(Object)document);
+        Assert.isTrue(!document.containsPositionCategory(fPositionCategory));
+
+        fDocument= document;
+        fDocument.addPositionCategory(fPositionCategory);
+
+        initialize();
+    }
+
+    /**
+     * Performs the initial partitioning of the partitioner's document.
+     */
+    protected void initialize() {
+
+        fScanner.setRange(fDocument, 0, fDocument.getLength());
+
+        try {
+            IToken token= fScanner.nextToken();
+            while (!token.isEOF()) {
+
+                String contentType= getTokenContentType(token);
+
+                if (isSupportedContentType(contentType)) {
+                    TypedPosition p= new TypedPosition(fScanner.getTokenOffset(), fScanner.getTokenLength(), contentType);
+                    fDocument.addPosition(fPositionCategory, p);
+                }
+
+                token= fScanner.nextToken();
+            }
+        } catch (BadLocationException x) {
+            // cannot happen as offsets come from scanner
+        } catch (BadPositionCategoryException x) {
+            // cannot happen if document has been connected before
+        }
+    }
+
+    /*
+     * @see IDocumentPartitioner#disconnect
+     */
+    public void disconnect() {
+
+        Assert.isTrue(fDocument.containsPositionCategory(fPositionCategory));
+
+        try {
+            fDocument.removePositionCategory(fPositionCategory);
+        } catch (BadPositionCategoryException x) {
+            // can not happen because of Assert
+        }
+    }
+
+    /*
+     * @see IDocumentPartitioner#documentAboutToBeChanged
+     */
+    public void documentAboutToBeChanged(DocumentEvent e) {
+
+        Assert.isTrue(e.getDocument() is fDocument);
+
+        fPreviousDocumentLength= e.getDocument().getLength();
+        fStartOffset= -1;
+        fEndOffset= -1;
+        fDeleteOffset= -1;
+    }
+
+    /*
+     * @see IDocumentPartitioner#documentChanged
+     */
+    public bool documentChanged(DocumentEvent e) {
+        IRegion region= documentChanged2(e);
+        return (region !is null);
+    }
+
+    /**
+     * Helper method for tracking the minimal region containing all partition changes.
+     * If <code>offset</code> is smaller than the remembered offset, <code>offset</code>
+     * will from now on be remembered. If <code>offset  + length</code> is greater than
+     * the remembered end offset, it will be remembered from now on.
+     *
+     * @param offset the offset
+     * @param length the length
+     */
+    private void rememberRegion(int offset, int length) {
+        // remember start offset
+        if (fStartOffset is -1)
+            fStartOffset= offset;
+        else if (offset < fStartOffset)
+            fStartOffset= offset;
+
+        // remember end offset
+        int endOffset= offset + length;
+        if (fEndOffset is -1)
+            fEndOffset= endOffset;
+        else if (endOffset > fEndOffset)
+            fEndOffset= endOffset;
+    }
+
+    /**
+     * Remembers the given offset as the deletion offset.
+     *
+     * @param offset the offset
+     */
+    private void rememberDeletedOffset(int offset) {
+        fDeleteOffset= offset;
+    }
+
+    /**
+     * Creates the minimal region containing all partition changes using the
+     * remembered offset, end offset, and deletion offset.
+     * @return the minimal region containing all the partition changes
+     */
+    private IRegion createRegion() {
+        if (fDeleteOffset is -1) {
+            if (fStartOffset is -1 || fEndOffset is -1)
+                return null;
+            return new Region(fStartOffset, fEndOffset - fStartOffset);
+        } else if (fStartOffset is -1 || fEndOffset is -1) {
+            return new Region(fDeleteOffset, 0);
+        } else {
+            int offset= Math.min(fDeleteOffset, fStartOffset);
+            int endOffset= Math.max(fDeleteOffset, fEndOffset);
+            return new Region(offset, endOffset - offset);
+        }
+    }
+
+    /*
+     * @see IDocumentPartitionerExtension#documentChanged2(DocumentEvent)
+     * @since 2.0
+     */
+    public IRegion documentChanged2(DocumentEvent e) {
+
+        try {
+
+            IDocument d= e.getDocument();
+            Position[] category= d.getPositions(fPositionCategory);
+            int first= 0;
+            int reparseStart= 0;
+            int originalSize= category.length;
+
+            if (originalSize > 0) {
+
+                /*
+                 * determine character position at which the scanner starts:
+                 * first position behind the last non-default partition the actual position is not involved with
+                 */
+
+                first= d.computeIndexInCategory(fPositionCategory, e.getOffset());
+
+                Position p= null;
+                do {
+                    --first;
+                    if (first < 0)
+                        break;
+
+                    p= category[first];
+
+                } while (p.overlapsWith(e.getOffset(), e.getLength()) ||
+                            (e.getOffset() is fPreviousDocumentLength &&
+                             (p.getOffset() + p.getLength() is fPreviousDocumentLength)));
+
+                fPositionUpdater.update(e);
+                for (int i= 0; i < category.length; i++) {
+                    p= category[i];
+                    if (p.isDeleted) {
+                        rememberDeletedOffset(e.getOffset());
+                        break;
+                    }
+                }
+                category= d.getPositions(fPositionCategory);
+
+                if (first >= 0) {
+                    p= category[first];
+                    reparseStart= p.getOffset() + p.getLength();
+                }
+
+                ++first;
+            }
+
+            fScanner.setRange(d, reparseStart, d.getLength() - reparseStart);
+
+            int lastScannedPosition= reparseStart;
+            IToken token= fScanner.nextToken();
+
+            while (!token.isEOF()) {
+
+
+                String contentType= getTokenContentType(token);
+
+                if (!isSupportedContentType(contentType)) {
+                    token= fScanner.nextToken();
+                    continue;
+                }
+
+                int start= fScanner.getTokenOffset();
+                int length= fScanner.getTokenLength();
+
+                lastScannedPosition= start + length - 1;
+
+                // remove all affected positions
+                while (first < category.length) {
+                    TypedPosition p= cast(TypedPosition) category[first];
+                    if (lastScannedPosition >= p.offset + p.length ||
+                            (p.overlapsWith(start, length) &&
+                                (!d.containsPosition(fPositionCategory, start, length) ||
+                                 !contentType.equals(p.getType())))) {
+
+                        rememberRegion(p.offset, p.length);
+                        d.removePosition(fPositionCategory, p);
+                        ++ first;
+
+                    } else
+                        break;
+                }
+
+                // if position already exists we are done
+                if (d.containsPosition(fPositionCategory, start, length))
+                    return createRegion();
+
+                // insert the new type position
+                try {
+                    d.addPosition(fPositionCategory, new TypedPosition(start, length, contentType));
+                    rememberRegion(start, length);
+                } catch (BadPositionCategoryException x) {
+                } catch (BadLocationException x) {
+                }
+
+                token= fScanner.nextToken();
+            }
+
+
+            // remove all positions behind lastScannedPosition since there aren't any further types
+            if (lastScannedPosition !is reparseStart) {
+                // if this condition is not met, nothing has been scanned because of a delete
+                ++ lastScannedPosition;
+            }
+            first= d.computeIndexInCategory(fPositionCategory, lastScannedPosition);
+
+            TypedPosition p;
+            while (first < category.length) {
+                p= cast(TypedPosition) category[first++];
+                d.removePosition(fPositionCategory, p);
+                rememberRegion(p.offset, p.length);
+            }
+
+        } catch (BadPositionCategoryException x) {
+            // should never happen on connected documents
+        } catch (BadLocationException x) {
+        }
+
+        return createRegion();
+    }
+
+
+    /**
+     * Returns the position in the partitoner's position category which is
+     * close to the given offset. This is, the position has either an offset which
+     * is the same as the given offset or an offset which is smaller than the given
+     * offset. This method profits from the knowledge that a partitioning is
+     * a ordered set of disjoint position.
+     *
+     * @param offset the offset for which to search the closest position
+     * @return the closest position in the partitioner's category
+     */
+    protected TypedPosition findClosestPosition(int offset) {
+
+        try {
+
+            int index= fDocument.computeIndexInCategory(fPositionCategory, offset);
+            Position[] category= fDocument.getPositions(fPositionCategory);
+
+            if (category.length is 0)
+                return null;
+
+            if (index < category.length) {
+                if (offset is category[index].offset)
+                    return cast(TypedPosition) category[index];
+            }
+
+            if (index > 0)
+                index--;
+
+            return cast(TypedPosition) category[index];
+
+        } catch (BadPositionCategoryException x) {
+        } catch (BadLocationException x) {
+        }
+
+        return null;
+    }
+
+
+    /*
+     * @see IDocumentPartitioner#getContentType
+     */
+    public String getContentType(int offset) {
+
+        TypedPosition p= findClosestPosition(offset);
+        if (p !is null && p.includes(offset))
+            return p.getType();
+
+        return IDocument.DEFAULT_CONTENT_TYPE;
+    }
+
+    /*
+     * @see IDocumentPartitioner#getPartition
+     */
+    public ITypedRegion getPartition(int offset) {
+
+        try {
+
+            Position[] category = fDocument.getPositions(fPositionCategory);
+
+            if (category is null || category.length is 0)
+                return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE);
+
+            int index= fDocument.computeIndexInCategory(fPositionCategory, offset);
+
+            if (index < category.length) {
+
+                TypedPosition next= cast(TypedPosition) category[index];
+
+                if (offset is next.offset)
+                    return new TypedRegion(next.getOffset(), next.getLength(), next.getType());
+
+                if (index is 0)
+                    return new TypedRegion(0, next.offset, IDocument.DEFAULT_CONTENT_TYPE);
+
+                TypedPosition previous= cast(TypedPosition) category[index - 1];
+                if (previous.includes(offset))
+                    return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType());
+
+                int endOffset= previous.getOffset() + previous.getLength();
+                return new TypedRegion(endOffset, next.getOffset() - endOffset, IDocument.DEFAULT_CONTENT_TYPE);
+            }
+
+            TypedPosition previous= cast(TypedPosition) category[category.length - 1];
+            if (previous.includes(offset))
+                return new TypedRegion(previous.getOffset(), previous.getLength(), previous.getType());
+
+            int endOffset= previous.getOffset() + previous.getLength();
+            return new TypedRegion(endOffset, fDocument.getLength() - endOffset, IDocument.DEFAULT_CONTENT_TYPE);
+
+        } catch (BadPositionCategoryException x) {
+        } catch (BadLocationException x) {
+        }
+
+        return new TypedRegion(0, fDocument.getLength(), IDocument.DEFAULT_CONTENT_TYPE);
+    }
+
+    /*
+     * @see IDocumentPartitioner#computePartitioning
+     */
+    public ITypedRegion[] computePartitioning(int offset, int length) {
+        return computePartitioning(offset, length, false);
+    }
+
+    /*
+     * @see IDocumentPartitioner#getLegalContentTypes
+     */
+    public String[] getLegalContentTypes() {
+        return TextUtilities.copy(fLegalContentTypes);
+    }
+
+    /**
+     * Returns whether the given type is one of the legal content types.
+     *
+     * @param contentType the content type to check
+     * @return <code>true</code> if the content type is a legal content type
+     */
+    protected bool isSupportedContentType(String contentType) {
+        if (contentType !is null) {
+            for (int i= 0; i < fLegalContentTypes.length; i++) {
+                if (fLegalContentTypes[i].equals(contentType))
+                    return true;
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns a content type encoded in the given token. If the token's
+     * data is not <code>null</code> and a string it is assumed that
+     * it is the encoded content type.
+     *
+     * @param token the token whose content type is to be determined
+     * @return the token's content type
+     */
+    protected String getTokenContentType(IToken token) {
+        Object data= token.getData();
+        if ( auto str = cast(ArrayWrapperString)data )
+            return str.array;
+        return null;
+    }
+
+    /* zero-length partition support */
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension2#getContentType(int)
+     * @since 3.0
+     */
+    public String getContentType(int offset, bool preferOpenPartitions) {
+        return getPartition(offset, preferOpenPartitions).getType();
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension2#getPartition(int)
+     * @since 3.0
+     */
+    public ITypedRegion getPartition(int offset, bool preferOpenPartitions) {
+        ITypedRegion region= getPartition(offset);
+        if (preferOpenPartitions) {
+            if (region.getOffset() is offset && !region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE)) {
+                if (offset > 0) {
+                    region= getPartition(offset - 1);
+                    if (region.getType().equals(IDocument.DEFAULT_CONTENT_TYPE))
+                        return region;
+                }
+                return new TypedRegion(offset, 0, IDocument.DEFAULT_CONTENT_TYPE);
+            }
+        }
+        return region;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentPartitionerExtension2#computePartitioning(int, int)
+     * @since 3.0
+     */
+    public ITypedRegion[] computePartitioning(int offset, int length, bool includeZeroLengthPartitions) {
+        List list= new ArrayList();
+
+        try {
+
+            int endOffset= offset + length;
+
+            Position[] category= fDocument.getPositions(fPositionCategory);
+
+            TypedPosition previous= null, current= null;
+            int start, end, gapOffset;
+            Position gap= null;
+
+            for (int i= 0; i < category.length; i++) {
+
+                current= cast(TypedPosition) category[i];
+
+                gapOffset= (previous !is null) ? previous.getOffset() + previous.getLength() : 0;
+                gap= new Position(gapOffset, current.getOffset() - gapOffset);
+                if ((includeZeroLengthPartitions || gap.getLength() > 0) && gap.overlapsWith(offset, length)) {
+                    start= Math.max(offset, gapOffset);
+                    end= Math.min(endOffset, gap.getOffset() + gap.getLength());
+                    list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE));
+                }
+
+                if (current.overlapsWith(offset, length)) {
+                    start= Math.max(offset, current.getOffset());
+                    end= Math.min(endOffset, current.getOffset() + current.getLength());
+                    list.add(new TypedRegion(start, end - start, current.getType()));
+                }
+
+                previous= current;
+            }
+
+            if (previous !is null) {
+                gapOffset= previous.getOffset() + previous.getLength();
+                gap= new Position(gapOffset, fDocument.getLength() - gapOffset);
+                if ((includeZeroLengthPartitions || gap.getLength() > 0) && ((includeZeroLengthPartitions && offset + length is gapOffset && gap.length is 0) || gap.overlapsWith(offset, length))) {
+                    start= Math.max(offset, gapOffset);
+                    end= Math.min(endOffset, fDocument.getLength());
+                    list.add(new TypedRegion(start, end - start, IDocument.DEFAULT_CONTENT_TYPE));
+                }
+            }
+
+            if (list.isEmpty())
+                list.add(new TypedRegion(offset, length, IDocument.DEFAULT_CONTENT_TYPE));
+
+        } catch (BadPositionCategoryException x) {
+        }
+
+        return arraycast!(ITypedRegion)(list.toArray());
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/RuleBasedScanner.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,246 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.rules.RuleBasedScanner;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+
+
+/**
+ * A generic scanner which can be "programmed" with a sequence of rules.
+ * The scanner is used to get the next token by evaluating its rule in sequence until
+ * one is successful. If a rule returns a token which is undefined, the scanner will proceed to
+ * the next rule. Otherwise the token provided by the rule will be returned by
+ * the scanner. If no rule returned a defined token, this scanner returns a token
+ * which returns <code>true</code> when calling <code>isOther</code>, unless the end
+ * of the file is reached. In this case the token returns <code>true</code> when calling
+ * <code>isEOF</code>.
+ *
+ * @see IRule
+ */
+public class RuleBasedScanner : ICharacterScanner, ITokenScanner {
+
+    /** The list of rules of this scanner */
+    protected IRule[] fRules;
+    /** The token to be returned by default if no rule fires */
+    protected IToken fDefaultReturnToken;
+    /** The document to be scanned */
+    protected IDocument fDocument;
+    /** The cached legal line delimiters of the document */
+    protected char[][] fDelimiters;
+    /** The offset of the next character to be read */
+    protected int fOffset;
+    /** The end offset of the range to be scanned */
+    protected int fRangeEnd;
+    /** The offset of the last read token */
+    protected int fTokenOffset;
+    /** The cached column of the current scanner position */
+    protected int fColumn;
+    /** Internal setting for the un-initialized column cache. */
+    protected static final int UNDEFINED= -1;
+
+    /**
+     * Creates a new rule based scanner which does not have any rule.
+     */
+    public this() {
+    }
+
+    /**
+     * Configures the scanner with the given sequence of rules.
+     *
+     * @param rules the sequence of rules controlling this scanner
+     */
+    public void setRules(IRule[] rules) {
+        if (rules !is null) {
+            fRules= new IRule[rules.length];
+            SimpleType!(IRule).arraycopy(rules, 0, fRules, 0, rules.length);
+        } else
+            fRules= null;
+    }
+
+    /**
+     * Configures the scanner's default return token. This is the token
+     * which is returned when none of the rules fired and EOF has not been
+     * reached.
+     *
+     * @param defaultReturnToken the default return token
+     * @since 2.0
+     */
+    public void setDefaultReturnToken(IToken defaultReturnToken) {
+        Assert.isNotNull(defaultReturnToken.getData());
+        fDefaultReturnToken= defaultReturnToken;
+    }
+
+    /*
+     * @see ITokenScanner#setRange(IDocument, int, int)
+     */
+    public void setRange(IDocument document, int offset, int length) {
+        Assert.isLegal(document !is null);
+        final int documentLength= document.getLength();
+        checkRange(offset, length, documentLength);
+
+        fDocument= document;
+        fOffset= offset;
+        fColumn= UNDEFINED;
+        fRangeEnd= offset + length;
+
+        String[] delimiters= fDocument.getLegalLineDelimiters();
+        fDelimiters= new char[][](delimiters.length);
+        for (int i= 0; i < delimiters.length; i++)
+            fDelimiters[i]= delimiters[i].toCharArray();
+
+        if (fDefaultReturnToken is null)
+            fDefaultReturnToken= new Token(null);
+    }
+
+    /**
+     * Checks that the given range is valid.
+     * See https://bugs.eclipse.org/bugs/show_bug.cgi?id=69292
+     *
+     * @param offset the offset of the document range to scan
+     * @param length the length of the document range to scan
+     * @param documentLength the document's length
+     * @since 3.3
+     */
+    private void checkRange(int offset, int length, int documentLength) {
+        Assert.isLegal(offset > -1);
+        Assert.isLegal(length > -1);
+        Assert.isLegal(offset + length <= documentLength);
+    }
+
+    /*
+     * @see ITokenScanner#getTokenOffset()
+     */
+    public int getTokenOffset() {
+        return fTokenOffset;
+    }
+
+    /*
+     * @see ITokenScanner#getTokenLength()
+     */
+    public int getTokenLength() {
+        if (fOffset < fRangeEnd)
+            return fOffset - getTokenOffset();
+        return fRangeEnd - getTokenOffset();
+    }
+
+
+    /*
+     * @see ICharacterScanner#getColumn()
+     */
+    public int getColumn() {
+        if (fColumn is UNDEFINED) {
+            try {
+                int line= fDocument.getLineOfOffset(fOffset);
+                int start= fDocument.getLineOffset(line);
+
+                fColumn= fOffset - start;
+
+            } catch (BadLocationException ex) {
+            }
+        }
+        return fColumn;
+    }
+
+    /*
+     * @see ICharacterScanner#getLegalLineDelimiters()
+     */
+    public char[][] getLegalLineDelimiters() {
+        return fDelimiters;
+    }
+
+    /*
+     * @see ITokenScanner#nextToken()
+     */
+    public IToken nextToken() {
+
+        fTokenOffset= fOffset;
+        fColumn= UNDEFINED;
+
+        if (fRules !is null) {
+            for (int i= 0; i < fRules.length; i++) {
+                IToken token= (fRules[i].evaluate(this));
+                if (!token.isUndefined())
+                    return token;
+            }
+        }
+
+        if (read() is EOF)
+            return Token.EOF;
+        return fDefaultReturnToken;
+    }
+
+    /*
+     * @see ICharacterScanner#read()
+     */
+    public int read() {
+
+        try {
+
+            if (fOffset < fRangeEnd) {
+                try {
+                    return fDocument.getChar(fOffset);
+                } catch (BadLocationException e) {
+                }
+            }
+
+            return EOF;
+
+        } finally {
+            ++ fOffset;
+            fColumn= UNDEFINED;
+        }
+    }
+
+    /*
+     * @see ICharacterScanner#unread()
+     */
+    public void unread() {
+        --fOffset;
+        fColumn= UNDEFINED;
+    }
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/SingleLineRule.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Christopher Lenz (cmlenz@gmx.de) - support for line continuation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.rules.SingleLineRule;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A specific configuration of pattern rule whereby
+ * the pattern begins with a specific sequence and may
+ * end with a specific sequence, but will not span more
+ * than a single line.
+ */
+public class SingleLineRule : PatternRule {
+
+    /**
+     * Creates a rule for the given starting and ending sequence
+     * which, if detected, will return the specified token.
+     *
+     * @param startSequence the pattern's start sequence
+     * @param endSequence the pattern's end sequence
+     * @param token the token to be returned on success
+     */
+    public this(String startSequence, String endSequence, IToken token) {
+        this(startSequence, endSequence, token, cast(wchar) 0);
+    }
+
+    /**
+     * Creates a rule for the given starting and ending sequence
+     * which, if detected, will return the specified token.
+     * Any character which follows the given escape character
+     * will be ignored.
+     *
+     * @param startSequence the pattern's start sequence
+     * @param endSequence the pattern's end sequence
+     * @param token the token to be returned on success
+     * @param escapeCharacter the escape character
+     */
+    public this(String startSequence, String endSequence, IToken token, char escapeCharacter) {
+        this(startSequence, endSequence, token, escapeCharacter, false);
+    }
+
+    /**
+     * Creates a rule for the given starting and ending sequence
+     * which, if detected, will return the specified token. Alternatively, the
+     * line can also be ended with the end of the file.
+     * Any character which follows the given escape character
+     * will be ignored.
+     *
+     * @param startSequence the pattern's start sequence
+     * @param endSequence the pattern's end sequence
+     * @param token the token to be returned on success
+     * @param escapeCharacter the escape character
+     * @param breaksOnEOF indicates whether the end of the file successfully terminates this rule
+     * @since 2.1
+     */
+    public this(String startSequence, String endSequence, IToken token, char escapeCharacter, bool breaksOnEOF) {
+        super(startSequence, endSequence, token, escapeCharacter, true, breaksOnEOF);
+    }
+
+    /**
+     * Creates a rule for the given starting and ending sequence
+     * which, if detected, will return the specified token. Alternatively, the
+     * line can also be ended with the end of the file.
+     * Any character which follows the given escape character
+     * will be ignored. In addition, an escape character immediately before an
+     * end of line can be set to continue the line.
+     *
+     * @param startSequence the pattern's start sequence
+     * @param endSequence the pattern's end sequence
+     * @param token the token to be returned on success
+     * @param escapeCharacter the escape character
+     * @param breaksOnEOF indicates whether the end of the file successfully terminates this rule
+     * @param escapeContinuesLine indicates whether the specified escape character is used for line
+     *        continuation, so that an end of line immediately after the escape character does not
+     *        terminate the line, even if <code>breakOnEOL</code> is true
+     * @since 3.0
+     */
+    public this(String startSequence, String endSequence, IToken token, char escapeCharacter, bool breaksOnEOF, bool escapeContinuesLine) {
+        super(startSequence, endSequence, token, escapeCharacter, true, breaksOnEOF, escapeContinuesLine);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/Token.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.rules.Token;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Standard implementation of <code>IToken</code>.
+ */
+public class Token : IToken {
+
+    /** Internal token type: Undefined */
+    private static const int T_UNDEFINED= 0;
+    /** Internal token type: EOF */
+    private static const int T_EOF= 1;
+    /** Internal token type: Whitespace */
+    private static const int T_WHITESPACE= 2;
+    /** Internal token type: Others */
+    private static const int T_OTHER=   3;
+
+
+    /**
+     * Standard token: Undefined.
+     */
+    public static IToken UNDEFINED_;
+    public static IToken UNDEFINED(){
+        if( UNDEFINED_ is null ){
+            synchronized( Token.classinfo ){
+                if( UNDEFINED_ is null ){
+                    UNDEFINED_ = new Token(T_UNDEFINED);
+                }
+            }
+        }
+        return UNDEFINED_;
+    }
+    /**
+     * Standard token: End Of File.
+     */
+    public static IToken EOF_;
+    public static IToken EOF(){
+        if( EOF_ is null ){
+            synchronized( Token.classinfo ){
+                if( EOF_ is null ){
+                    EOF_ = new Token(T_EOF);
+                }
+            }
+        }
+        return EOF_;
+    }
+    /**
+     * Standard token: Whitespace.
+     */
+    public static IToken WHITESPACE_;
+    public static IToken WHITESPACE(){
+        if( WHITESPACE_ is null ){
+            synchronized( Token.classinfo ){
+                if( WHITESPACE_ is null ){
+                    WHITESPACE_ = new Token(T_WHITESPACE);
+                }
+            }
+        }
+        return WHITESPACE_;
+    }
+
+    /**
+     * Standard token: Neither {@link #UNDEFINED}, {@link #WHITESPACE}, nor {@link #EOF}.
+     * @deprecated will be removed
+     */
+    public static IToken OTHER_;
+    public static IToken OTHER(){
+        if( OTHER_ is null ){
+            synchronized( Token.classinfo ){
+                if( OTHER_ is null ){
+                    OTHER_ = new Token(T_OTHER);
+                }
+            }
+        }
+        return OTHER_;
+    }
+
+    /** The type of this token */
+    private int fType;
+    /** The data associated with this token */
+    private Object fData;
+
+    /**
+     * Creates a new token according to the given specification which does not
+     * have any data attached to it.
+     *
+     * @param type the type of the token
+     * @since 2.0
+     */
+    private this(int type) {
+        fType= type;
+        fData= null;
+    }
+
+    /**
+     * Creates a new token which represents neither undefined, whitespace, nor EOF.
+     * The newly created token has the given data attached to it.
+     *
+     * @param data the data attached to the newly created token
+     */
+    public this(Object data) {
+        fType= T_OTHER;
+        fData= data;
+    }
+
+    /**
+     * Re-initializes the data of this token. The token may not represent
+     * undefined, whitespace, or EOF.
+     *
+     * @param data to be attached to the token
+     * @since 2.0
+     */
+    public void setData(Object data) {
+        Assert.isTrue(isOther());
+        fData= data;
+    }
+
+    /*
+     * @see IToken#getData()
+     */
+    public Object getData() {
+        return fData;
+    }
+
+    /*
+     * @see IToken#isOther()
+     */
+    public bool isOther() {
+        return (fType is T_OTHER);
+    }
+
+    /*
+     * @see IToken#isEOF()
+     */
+    public bool isEOF() {
+        return (fType is T_EOF);
+    }
+
+    /*
+     * @see IToken#isWhitespace()
+     */
+    public bool isWhitespace() {
+        return (fType is T_WHITESPACE);
+    }
+
+    /*
+     * @see IToken#isUndefined()
+     */
+    public bool isUndefined() {
+        return (fType is T_UNDEFINED);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/WhitespaceRule.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.rules.WhitespaceRule;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * An implementation of <code>IRule</code> capable of detecting whitespace.
+ * A whitespace rule uses a whitespace detector in order to find out which
+ * characters are whitespace characters.
+ *
+ * @see IWhitespaceDetector
+ */
+public class WhitespaceRule : IRule {
+
+    /** The whitespace detector used by this rule */
+    protected IWhitespaceDetector fDetector;
+
+    /**
+     * Creates a rule which, with the help of an
+     * whitespace detector, will return a whitespace
+     * token when a whitespace is detected.
+     *
+     * @param detector the rule's whitespace detector, may not be <code>null</code>
+     */
+    public this(IWhitespaceDetector detector) {
+        Assert.isNotNull(cast(Object)detector);
+        fDetector= detector;
+    }
+
+    /*
+     * @see IRule#evaluate(ICharacterScanner)
+     */
+    public IToken evaluate(ICharacterScanner scanner) {
+        int c= scanner.read();
+        if (fDetector.isWhitespace(cast(char) c)) {
+            do {
+                c= scanner.read();
+            } while (fDetector.isWhitespace(cast(char) c));
+            scanner.unread();
+            return Token.WHITESPACE;
+        }
+
+        scanner.unread();
+        return Token.UNDEFINED;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/WordPatternRule.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.rules.WordPatternRule;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WordRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+
+
+
+/**
+ * A specific single line rule which stipulates that the start
+ * and end sequence occur within a single word, as defined by a word detector.
+ *
+ * @see IWordDetector
+ */
+public class WordPatternRule : SingleLineRule {
+
+    /** The word detector used by this rule */
+    protected IWordDetector fDetector;
+    /** The internal buffer used for pattern detection */
+    private StringBuffer fBuffer;
+
+    /**
+     * Creates a rule for the given starting and ending word
+     * pattern which, if detected, will return the specified token.
+     * A word detector is used to identify words.
+     *
+     * @param detector the word detector to be used
+     * @param startSequence the start sequence of the word pattern
+     * @param endSequence the end sequence of the word pattern
+     * @param token the token to be returned on success
+     */
+    public this(IWordDetector detector, String startSequence, String endSequence, IToken token) {
+        this(detector, startSequence, endSequence, token, cast(wchar)0);
+    }
+
+    /**
+    /**
+     * Creates a rule for the given starting and ending word
+     * pattern which, if detected, will return the specified token.
+     * A word detector is used to identify words.
+     * Any character which follows the given escapeCharacter will be ignored.
+     *
+     * @param detector the word detector to be used
+     * @param startSequence the start sequence of the word pattern
+     * @param endSequence the end sequence of the word pattern
+     * @param token the token to be returned on success
+     * @param escapeCharacter the escape character
+     */
+    public this(IWordDetector detector, String startSequence, String endSequence, IToken token, char escapeCharacter) {
+        fBuffer= new StringBuffer();
+        super(startSequence, endSequence, token, escapeCharacter);
+        Assert.isNotNull(cast(Object)detector);
+        fDetector= detector;
+    }
+
+    /**
+     * Returns whether the end sequence was detected.
+     * The rule acquires the rest of the word, using the
+     * provided word detector, and tests to determine if
+     * it ends with the end sequence.
+     *
+     * @param scanner the scanner to be used
+     * @return <code>true</code> if the word ends on the given end sequence
+     */
+    protected bool endSequenceDetected(ICharacterScanner scanner) {
+        fBuffer.truncate(0);
+        int c= scanner.read();
+        while (fDetector.isWordPart(cast(char) c)) {
+            fBuffer.append(cast(char) c);
+            c= scanner.read();
+        }
+        scanner.unread();
+
+        if (fBuffer.length() >= fEndSequence.length) {
+            for (int i=fEndSequence.length - 1, j= fBuffer.length() - 1; i >= 0; i--, j--) {
+                if (fEndSequence[i] !is fBuffer.slice()[j]) {
+                    unreadBuffer(scanner);
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        unreadBuffer(scanner);
+        return false;
+    }
+
+    /**
+     * Returns the characters in the buffer to the scanner.
+     * Note that the rule must also return the characters
+     * read in as part of the start sequence expect the first one.
+     *
+     * @param scanner the scanner to be used
+     */
+    protected void unreadBuffer(ICharacterScanner scanner) {
+        fBuffer.select(0, 0 );
+        fBuffer.replace(fStartSequence);
+        for (int i= fBuffer.length() - 1; i > 0; i--)
+            scanner.unread();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/rules/WordRule.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.rules.WordRule;
+
+import dwtx.jface.text.rules.FastPartitioner; // packageimport
+import dwtx.jface.text.rules.ITokenScanner; // packageimport
+import dwtx.jface.text.rules.Token; // packageimport
+import dwtx.jface.text.rules.RuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.EndOfLineRule; // packageimport
+import dwtx.jface.text.rules.WhitespaceRule; // packageimport
+import dwtx.jface.text.rules.WordPatternRule; // packageimport
+import dwtx.jface.text.rules.IPredicateRule; // packageimport
+import dwtx.jface.text.rules.DefaultPartitioner; // packageimport
+import dwtx.jface.text.rules.NumberRule; // packageimport
+import dwtx.jface.text.rules.SingleLineRule; // packageimport
+import dwtx.jface.text.rules.PatternRule; // packageimport
+import dwtx.jface.text.rules.IWordDetector; // packageimport
+import dwtx.jface.text.rules.RuleBasedDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.ICharacterScanner; // packageimport
+import dwtx.jface.text.rules.IRule; // packageimport
+import dwtx.jface.text.rules.DefaultDamagerRepairer; // packageimport
+import dwtx.jface.text.rules.IToken; // packageimport
+import dwtx.jface.text.rules.IPartitionTokenScanner; // packageimport
+import dwtx.jface.text.rules.MultiLineRule; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitioner; // packageimport
+import dwtx.jface.text.rules.RuleBasedPartitionScanner; // packageimport
+import dwtx.jface.text.rules.BufferedRuleBasedScanner; // packageimport
+import dwtx.jface.text.rules.IWhitespaceDetector; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+import dwtx.core.runtime.Assert;
+
+
+
+/**
+ * An implementation of <code>IRule</code> capable of detecting words
+ * Word rules also allow for the association of tokens with specific words.
+ * That is, not only can the rule be used to provide tokens for exact matches,
+ * but also for the generalized notion of a word in the context in which it is used.
+ * A word rules uses a word detector to determine what a word is.
+ *
+ * @see IWordDetector
+ */
+public class WordRule : IRule {
+
+    /** Internal setting for the un-initialized column constraint. */
+    protected static const int UNDEFINED= -1;
+
+    /** The word detector used by this rule. */
+    protected IWordDetector fDetector;
+    /** The default token to be returned on success and if nothing else has been specified. */
+    protected IToken fDefaultToken;
+    /** The column constraint. */
+    protected int fColumn= UNDEFINED;
+    /** The table of predefined words and token for this rule. */
+    protected Map fWords;
+    /** Buffer used for pattern detection. */
+    private StringBuffer fBuffer;
+    /**
+     * Tells whether this rule is case sensitive.
+     * @since 3.3
+     */
+    private bool fIgnoreCase= false;
+
+    /**
+     * Creates a rule which, with the help of an word detector, will return the token
+     * associated with the detected word. If no token has been associated, the scanner
+     * will be rolled back and an undefined token will be returned in order to allow
+     * any subsequent rules to analyze the characters.
+     *
+     * @param detector the word detector to be used by this rule, may not be <code>null</code>
+     * @see #addWord(String, IToken)
+     */
+    public this(IWordDetector detector) {
+        this(detector, Token.UNDEFINED, false);
+    }
+
+    /**
+     * Creates a rule which, with the help of a word detector, will return the token
+     * associated with the detected word. If no token has been associated, the
+     * specified default token will be returned.
+     *
+     * @param detector the word detector to be used by this rule, may not be <code>null</code>
+     * @param defaultToken the default token to be returned on success
+     *          if nothing else is specified, may not be <code>null</code>
+     * @see #addWord(String, IToken)
+     */
+    public this(IWordDetector detector, IToken defaultToken) {
+        this(detector, defaultToken, false);
+    }
+
+    /**
+     * Creates a rule which, with the help of a word detector, will return the token
+     * associated with the detected word. If no token has been associated, the
+     * specified default token will be returned.
+     *
+     * @param detector the word detector to be used by this rule, may not be <code>null</code>
+     * @param defaultToken the default token to be returned on success
+     *          if nothing else is specified, may not be <code>null</code>
+     * @param ignoreCase the case sensitivity associated with this rule
+     * @see #addWord(String, IToken)
+     * @since 3.3
+     */
+    public this(IWordDetector detector, IToken defaultToken, bool ignoreCase) {
+        fWords= new HashMap();
+        fBuffer= new StringBuffer();
+
+        Assert.isNotNull(cast(Object)detector);
+        Assert.isNotNull(cast(Object)defaultToken);
+
+        fDetector= detector;
+        fDefaultToken= defaultToken;
+        fIgnoreCase= ignoreCase;
+    }
+
+    /**
+     * Adds a word and the token to be returned if it is detected.
+     *
+     * @param word the word this rule will search for, may not be <code>null</code>
+     * @param token the token to be returned if the word has been found, may not be <code>null</code>
+     */
+    public void addWord(String word, IToken token) {
+        //Assert.isNotNull(word);
+        Assert.isNotNull(cast(Object)token);
+
+        fWords.put(word, cast(Object)token);
+    }
+
+    /**
+     * Sets a column constraint for this rule. If set, the rule's token
+     * will only be returned if the pattern is detected starting at the
+     * specified column. If the column is smaller then 0, the column
+     * constraint is considered removed.
+     *
+     * @param column the column in which the pattern starts
+     */
+    public void setColumnConstraint(int column) {
+        if (column < 0)
+            column= UNDEFINED;
+        fColumn= column;
+    }
+
+    /*
+     * @see IRule#evaluate(ICharacterScanner)
+     */
+    public IToken evaluate(ICharacterScanner scanner) {
+        int c= scanner.read();
+        if (c !is ICharacterScanner.EOF && fDetector.isWordStart(cast(char) c)) {
+            if (fColumn is UNDEFINED || (fColumn is scanner.getColumn() - 1)) {
+
+                fBuffer.truncate(0);
+                do {
+                    fBuffer.append(cast(char) c);
+                    c= scanner.read();
+                } while (c !is ICharacterScanner.EOF && fDetector.isWordPart(cast(char) c));
+                scanner.unread();
+
+                String buffer= fBuffer.toString();
+                IToken token= cast(IToken)fWords.get(buffer);
+
+                if(fIgnoreCase) {
+                    Iterator iter= fWords.keySet().iterator();
+                    while (iter.hasNext()) {
+                        String key= stringcast(iter.next());
+                        if(buffer.equalsIgnoreCase(key)) {
+                            token= cast(IToken)fWords.get(key);
+                            break;
+                        }
+                    }
+                } else
+                    token= cast(IToken)fWords.get(buffer);
+
+                if (token !is null)
+                    return token;
+
+                if (fDefaultToken.isUndefined())
+                    unreadBuffer(scanner);
+
+                return fDefaultToken;
+            }
+        }
+
+        scanner.unread();
+        return Token.UNDEFINED;
+    }
+
+    /**
+     * Returns the characters in the buffer to the scanner.
+     *
+     * @param scanner the scanner to be used
+     */
+    protected void unreadBuffer(ICharacterScanner scanner) {
+        for (int i= fBuffer.length() - 1; i >= 0; i--)
+            scanner.unread();
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/AbstractRulerColumn.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,725 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.AbstractRulerColumn;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.events.MouseMoveListener;
+import dwt.events.PaintEvent;
+import dwt.events.PaintListener;
+import dwt.graphics.Color;
+import dwt.graphics.Font;
+import dwt.graphics.GC;
+import dwt.widgets.Canvas;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.resource.JFaceResources;
+import dwtx.jface.text.ITextListener;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.IViewportListener;
+import dwtx.jface.text.JFaceTextUtil;
+import dwtx.jface.text.TextEvent;
+
+
+/**
+ * Abstract implementation of a {@link IVerticalRulerColumn} that
+ * uses a {@link Canvas} to draw the ruler contents and which
+ * handles scrolling and mouse selection.
+ *
+ * <h3>Painting</h3>
+ * Subclasses can hook into the paint loop at three levels:
+ * <ul>
+ * <li>Override <strong>{@link #paint(GC, ILineRange)}</strong> to control the entire painting of
+ * the ruler.</li>
+ * <li>Override <strong>{@link #paintLine(GC, int, int, int, int)}</strong> to control the
+ * painting of a line.</li>
+ * <li>Leave the painting to the default implementation, but override <strong>{@link #computeBackground(int)}</strong>,
+ * <strong>{@link #computeForeground(int)}</strong> and <strong>{@link #computeText(int)}</strong>
+ * to specify the ruler appearance for a line.</li>
+ * </ul>
+ *
+ * <h3>Invalidation</h3>
+ * Subclasses may call {@link #redraw()} to mark the entire ruler as needing to be redrawn.
+ * Alternatively, use {@link #redraw(ILineRange)} to only invalidate a certain line range, for
+ * example due to changes to the display model.
+ *
+ * <h3>Configuration</h3>
+ * Subclasses can set the following properties. Setting them may trigger redrawing.
+ * <ul>
+ * <li>The {@link #setFont(Font) font} used to draw text in {@link #paintLine(GC, int, int, int, int)}.</li>
+ * <li>The horizontal {@link #setTextInset(int) text inset} for text drawn.</li>
+ * <li>The {@link #setDefaultBackground(Color) default background color} of the ruler.</li>
+ * <li>The {@link #setWidth(int) width} of the ruler.</li>
+ * </ul>
+ *
+ * @since 3.3
+ */
+public abstract class AbstractRulerColumn : IVerticalRulerColumn, IVerticalRulerInfo, IVerticalRulerInfoExtension {
+    private static const int DEFAULT_WIDTH= 12;
+    private static const int DEFAULT_TEXT_INSET= 2;
+
+    /**
+     * Handles all the mouse interaction in this line number ruler column.
+     */
+    private final class MouseHandler : MouseListener, MouseMoveListener {
+
+        /*
+         * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent)
+         */
+        public void mouseUp(MouseEvent event) {
+        }
+
+        /*
+         * @see dwt.events.MouseListener#mouseDown(dwt.events.MouseEvent)
+         */
+        public void mouseDown(MouseEvent event) {
+            fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+        }
+
+        /*
+         * @see dwt.events.MouseListener#mouseDoubleClick(dwt.events.MouseEvent)
+         */
+        public void mouseDoubleClick(MouseEvent event) {
+            fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+        }
+
+        /*
+         * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent)
+         */
+        public void mouseMove(MouseEvent event) {
+            fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+        }
+    }
+
+    /**
+     * Internal listener class that updates the ruler upon scrolling and text modifications.
+     */
+    private final class InternalListener : IViewportListener, ITextListener {
+
+        /*
+         * @see IViewportListener#viewportChanged(int)
+         */
+        public void viewportChanged(int topPixel) {
+            int delta= topPixel - fLastTopPixel;
+            if (scrollVertical(delta))
+                fCanvas.update(); // force update the invalidated regions
+        }
+
+        /*
+         * @see ITextListener#textChanged(TextEvent)
+         */
+        public void textChanged(TextEvent event) {
+            /*
+             * Redraw: - when the viewer is drawing, and any of the following - the widget was not
+             * full before the change - the widget is not full after the change - the document event
+             * was a visual modification (no document event attached) - for example when the
+             * projection changes.
+             */
+            if (!event.getViewerRedrawState())
+                return;
+
+            if (fWasShowingEntireContents || event.getDocumentEvent() is null || JFaceTextUtil.isShowingEntireContents(fStyledText))
+                redraw();
+        }
+    }
+
+    /* Listeners */
+
+    /** The viewport listener. */
+    private const InternalListener fInternalListener;
+    /** The mouse handler. */
+    private const MouseHandler fMouseHandler;
+
+    /*
+     * Implementation and context of this ruler - created and set in createControl(), disposed of in
+     * columnRemoved().
+     */
+
+    /** The parent ruler, possibly <code>null</code>. */
+    private CompositeRuler fParentRuler;
+    /** The canvas, the only widget used to draw this ruler, possibly <code>null</code>. */
+    private Canvas fCanvas;
+    /** The text viewer, possibly <code>null</code>. */
+    private ITextViewer fTextViewer;
+    /** The text viewer's widget, possibly <code>null</code>. */
+    private StyledText fStyledText;
+
+    /* State when the canvas was last painted. */
+
+    /** The text widget's top pixel when the ruler was last painted. */
+    private int fLastTopPixel= -1;
+    /** Whether the text widget was showing the entire contents when the ruler was last painted. */
+    private bool fWasShowingEntireContents= false;
+
+    /* Configuration */
+
+    /** The width of this ruler. */
+    private int fWidth= DEFAULT_WIDTH;
+    /** The text inset. */
+    private int fTextInset= DEFAULT_TEXT_INSET;
+    /** The default background color, <code>null</code> to use the text viewer's background color. */
+    private Color fBackground;
+    /** The font, <code>null</code> to use the default font. */
+    private Font fFont;
+    /** The annotation model, possibly <code>null</code>. */
+    private IAnnotationModel fModel;
+    /** The annotation hover, possibly <code>null</code>. */
+    private IAnnotationHover fHover;
+
+    /**
+     * Creates a new ruler.
+     */
+    protected this() {
+        fMouseHandler= new MouseHandler();
+        fInternalListener= new InternalListener();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerColumn#createControl(dwtx.jface.text.source.CompositeRuler,
+     *      dwt.widgets.Composite)
+     */
+    public Control createControl(CompositeRuler parentRuler, Composite parentControl) {
+        Assert.isLegal(parentControl !is null);
+        Assert.isLegal(parentRuler !is null);
+        Assert.isLegal(fParentRuler is null); // only call when not yet initialized!
+
+        fParentRuler= parentRuler;
+
+        fTextViewer= getParentRuler().getTextViewer();
+        fTextViewer.addViewportListener(fInternalListener);
+        fTextViewer.addTextListener(fInternalListener);
+
+        fStyledText= fTextViewer.getTextWidget();
+
+        fCanvas= new Canvas(parentControl, getCanvasStyle());
+
+        fCanvas.setBackground(getDefaultBackground());
+        fCanvas.setFont(getFont());
+
+        fCanvas.addPaintListener(new class()  PaintListener {
+            public void paintControl(PaintEvent event) {
+                this.outer.paintControl(event);
+            }
+        });
+
+        fCanvas.addMouseListener(fMouseHandler);
+        fCanvas.addMouseMoveListener(fMouseHandler);
+
+        return fCanvas;
+    }
+
+    /**
+     * Returns the DWT style bits used when creating the ruler canvas.
+     * <p>
+     * The default implementation returns <code>DWT.NO_BACKGROUND</code>.</p>
+     * <p>
+     * Clients may reimplement this method to create a canvas with their
+     * desired style bits.</p>
+     *
+     * @return the DWT style bits, or <code>DWT.NONE</code> if none
+     */
+    protected int getCanvasStyle() {
+        return DWT.NO_BACKGROUND;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerColumn#getControl()
+     */
+    public final Control getControl() {
+        return fCanvas;
+    }
+
+    /**
+     * The new width in pixels. The <code>DEFAULT_WIDTH</code> constant
+     * specifies the default width.
+     *
+     * @param width the new width
+     */
+    protected final void setWidth(int width) {
+        Assert.isLegal(width >= 0);
+        if (fWidth !is width) {
+            fWidth= width;
+            CompositeRuler composite= getParentRuler();
+            if (composite !is null)
+                composite.relayout();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerColumn#getWidth()
+     */
+    public final int getWidth() {
+        return fWidth;
+    }
+
+    /**
+     * Returns the parent ruler, <code>null</code> before
+     * {@link #createControl(CompositeRuler, Composite)} has been called.
+     *
+     * @return the parent ruler or <code>null</code>
+     */
+    protected final CompositeRuler getParentRuler() {
+        return fParentRuler;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @param font the font or <code>null</code> to use the default font
+     */
+    public final void setFont(Font font) {
+        if (fFont !is font) {
+            fFont= font;
+            redraw();
+        }
+    }
+
+    /**
+     * Returns the current font. If a font has not been explicitly set, the widget's font is
+     * returned.
+     *
+     * @return the font used to render text on the ruler.
+     */
+    protected final Font getFont() {
+        if (fFont !is null)
+            return fFont;
+        if (fStyledText !is null && !fStyledText.isDisposed())
+            return fStyledText.getFont();
+        return JFaceResources.getTextFont();
+    }
+
+    /**
+     * Sets the text inset (padding) used to draw text in {@link #paintLine(GC, int, int, int, int)}.
+     *
+     * @param textInset the new text inset
+     */
+    protected final void setTextInset(int textInset) {
+        if (textInset !is fTextInset) {
+            fTextInset= textInset;
+            redraw();
+        }
+    }
+
+    /**
+     * Returns the text inset for text drawn by {@link #paintLine(GC, int, int, int, int)}. The
+     * <code>DEFAULT_TEXT_INSET</code> constant specifies the default inset in pixels.
+     *
+     * @return the text inset for text
+     */
+    protected final int getTextInset() {
+        return fTextInset;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerColumn#setModel(dwtx.jface.text.source.IAnnotationModel)
+     */
+    public void setModel(IAnnotationModel model) {
+        if (fModel !is model) {
+            fModel= model;
+            redraw();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getModel()
+     */
+    public final IAnnotationModel getModel() {
+        return fModel;
+    }
+
+    /**
+     * Sets the default background color for this column. The default background is used as default
+     * implementation of {@link #computeBackground(int)} and also to paint the area of the ruler
+     * that does not correspond to any lines (when the viewport is not entirely filled with lines).
+     *
+     * @param background the default background color, <code>null</code> to use the text widget's
+     *        background
+     */
+    protected final void setDefaultBackground(Color background) {
+        if (fBackground !is background) {
+            fBackground= background;
+            if (fCanvas !is null && !fCanvas.isDisposed())
+                fCanvas.setBackground(getDefaultBackground());
+            redraw();
+        }
+    }
+
+    /**
+     * Returns the background color. May return <code>null</code> if the system is shutting down.
+     *
+     * @return the background color
+     */
+    protected final Color getDefaultBackground() {
+        if (fBackground !is null)
+            return fBackground;
+        if (fStyledText !is null && !fStyledText.isDisposed())
+            return fStyledText.getBackground();
+        Display display;
+        if (fCanvas !is null && !fCanvas.isDisposed())
+            display= fCanvas.getDisplay();
+        else
+            display= Display.getCurrent();
+        if (display !is null)
+            return display.getSystemColor(DWT.COLOR_LIST_BACKGROUND);
+        return null;
+    }
+
+    /**
+     * Sets the annotation hover.
+     *
+     * @param hover the annotation hover, <code>null</code> for no hover
+     */
+    protected final void setHover(IAnnotationHover hover) {
+        if (fHover !is hover)
+            fHover= hover;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getHover()
+     */
+    public IAnnotationHover getHover() {
+        return fHover;
+    }
+
+    /**
+     * Disposes this ruler column.
+     * <p>
+     * Subclasses may extend this method.</p>
+     * <p>
+     * Clients who created this column are responsible to call this method
+     * once the column is no longer used.</p>
+     */
+    public void dispose() {
+        if (fTextViewer !is null) {
+            fTextViewer.removeViewportListener(fInternalListener);
+            fTextViewer.removeTextListener(fInternalListener);
+            fTextViewer= null;
+        }
+
+        if (fStyledText !is null)
+            fStyledText= null;
+
+        if (fCanvas !is null) {
+            fCanvas.dispose();
+            fCanvas= null;
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerColumn#redraw()
+     */
+    public final void redraw() {
+        if (fCanvas !is null && !fCanvas.isDisposed())
+            fCanvas.redraw();
+    }
+
+    /**
+     * Marks the region covered by <code>lines</code> as needing to be redrawn.
+     *
+     * @param lines the lines to be redrawn in document coordinates
+     */
+    protected final void redraw(ILineRange lines) {
+        if (fCanvas is null || fCanvas.isDisposed())
+            return;
+        int firstModelLine= lines.getStartLine();
+        int lastModelLine= firstModelLine + lines.getNumberOfLines();
+        int firstWidgetLine= JFaceTextUtil.modelLineToWidgetLine(fTextViewer, firstModelLine);
+        int lastWidgetLine= JFaceTextUtil.modelLineToWidgetLine(fTextViewer, lastModelLine);
+
+        int from= Math.max(0, fStyledText.getLinePixel(firstWidgetLine));
+        // getLinePixel will return the last pixel of the last line if line is lineCount
+        int to= Math.min(fCanvas.getSize().y, fStyledText.getLinePixel(lastWidgetLine + 1));
+        fCanvas.redraw(0, from, fWidth, to - from, false);
+    }
+
+    /**
+     * Paints the ruler column.
+     *
+     * @param event the paint event
+     */
+    private void paintControl(PaintEvent event) {
+        if (fTextViewer is null)
+            return;
+        fWasShowingEntireContents= JFaceTextUtil.isShowingEntireContents(fStyledText);
+        fLastTopPixel= fStyledText.getTopPixel();
+
+        ILineRange lines= computeDirtyWidgetLines(event);
+        GC gc= event.gc;
+        paint(gc, lines);
+
+        if ((fCanvas.getStyle() & DWT.NO_BACKGROUND) !is 0) {
+            // fill empty area below any lines
+            int firstEmpty= Math.max(event.y, fStyledText.getLinePixel(fStyledText.getLineCount()));
+            int lastEmpty= event.y + event.height;
+            if (lastEmpty > firstEmpty) {
+                gc.setBackground(getDefaultBackground());
+                gc.fillRectangle(0, firstEmpty, getWidth(), lastEmpty - firstEmpty);
+            }
+        }
+    }
+
+    /**
+     * Computes the widget lines that need repainting given the clipping region of a paint event.
+     *
+     * @param event the paint event
+     * @return the lines in widget coordinates that need repainting
+     */
+    private ILineRange computeDirtyWidgetLines(PaintEvent event) {
+        int firstLine= fStyledText.getLineIndex(event.y);
+        int lastLine= fStyledText.getLineIndex(event.y + event.height - 1);
+        return new LineRange(firstLine, lastLine - firstLine + 1);
+    }
+
+    /**
+     * Paints the ruler. Note that <code>lines</code> reference widget line indices, and that
+     * <code>lines</code> may not cover the entire viewport, but only the lines that need to be
+     * painted. The lines may not be entirely visible.
+     * <p>
+     * Subclasses may replace or extend. The default implementation calls
+     * {@link #paintLine(GC, int, int, int, int)} for every visible line.
+     * </p>
+     *
+     * @param gc the graphics context to paint on
+     * @param lines the lines to paint in widget coordinates
+     */
+    protected void paint(GC gc, ILineRange lines) {
+        final int firstLine= lines.getStartLine();
+        final int lastLine= firstLine + lines.getNumberOfLines();
+        for (int line= firstLine; line < lastLine; line++) {
+            int modelLine= JFaceTextUtil.widgetLine2ModelLine(fTextViewer, line);
+            if (modelLine is -1)
+                continue;
+            int linePixel= fStyledText.getLinePixel(line);
+            int lineHeight= fStyledText.getLineHeight(fStyledText.getOffsetAtLine(line));
+            paintLine(gc, modelLine, line, linePixel, lineHeight);
+        }
+    }
+
+    /**
+     * Paints the ruler representation of a single line.
+     * <p>
+     * Subclasses may replace or extend. The default implementation draws the text obtained by
+     * {@link #computeText(int)} in the {@link #computeForeground(int) foreground color} and fills
+     * the entire width using the {@link #computeBackground(int) background color}. The text is
+     * drawn {@link #getTextInset()} pixels to the right of the left border.
+     * </p>
+     *
+     * @param gc the graphics context to paint on
+     * @param modelLine the model line (based on document coordinates)
+     * @param widgetLine the line in the text widget corresponding to <code>modelLine</code>
+     * @param linePixel the first y-pixel of the widget line
+     * @param lineHeight the line height in pixels
+     */
+    protected void paintLine(GC gc, int modelLine, int widgetLine, int linePixel, int lineHeight) {
+        gc.setBackground(computeBackground(modelLine));
+        gc.fillRectangle(0, linePixel, getWidth(), lineHeight);
+        String text= computeText(modelLine);
+        if (text !is null) {
+            gc.setForeground(computeForeground(modelLine));
+            gc.drawString(text, getTextInset(), linePixel, true);
+        }
+    }
+
+    /**
+     * Returns the text to be drawn for a certain line by {@link #paintLine(GC, int, int, int, int)},
+     * <code>null</code> for no text. The default implementation returns <code>null</code>.
+     * <p>
+     * Subclasses may replace or extend.
+     * </p>
+     *
+     * @param line the document line number
+     * @return the text to be drawn for the given line, <code>null</code> for no text
+     */
+    protected String computeText(int line) {
+        return null;
+    }
+
+    /**
+     * Returns the background color drawn for a certain line by
+     * {@link #paintLine(GC, int, int, int, int)}. The default implementation returns
+     * {@link #getDefaultBackground()}.
+     * <p>
+     * Subclasses may replace or extend.
+     * </p>
+     *
+     * @param line the document line number
+     * @return the background color for drawn for the given line
+     */
+    protected Color computeBackground(int line) {
+        return getDefaultBackground();
+    }
+
+    /**
+     * Returns the foreground color drawn for a certain line by
+     * {@link #paintLine(GC, int, int, int, int)}. The default implementation returns a
+     * {@link DWT#COLOR_DARK_GRAY} color.
+     * <p>
+     * Subclasses may replace or extend.
+     * </p>
+     *
+     * @param line the document line number
+     * @return the foreground color for drawn for the given line
+     */
+    protected Color computeForeground(int line) {
+        return fStyledText.getDisplay().getSystemColor(DWT.COLOR_DARK_GRAY);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfo#getLineOfLastMouseButtonActivity()
+     */
+    public final int getLineOfLastMouseButtonActivity() {
+        return getParentRuler().getLineOfLastMouseButtonActivity();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfo#toDocumentLineNumber(int)
+     */
+    public final int toDocumentLineNumber(int y_coordinate) {
+        return getParentRuler().toDocumentLineNumber(y_coordinate);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener)
+     */
+    public void addVerticalRulerListener(IVerticalRulerListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener)
+     */
+    public void removeVerticalRulerListener(IVerticalRulerListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Scrolls the canvas vertically (adapted from
+     * {@linkplain StyledText StyledText.scrollVertical()}).
+     *
+     * @param pixels the number of pixels to scroll (negative to scroll upwards)
+     * @return <code>true</code> if the widget was scrolled, <code>false</code> if the widget
+     *         was not scrolled
+     */
+    private bool scrollVertical(int pixels) {
+        if (pixels is 0 || fCanvas is null || fCanvas.isDisposed())
+            return false;
+
+        final int width= getWidth();
+        final int clientAreaHeight= fStyledText.getClientArea().height;
+        final int topMargin= 0;
+        final int leftMargin= 0;
+        final int bottomMargin= 0;
+
+        if (pixels > 0) {
+            // downwards scrolling - content moves upwards
+            int sourceY= topMargin + pixels;
+            int scrollHeight= clientAreaHeight - sourceY - bottomMargin;
+            if (scrollHeight > 0)
+                // scroll recycled area
+                fCanvas.scroll(leftMargin, topMargin, leftMargin, sourceY, width, scrollHeight, true);
+            if (sourceY > scrollHeight) {
+                // redraw in-between area
+                int redrawY= Math.max(0, topMargin + scrollHeight);
+                int redrawHeight= Math.min(clientAreaHeight, pixels - scrollHeight);
+                fCanvas.redraw(leftMargin, redrawY, width, redrawHeight, true);
+            }
+        } else {
+            // upwards scrolling - content moves downwards
+            int destinationY= topMargin - pixels;
+            int scrollHeight= clientAreaHeight - destinationY - bottomMargin;
+            if (scrollHeight > 0)
+                // scroll recycled area
+                fCanvas.scroll(leftMargin, destinationY, leftMargin, topMargin, width, scrollHeight, true);
+            if (destinationY > scrollHeight) {
+                // redraw in-between area
+                int redrawY= Math.max(0, topMargin + scrollHeight);
+                int redrawHeight= Math.min(clientAreaHeight, -pixels - scrollHeight);
+                fCanvas.redraw(leftMargin, redrawY, width, redrawHeight, true);
+            }
+        }
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/Annotation.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,225 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.Annotation;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Annotation managed by an
+ * {@link dwtx.jface.text.source.IAnnotationModel}.
+ * <p>
+ * Annotations are typed, can have an associated text and can be marked as persistent and
+ * deleted. Annotations which are not explicitly initialized with an annotation
+ * type are of type <code>"dwtx.text.annotation.unknown"</code>.
+ */
+public class Annotation {
+
+    /**
+     * Constant for unknown annotation types.<p>
+     * Value: <code>"dwtx.text.annotation.unknown"</code>
+     * @since 3.0
+     */
+    public const static String TYPE_UNKNOWN= "dwtx.text.annotation.unknown";  //$NON-NLS-1$
+
+
+    /**
+     * The type of this annotation.
+     * @since 3.0
+     */
+    private String fType;
+    /**
+     * Indicates whether this annotation is persistent or not.
+     * @since 3.0
+     */
+    private bool fIsPersistent= false;
+    /**
+     * Indicates whether this annotation is marked as deleted or not.
+     * @since 3.0
+     */
+    private bool fMarkedAsDeleted= false;
+    /**
+     * The text associated with this annotation.
+     * @since 3.0
+     */
+    private String fText;
+
+
+    /**
+     * Creates a new annotation that is not persistent and type less.
+     */
+    protected this() {
+        this(null, false, null);
+    }
+
+    /**
+     * Creates a new annotation with the given properties.
+     *
+     * @param type the unique name of this annotation type
+     * @param isPersistent <code>true</code> if this annotation is
+     *            persistent, <code>false</code> otherwise
+     * @param text the text associated with this annotation
+     * @since 3.0
+     */
+    public this(String type, bool isPersistent, String text) {
+        fType= type;
+        fIsPersistent= isPersistent;
+        fText= text;
+    }
+
+    /**
+     * Creates a new annotation with the given persistence state.
+     *
+     * @param isPersistent <code>true</code> if persistent, <code>false</code> otherwise
+     * @since 3.0
+     */
+    public this(bool isPersistent) {
+        this(null, isPersistent, null);
+    }
+
+    /**
+     * Returns whether this annotation is persistent.
+     *
+     * @return <code>true</code> if this annotation is persistent, <code>false</code>
+     *         otherwise
+     * @since 3.0
+     */
+    public bool isPersistent() {
+        return fIsPersistent;
+    }
+
+    /**
+     * Sets the type of this annotation.
+     *
+     * @param type the annotation type
+     * @since 3.0
+     */
+    public void setType(String type) {
+        fType= type;
+    }
+
+    /**
+     * Returns the type of the annotation.
+     *
+     * @return the type of the annotation
+     * @since 3.0
+     */
+    public String getType() {
+        return fType is null ? TYPE_UNKNOWN : fType;
+    }
+
+    /**
+     * Marks this annotation deleted according to the value of the
+     * <code>deleted</code> parameter.
+     *
+     * @param deleted <code>true</code> if annotation should be marked as deleted
+     * @since 3.0
+     */
+    public void markDeleted(bool deleted) {
+        fMarkedAsDeleted= deleted;
+    }
+
+    /**
+     * Returns whether this annotation is marked as deleted.
+     *
+     * @return <code>true</code> if annotation is marked as deleted, <code>false</code>
+     *         otherwise
+     * @since 3.0
+     */
+    public bool isMarkedDeleted() {
+        return fMarkedAsDeleted;
+    }
+
+    /**
+     * Sets the text associated with this annotation.
+     *
+     * @param text the text associated with this annotation
+     * @since 3.0
+     */
+    public void setText(String text) {
+        fText= text;
+    }
+
+    /**
+     * Returns the text associated with this annotation.
+     *
+     * @return the text associated with this annotation or <code>null</code>
+     * @since 3.0
+     */
+    public String getText() {
+        return fText;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/AnnotationBarHoverManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,858 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.AnnotationBarHoverManager;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.ControlEvent;
+import dwt.events.ControlListener;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.events.MouseMoveListener;
+import dwt.events.MouseTrackAdapter;
+import dwt.events.ShellEvent;
+import dwt.events.ShellListener;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Listener;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.internal.text.InformationControlReplacer;
+import dwtx.jface.internal.text.InternalAccessor;
+import dwtx.jface.text.AbstractHoverInformationControlManager;
+import dwtx.jface.text.AbstractInformationControlManager;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.JFaceTextUtil;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextUtilities;
+import dwtx.jface.text.ITextViewerExtension8;
+
+
+/**
+ * This manager controls the layout, content, and visibility of an information
+ * control in reaction to mouse hover events issued by the vertical ruler of a
+ * source viewer.
+ * @since 2.0
+ */
+public class AnnotationBarHoverManager : AbstractHoverInformationControlManager {
+
+    /**
+     * The information control closer for the hover information. Closes the information control as soon as the mouse pointer leaves the subject area, a mouse button is pressed, the user presses a key, or the subject control is resized or moved.
+     *
+     * @since 3.0
+     * @deprecated As of 3.4, no longer used as closer from super class is used
+     */
+    protected class Closer : MouseTrackAdapter , IInformationControlCloser, MouseListener, MouseMoveListener, ControlListener, KeyListener, DisposeListener, ShellListener, Listener {
+
+        /** The closer's subject control */
+        private Control fSubjectControl;
+        /** The subject area */
+        private Rectangle fSubjectArea;
+        /** Indicates whether this closer is active */
+        private bool fIsActive= false;
+        /** The information control. */
+        private IInformationControl fInformationControlToClose;
+        /**
+         * <code>true</code> if a wheel handler is installed.
+         * @since 3.2
+         */
+        private bool fHasWheelFilter= false;
+        /**
+         * The cached display.
+         * @since 3.2
+         */
+        private Display fDisplay;
+
+
+        /**
+         * Creates a new information control closer.
+         */
+        public this() {
+        }
+
+        /*
+         * @see IInformationControlCloser#setSubjectControl(Control)
+         */
+        public void setSubjectControl(Control control) {
+            fSubjectControl= control;
+        }
+
+        /*
+         * @see IInformationControlCloser#setHoverControl(IHoverControl)
+         */
+        public void setInformationControl(IInformationControl control) {
+            fInformationControlToClose= control;
+        }
+
+        /*
+         * @see IInformationControlCloser#start(Rectangle)
+         */
+        public void start(Rectangle subjectArea) {
+
+            if (fIsActive) return;
+            fIsActive= true;
+
+            fSubjectArea= subjectArea;
+
+            fInformationControlToClose.addDisposeListener(this);
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
+                fSubjectControl.addMouseListener(this);
+                fSubjectControl.addMouseMoveListener(this);
+                fSubjectControl.addMouseTrackListener(this);
+                fSubjectControl.getShell().addShellListener(this);
+                fSubjectControl.addControlListener(this);
+                fSubjectControl.addKeyListener(this);
+
+                fDisplay= fSubjectControl.getDisplay();
+                if (!fDisplay.isDisposed() && fHideOnMouseWheel) {
+                    fHasWheelFilter= true;
+                    fDisplay.addFilter(DWT.MouseWheel, this);
+                }
+            }
+        }
+
+        /*
+         * @see IInformationControlCloser#stop()
+         */
+        public void stop() {
+
+            if (!fIsActive)
+                return;
+            fIsActive= false;
+
+            if (fSubjectControl !is null && !fSubjectControl.isDisposed()) {
+                fSubjectControl.removeMouseListener(this);
+                fSubjectControl.removeMouseMoveListener(this);
+                fSubjectControl.removeMouseTrackListener(this);
+                fSubjectControl.getShell().removeShellListener(this);
+                fSubjectControl.removeControlListener(this);
+                fSubjectControl.removeKeyListener(this);
+            }
+
+            if (fDisplay !is null && !fDisplay.isDisposed() && fHasWheelFilter)
+                fDisplay.removeFilter(DWT.MouseWheel, this);
+            fHasWheelFilter= false;
+
+            fDisplay= null;
+
+        }
+
+        /**
+         * Stops the information control and if <code>delayRestart</code> is set allows restart only after a certain delay.
+         *
+         * @param delayRestart <code>true</code> if restart should be delayed
+         * @deprecated As of 3.4, replaced by {@link #stop()}. Note that <code>delayRestart</code> was never honored.
+         */
+        protected void stop(bool delayRestart) {
+            stop();
+        }
+
+        /*
+         * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent)
+         */
+        public void mouseMove(MouseEvent event) {
+            if (!fSubjectArea.contains(event.x, event.y))
+                hideInformationControl();
+        }
+
+        /*
+         * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent)
+         */
+        public void mouseUp(MouseEvent event) {
+        }
+
+        /*
+         * @see MouseListener#mouseDown(MouseEvent)
+         */
+        public void mouseDown(MouseEvent event) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see MouseListener#mouseDoubleClick(MouseEvent)
+         */
+        public void mouseDoubleClick(MouseEvent event) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see dwt.widgets.Listener#handleEvent(dwt.widgets.Event)
+         * @since 3.2
+         */
+        public void handleEvent(Event event) {
+            if (event.type is DWT.MouseWheel)
+                hideInformationControl();
+        }
+
+        /*
+         * @see MouseTrackAdapter#mouseExit(MouseEvent)
+         */
+        public void mouseExit(MouseEvent event) {
+            if (!fAllowMouseExit)
+                hideInformationControl();
+        }
+
+        /*
+         * @see ControlListener#controlResized(ControlEvent)
+         */
+        public void controlResized(ControlEvent event) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see ControlListener#controlMoved(ControlEvent)
+         */
+        public void controlMoved(ControlEvent event) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see KeyListener#keyReleased(KeyEvent)
+         */
+        public void keyReleased(KeyEvent event) {
+        }
+
+        /*
+         * @see KeyListener#keyPressed(KeyEvent)
+         */
+        public void keyPressed(KeyEvent event) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see dwt.events.ShellListener#shellActivated(dwt.events.ShellEvent)
+         * @since 3.1
+         */
+        public void shellActivated(ShellEvent e) {
+        }
+
+        /*
+         * @see dwt.events.ShellListener#shellClosed(dwt.events.ShellEvent)
+         * @since 3.1
+         */
+        public void shellClosed(ShellEvent e) {
+        }
+
+        /*
+         * @see dwt.events.ShellListener#shellDeactivated(dwt.events.ShellEvent)
+         * @since 3.1
+         */
+        public void shellDeactivated(ShellEvent e) {
+            hideInformationControl();
+        }
+
+        /*
+         * @see dwt.events.ShellListener#shellDeiconified(dwt.events.ShellEvent)
+         * @since 3.1
+         */
+        public void shellDeiconified(ShellEvent e) {
+        }
+
+        /*
+         * @see dwt.events.ShellListener#shellIconified(dwt.events.ShellEvent)
+         * @since 3.1
+         */
+        public void shellIconified(ShellEvent e) {
+        }
+
+        /*
+         * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent)
+         */
+        public void widgetDisposed(DisposeEvent e) {
+            hideInformationControl();
+        }
+    }
+
+    /** The source viewer the manager is connected to */
+    private ISourceViewer fSourceViewer;
+    /** The vertical ruler the manager is registered with */
+    private IVerticalRulerInfo fVerticalRulerInfo;
+    /** The annotation hover the manager uses to retrieve the information to display. Can be <code>null</code>. */
+    private IAnnotationHover fAnnotationHover;
+    /**
+     * Indicates whether the mouse cursor is allowed to leave the subject area without closing the hover.
+     * @since 3.0
+     */
+    protected bool fAllowMouseExit= false;
+    /**
+     * Whether we should hide the over on mouse wheel action.
+     *
+     * @since 3.2
+     */
+    private bool fHideOnMouseWheel= true;
+
+    /**
+     * The current annotation hover.
+     * @since 3.2
+     */
+    private IAnnotationHover fCurrentHover;
+
+    /**
+     * Creates an annotation hover manager with the given parameters. In addition,
+     * the hovers anchor is RIGHT and the margin is 5 points to the right.
+     *
+     * @param sourceViewer the source viewer this manager connects to
+     * @param ruler the vertical ruler this manager connects to
+     * @param annotationHover the annotation hover providing the information to be displayed
+     * @param creator the information control creator
+     * @deprecated As of 2.1, replaced by {@link AnnotationBarHoverManager#AnnotationBarHoverManager(IVerticalRulerInfo, ISourceViewer, IAnnotationHover, IInformationControlCreator)}
+     */
+    public this(ISourceViewer sourceViewer, IVerticalRuler ruler, IAnnotationHover annotationHover, IInformationControlCreator creator) {
+        this(ruler, sourceViewer, annotationHover, creator);
+    }
+
+    /**
+     * Creates an annotation hover manager with the given parameters. In addition,
+     * the hovers anchor is RIGHT and the margin is 5 points to the right.
+     *
+     * @param rulerInfo the vertical ruler this manager connects to
+     * @param sourceViewer the source viewer this manager connects to
+     * @param annotationHover the annotation hover providing the information to be displayed or <code>null</code> if none
+     * @param creator the information control creator
+     * @since 2.1
+     */
+    public this(IVerticalRulerInfo rulerInfo, ISourceViewer sourceViewer, IAnnotationHover annotationHover, IInformationControlCreator creator) {
+        super(creator);
+
+        Assert.isNotNull(cast(Object)sourceViewer);
+
+        fSourceViewer= sourceViewer;
+        fVerticalRulerInfo= rulerInfo;
+        fAnnotationHover= annotationHover;
+
+        setAnchor(ANCHOR_RIGHT);
+        setMargins(5, 0);
+        // use closer from super class
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#computeInformation()
+     */
+    protected void computeInformation() {
+        fAllowMouseExit= false;
+        MouseEvent event= getHoverEvent();
+        IAnnotationHover hover= getHover(event);
+        if (hover is null) {
+            setInformation(cast(Object)null, null);
+            return;
+        }
+
+        int line= getHoverLine(event);
+
+        if ( cast(IAnnotationHoverExtension)hover ) {
+            IAnnotationHoverExtension extension= cast(IAnnotationHoverExtension) hover;
+            ILineRange range= extension.getHoverLineRange(fSourceViewer, line);
+            setCustomInformationControlCreator(extension.getHoverControlCreator());
+            range= adaptLineRange(range, line);
+            if (range !is null)
+                setInformation(extension.getHoverInfo(fSourceViewer, range, computeNumberOfVisibleLines()), computeArea(range));
+            else
+                setInformation(cast(Object)null, null);
+
+        } else {
+            setCustomInformationControlCreator(null);
+            setInformation(hover.getHoverInfo(fSourceViewer, line), computeArea(line));
+        }
+
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#showInformationControl(dwt.graphics.Rectangle)
+     * @since 3.2
+     */
+    protected void showInformationControl(Rectangle subjectArea) {
+        super.showInformationControl(subjectArea);
+        fCurrentHover= getHover(getHoverEvent());
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#hideInformationControl()
+     * @since 3.2
+     */
+    protected void hideInformationControl() {
+        fCurrentHover= null;
+        super.hideInformationControl();
+    }
+
+    /**
+     * Adapts a given line range so that the result is a line range that does
+     * not overlap with any collapsed region and fits into the view port of the
+     * attached viewer.
+     *
+     * @param lineRange the original line range
+     * @param line the anchor line
+     * @return the adapted line range
+     * @since 3.0
+     */
+    private ILineRange adaptLineRange(ILineRange lineRange, int line) {
+        if (lineRange !is null) {
+            lineRange= adaptLineRangeToFolding(lineRange, line);
+            if (lineRange !is null)
+                return adaptLineRangeToViewport(lineRange);
+        }
+        return null;
+    }
+
+    /**
+     * Adapts a given line range so that the result is a line range that does
+     * not overlap with any collapsed region of the attached viewer.
+     *
+     * @param lineRange the original line range
+     * @param line the anchor line
+     * @return the adapted line range
+     * @since 3.0
+     */
+    private ILineRange adaptLineRangeToFolding(ILineRange lineRange, int line) {
+
+        if ( cast(ITextViewerExtension5)fSourceViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) fSourceViewer;
+
+            try {
+                IRegion region= convertToRegion(lineRange);
+                IRegion[] coverage= extension.getCoveredModelRanges(region);
+                if (coverage !is null && coverage.length > 0) {
+                    IRegion container= findRegionContainingLine(coverage, line);
+                    if (container !is null)
+                        return convertToLineRange(container);
+                }
+
+            } catch (BadLocationException x) {
+            }
+
+            return null;
+        }
+
+        return lineRange;
+    }
+
+    /**
+     * Adapts a given line range so that the result is a line range that fits
+     * into the view port of the attached viewer.
+     *
+     * @param lineRange the original line range
+     * @return the adapted line range
+     * @since 3.0
+     */
+    private ILineRange adaptLineRangeToViewport(ILineRange lineRange) {
+
+        try {
+            StyledText text= fSourceViewer.getTextWidget();
+
+            int topLine= text.getTopIndex();
+            int rangeTopLine= getWidgetLineNumber(lineRange.getStartLine());
+            int topDelta= Math.max(topLine - rangeTopLine, 0);
+
+            Rectangle size= text.getClientArea();
+            Rectangle trim= text.computeTrim(0, 0, 0, 0);
+            int height= size.height - trim.height;
+
+            int lines= JFaceTextUtil.getLineIndex(text, height) - text.getTopIndex();
+
+            int bottomLine= topLine + lines;
+
+            int rangeBottomLine= getWidgetLineNumber(lineRange.getStartLine() + lineRange.getNumberOfLines() - 1);
+            int bottomDelta= Math.max(rangeBottomLine - bottomLine, 0);
+
+            return new LineRange(lineRange.getStartLine() + topDelta, lineRange.getNumberOfLines() - bottomDelta - topDelta);
+
+        } catch (BadLocationException ex) {
+        }
+
+        return null;
+    }
+
+    /**
+     * Converts a line range into a character range.
+     *
+     * @param lineRange the line range
+     * @return the corresponding character range
+     * @throws BadLocationException in case the given line range is invalid
+     */
+    private IRegion convertToRegion(ILineRange lineRange)  {
+        IDocument document= fSourceViewer.getDocument();
+        int startOffset= document.getLineOffset(lineRange.getStartLine());
+        int endLine= lineRange.getStartLine() + Math.max(0, lineRange.getNumberOfLines() - 1);
+        IRegion lineInfo= document.getLineInformation(endLine);
+        int endOffset= lineInfo.getOffset() + lineInfo.getLength();
+        return new Region(startOffset, endOffset - startOffset);
+    }
+
+    /**
+     * Returns the region out of the given set that contains the given line or
+     * <code>null</code>.
+     *
+     * @param regions the set of regions
+     * @param line the line
+     * @return the region of the set that contains the line
+     * @throws BadLocationException in case line is invalid
+     */
+    private IRegion findRegionContainingLine(IRegion[] regions, int line)  {
+        IDocument document= fSourceViewer.getDocument();
+        IRegion lineInfo= document.getLineInformation(line);
+        for (int i= 0; i < regions.length; i++) {
+            if (TextUtilities.overlaps(regions[i], lineInfo))
+                return regions[i];
+        }
+        return null;
+    }
+
+    /**
+     * Converts a given character region into a line range.
+     *
+     * @param region the character region
+     * @return the corresponding line range
+     * @throws BadLocationException in case the given region in invalid
+     */
+    private ILineRange convertToLineRange(IRegion region)  {
+        IDocument document= fSourceViewer.getDocument();
+        int startLine= document.getLineOfOffset(region.getOffset());
+        int endLine= document.getLineOfOffset(region.getOffset() + region.getLength());
+        return new LineRange(startLine, endLine - startLine + 1);
+    }
+
+    /**
+     * Returns the visible area of the vertical ruler covered by the given line
+     * range.
+     *
+     * @param lineRange the line range
+     * @return the visible area
+     */
+    private Rectangle computeArea(ILineRange lineRange) {
+        try {
+            StyledText text= fSourceViewer.getTextWidget();
+            final int startLine= getWidgetLineNumber(lineRange.getStartLine());
+            int y= JFaceTextUtil.computeLineHeight(text, 0, startLine, startLine) - text.getTopPixel();
+            int height= JFaceTextUtil.computeLineHeight(text, startLine, startLine + lineRange.getNumberOfLines(), lineRange.getNumberOfLines());
+            Point size= fVerticalRulerInfo.getControl().getSize();
+            return new Rectangle(0, y, size.x, height);
+        } catch (BadLocationException x) {
+        }
+        return null;
+    }
+
+    /**
+     * Returns the number of the currently visible lines.
+     *
+     * @return the number of the currently visible lines
+     * @deprecated to avoid deprecation warning
+     */
+    private int computeNumberOfVisibleLines() {
+        // Hack to reduce amount of copied code.
+        return LineNumberRulerColumn.getVisibleLinesInViewport(fSourceViewer.getTextWidget());
+    }
+
+    /**
+     * Determines the hover to be used to display information based on the source of the
+     * mouse hover event. If <code>fVerticalRulerInfo</code> is not a composite ruler, the
+     * standard hover is returned.
+     *
+     * @param event the source of the mouse hover event
+     * @return the hover depending on <code>source</code>, or <code>fAnnotationHover</code> if none can be found.
+     * @since 3.0
+     */
+    private IAnnotationHover getHover(MouseEvent event) {
+        if (event is null || event.getSource() is null)
+            return fAnnotationHover;
+
+        if ( cast(CompositeRuler)fVerticalRulerInfo ) {
+            CompositeRuler comp= cast(CompositeRuler) fVerticalRulerInfo;
+            for (Iterator it= comp.getDecoratorIterator(); it.hasNext();) {
+                Object o= it.next();
+                if ( cast(IVerticalRulerInfoExtension)o  && cast(IVerticalRulerInfo)o ) {
+                    if ((cast(IVerticalRulerInfo) o).getControl() is event.getSource()) {
+                        IAnnotationHover hover= (cast(IVerticalRulerInfoExtension) o).getHover();
+                        if (hover !is null)
+                            return hover;
+                    }
+                }
+            }
+        }
+        return fAnnotationHover;
+    }
+
+    /**
+     * Returns the line of interest deduced from the mouse hover event.
+     *
+     * @param event a mouse hover event that triggered hovering
+     * @return the document model line number on which the hover event occurred or <code>-1</code> if there is no event
+     * @since 3.0
+     */
+    private int getHoverLine(MouseEvent event) {
+        return event is null ? -1 : fVerticalRulerInfo.toDocumentLineNumber(event.y);
+    }
+
+    /**
+     * Returns for the widget line number for the given document line number.
+     *
+     * @param line the absolute line number
+     * @return the line number relative to the viewer's visible region
+     * @throws BadLocationException if <code>line</code> is not valid in the viewer's document
+     */
+    private int getWidgetLineNumber(int line)  {
+        if ( cast(ITextViewerExtension5)fSourceViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) fSourceViewer;
+            return extension.modelLine2WidgetLine(line);
+        }
+
+        IRegion region= fSourceViewer.getVisibleRegion();
+        int firstLine= fSourceViewer.getDocument().getLineOfOffset(region.getOffset());
+        return line - firstLine;
+    }
+
+    /**
+     * Determines graphical area covered by the given line.
+     *
+     * @param line the number of the line in the viewer whose graphical extend in the vertical ruler must be computed
+     * @return the graphical extend of the given line
+     */
+    private Rectangle computeArea(int line) {
+        try {
+            StyledText text= fSourceViewer.getTextWidget();
+            int widgetLine= getWidgetLineNumber(line);
+            int y= JFaceTextUtil.computeLineHeight(text, 0, widgetLine, widgetLine) - text.getTopPixel();
+            Point size= fVerticalRulerInfo.getControl().getSize();
+            return new Rectangle(0, y, size.x, text.getLineHeight(text.getOffsetAtLine(widgetLine)));
+        } catch (IllegalArgumentException ex) {
+        } catch (BadLocationException ex) {
+        }
+        return null;
+    }
+
+    /**
+     * Returns the annotation hover for this hover manager.
+     *
+     * @return the annotation hover for this hover manager or <code>null</code> if none
+     * @since 2.1
+     */
+    protected IAnnotationHover getAnnotationHover() {
+        return fAnnotationHover;
+    }
+
+    /**
+     * Returns the source viewer for this hover manager.
+     *
+     * @return the source viewer for this hover manager
+     * @since 2.1
+     */
+    protected ISourceViewer getSourceViewer() {
+        return fSourceViewer;
+    }
+
+    /**
+     * Returns the vertical ruler info for this hover manager
+     *
+     * @return the vertical ruler info for this hover manager
+     * @since 2.1
+     */
+    protected IVerticalRulerInfo getVerticalRulerInfo() {
+        return fVerticalRulerInfo;
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#computeSizeConstraints(dwt.widgets.Control, dwt.graphics.Rectangle, dwtx.jface.text.IInformationControl)
+     * @since 3.0
+     */
+    protected Point computeSizeConstraints(Control subjectControl, Rectangle subjectArea, IInformationControl informationControl) {
+
+        Point constraints= super.computeSizeConstraints(subjectControl, subjectArea, informationControl);
+
+        // make as big as text area, if possible
+        StyledText styledText= fSourceViewer.getTextWidget();
+        if (styledText !is null) {
+            Rectangle r= styledText.getClientArea();
+            if (r !is null) {
+                constraints.x= r.width;
+                constraints.y= r.height;
+            }
+        }
+
+        return constraints;
+    }
+
+    /*
+     * @see dwtx.jface.text.AbstractInformationControlManager#computeLocation(dwt.graphics.Rectangle, dwt.graphics.Point, dwtx.jface.text.AbstractInformationControlManager.Anchor)
+     * @since 3.0
+     */
+    protected Point computeLocation(Rectangle subjectArea, Point controlSize, Anchor anchor) {
+        MouseEvent event= getHoverEvent();
+        IAnnotationHover hover= getHover(event);
+
+        bool allowMouseExit= false;
+        if ( cast(IAnnotationHoverExtension)hover ) {
+            IAnnotationHoverExtension extension= cast(IAnnotationHoverExtension) hover;
+            allowMouseExit= extension.canHandleMouseCursor();
+        }
+        bool hideOnMouseWheel= true;
+        if ( cast(IAnnotationHoverExtension2)hover ) {
+            IAnnotationHoverExtension2 extension= cast(IAnnotationHoverExtension2) hover;
+            hideOnMouseWheel= !extension.canHandleMouseWheel();
+        }
+        fHideOnMouseWheel= hideOnMouseWheel;
+
+        if (allowMouseExit) {
+            fAllowMouseExit= true;
+
+            Control subjectControl= getSubjectControl();
+            // return a location that just overlaps the annotation on the bar
+            if (anchor is AbstractInformationControlManager.ANCHOR_RIGHT)
+                return subjectControl.toDisplay(subjectArea.x - 4, subjectArea.y - 2);
+            else if (anchor is AbstractInformationControlManager.ANCHOR_LEFT)
+                return subjectControl.toDisplay(subjectArea.x + subjectArea.width - controlSize.x + 4, subjectArea.y - 2);
+        }
+
+        fAllowMouseExit= false;
+        return super.computeLocation(subjectArea, controlSize, anchor);
+    }
+
+    /**
+     * Returns the currently shown annotation hover or <code>null</code> if none
+     * hover is shown.
+     *
+     * @return the currently shown annotation hover or <code>null</code>
+     * @since 3.2
+     */
+    public IAnnotationHover getCurrentAnnotationHover() {
+        return fCurrentHover;
+    }
+
+    /**
+     * Returns an adapter that gives access to internal methods.
+     * <p>
+     * <strong>Note:</strong> This method is not intended to be referenced or overridden by clients.
+     * </p>
+     *
+     * @return the replaceable information control accessor
+     * @since 3.4
+     * @noreference This method is not intended to be referenced by clients.
+     * @nooverride This method is not intended to be re-implemented or extended by clients.
+     */
+    public InternalAccessor getInternalAccessor() {
+        return new class()  InternalAccessor {
+            public IInformationControl getCurrentInformationControl() {
+                return this.outer.superGetInternalAccessor().getCurrentInformationControl();
+            }
+
+            public void setInformationControlReplacer(InformationControlReplacer replacer) {
+                this.outer.superGetInternalAccessor().setInformationControlReplacer(replacer);
+            }
+
+            public InformationControlReplacer getInformationControlReplacer() {
+                return this.outer.superGetInternalAccessor().getInformationControlReplacer();
+            }
+
+            public bool canReplace(IInformationControl control) {
+                return this.outer.superGetInternalAccessor().canReplace(control);
+            }
+
+            public bool isReplaceInProgress() {
+                return this.outer.superGetInternalAccessor().isReplaceInProgress();
+            }
+
+            public void replaceInformationControl(bool takeFocus) {
+                this.outer.superGetInternalAccessor().replaceInformationControl(takeFocus);
+            }
+
+            public void cropToClosestMonitor(Rectangle bounds) {
+                this.outer.superGetInternalAccessor().cropToClosestMonitor(bounds);
+            }
+
+            public void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode) {
+                this.outer.superGetInternalAccessor().setHoverEnrichMode(mode);
+            }
+
+            public bool getAllowMouseExit() {
+                return fAllowMouseExit;
+            }
+        };
+    }
+    private InternalAccessor superGetInternalAccessor() {
+        return super.getInternalAccessor();
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/AnnotationColumn.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.source.AnnotationColumn;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * @deprecated use {@link dwtx.jface.text.source.AnnotationRulerColumn} instead.
+ * @since 2.0
+ */
+public final class AnnotationColumn : AnnotationRulerColumn {
+
+    /**
+     * Creates a new <code>AnnotationColumn</code> of the given width.
+     *
+     * @param width the width of this column
+     * @deprecated
+     */
+    public this(int width) {
+        super(width);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/AnnotationMap.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,291 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.AnnotationMap;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+
+
+/**
+ * Internal implementation of {@link dwtx.jface.text.source.IAnnotationMap}.
+ *
+ * @since 3.0
+ */
+class AnnotationMap : IAnnotationMap {
+
+    /**
+     * The lock object used to synchronize the operations explicitly defined by
+     * <code>IAnnotationMap</code>
+     */
+    private Object fLockObject;
+    /**
+     * The internal lock object used if <code>fLockObject</code> is <code>null</code>.
+     * @since 3.2
+     */
+    private const Object fInternalLockObject;
+
+    /** The map holding the annotations */
+    private Map fInternalMap;
+
+    /**
+     * Creates a new annotation map with the given capacity.
+     *
+     * @param capacity the capacity
+     */
+    public this(int capacity) {
+        fInternalLockObject= new Object();
+        fInternalMap= new HashMap(capacity);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ISynchronizable#setLockObject(java.lang.Object)
+     */
+    public synchronized void setLockObject(Object lockObject) {
+        fLockObject= lockObject;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ISynchronizable#getLockObject()
+     */
+    public synchronized Object getLockObject() {
+        if (fLockObject is null)
+            return fInternalLockObject;
+        return fLockObject;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationMap#valuesIterator()
+     */
+    public Iterator valuesIterator() {
+        synchronized (getLockObject()) {
+            return (new ArrayList(fInternalMap.values())).iterator();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationMap#keySetIterator()
+     */
+    public Iterator keySetIterator() {
+        synchronized (getLockObject()) {
+            return (new ArrayList(fInternalMap.keySet())).iterator();
+        }
+    }
+
+    /*
+     * @see java.util.Map#containsKey(java.lang.Object)
+     */
+    public bool containsKey(Object annotation) {
+        synchronized (getLockObject()) {
+            return fInternalMap.containsKey(annotation);
+        }
+    }
+
+    /*
+     * @see java.util.Map#put(java.lang.Object, java.lang.Object)
+     */
+    public Object put(Object annotation, Object position) {
+        synchronized (getLockObject()) {
+            return fInternalMap.put(annotation, position);
+        }
+    }
+
+    /*
+     * @see java.util.Map#get(java.lang.Object)
+     */
+    public Object get(Object annotation) {
+        synchronized (getLockObject()) {
+            return fInternalMap.get(annotation);
+        }
+    }
+
+    /*
+     * @see java.util.Map#clear()
+     */
+    public void clear() {
+        synchronized (getLockObject()) {
+            fInternalMap.clear();
+        }
+    }
+
+    /*
+     * @see java.util.Map#remove(java.lang.Object)
+     */
+    public Object remove(Object annotation) {
+        synchronized (getLockObject()) {
+            return fInternalMap.remove(annotation);
+        }
+    }
+
+    /*
+     * @see java.util.Map#size()
+     */
+    public int size() {
+        synchronized (getLockObject()) {
+            return fInternalMap.size();
+        }
+    }
+
+    /*
+     * @see java.util.Map#isEmpty()
+     */
+    public bool isEmpty() {
+        synchronized (getLockObject()) {
+            return fInternalMap.isEmpty();
+        }
+    }
+
+    /*
+     * @see java.util.Map#containsValue(java.lang.Object)
+     */
+    public bool containsValue(Object value) {
+        synchronized(getLockObject()) {
+            return fInternalMap.containsValue(value);
+        }
+    }
+
+    /*
+     * @see java.util.Map#putAll(java.util.Map)
+     */
+    public void putAll(Map map) {
+        synchronized (getLockObject()) {
+            fInternalMap.putAll(map);
+        }
+    }
+
+    /*
+     * @see IAnnotationMap#entrySet()
+     */
+    public Set entrySet() {
+        synchronized (getLockObject()) {
+            return fInternalMap.entrySet();
+        }
+    }
+
+    /*
+     * @see IAnnotationMap#keySet()
+     */
+    public Set keySet() {
+        synchronized (getLockObject()) {
+            return fInternalMap.keySet();
+        }
+    }
+
+    /*
+     * @see IAnnotationMap#values()
+     */
+    public Collection values() {
+        synchronized (getLockObject()) {
+            return fInternalMap.values();
+        }
+    }
+
+    /// DWT extension of Collection interfaces
+
+    public bool containsKey(String key) {
+        return containsKey(stringcast(key));
+    }
+    public Object get(String key) {
+        return get(stringcast(key));
+    }
+    public Object put(String key, String value) {
+        return put(stringcast(key), stringcast(value));
+    }
+    public Object put(Object key, String value) {
+        return put(key, stringcast(value));
+    }
+    public Object put(String key, Object value) {
+        return put(stringcast(key), value);
+    }
+    public Object remove(String key) {
+        return remove(stringcast(key));
+    }
+    public int opApply (int delegate(ref Object value) dg){
+        implMissing(__FILE__,__LINE__);
+        return 0;
+    }
+    public int opApply (int delegate(ref Object key, ref Object value) dg){
+        implMissing(__FILE__,__LINE__);
+        return 0;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/AnnotationModel.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1059 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.AnnotationModel;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.core.Exception;
+import tango.core.Thread;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.AbstractDocument;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentListener;
+import dwtx.jface.text.ISynchronizable;
+import dwtx.jface.text.Position;
+
+
+/**
+ * Standard implementation of {@link IAnnotationModel} and its extension
+ * interfaces. This class can directly be used by clients. Subclasses may adapt
+ * this annotation model to other existing annotation mechanisms. This class
+ * also implements {@link dwtx.jface.text.ISynchronizable}. All
+ * modifications of the model's internal annotation map are synchronized using
+ * the model's lock object.
+ */
+public class AnnotationModel : IAnnotationModel, IAnnotationModelExtension, IAnnotationModelExtension2, ISynchronizable {
+
+
+    /**
+     * Iterator that returns the annotations for a given region.
+     *
+     * @since 3.4
+     * @see AnnotationModel.RegionIterator#RegionIterator(Iterator, IAnnotationModel, int, int, bool, bool)
+     */
+    private static final class RegionIterator : Iterator {
+
+        private const Iterator fParentIterator;
+        private const bool fCanEndAfter;
+        private const bool fCanStartBefore;
+        private const IAnnotationModel fModel;
+        private Object fNext;
+        private Position fRegion;
+
+        /**
+         * Iterator that returns all annotations from the parent iterator which
+         * have a position in the given model inside the given region.
+         * <p>
+         * See {@link IAnnotationModelExtension2} for a definition of inside.
+         * </p>
+         *
+         * @param parentIterator iterator containing all annotations
+         * @param model the model to use to retrieve positions from for each
+         *            annotation
+         * @param offset start position of the region
+         * @param length length of the region
+         * @param canStartBefore include annotations starting before region
+         * @param canEndAfter include annotations ending after region
+         * @see IAnnotationModelExtension2
+         */
+        public this(Iterator parentIterator, IAnnotationModel model, int offset, int length, bool canStartBefore, bool canEndAfter) {
+            fParentIterator= parentIterator;
+            fModel= model;
+            fRegion= new Position(offset, length);
+            fCanEndAfter= canEndAfter;
+            fCanStartBefore= canStartBefore;
+            fNext= findNext();
+        }
+
+        /*
+         * @see java.util.Iterator#hasNext()
+         */
+        public bool hasNext() {
+            return fNext !is null;
+        }
+
+        /*
+         * @see java.util.Iterator#next()
+         */
+        public Object next() {
+            if (!hasNext())
+                throw new NoSuchElementException(null);
+
+            Object result= fNext;
+            fNext= findNext();
+            return result;
+        }
+
+        /*
+         * @see java.util.Iterator#remove()
+         */
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        private Object findNext() {
+            while (fParentIterator.hasNext()) {
+                Annotation next= cast(Annotation) fParentIterator.next();
+                Position position= fModel.getPosition(next);
+                if (position !is null) {
+                    int offset= position.getOffset();
+                    if (isWithinRegion(offset, position.getLength()))
+                        return next;
+                }
+            }
+            return null;
+        }
+
+        private bool isWithinRegion(int start, int length) {
+            if (fCanStartBefore && fCanEndAfter)
+                return fRegion.overlapsWith(start, length);
+            else if (fCanStartBefore)
+                return fRegion.includes(start + length - 1);
+            else if (fCanEndAfter)
+                return fRegion.includes(start);
+            else
+                return fRegion.includes(start) && fRegion.includes(start + length - 1);
+        }
+    }
+
+    /**
+     * An iterator iteration over a Positions and mapping positions to
+     * annotations using a provided map if the provided map contains the element.
+     *
+     * @since 3.4
+     */
+    private static final class AnnotationsInterator : Iterator {
+
+        private Object fNext;
+        private const Position[] fPositions;
+        private int fIndex;
+        private const Map fMap;
+
+        /**
+         * @param positions positions to iterate over
+         * @param map a map to map positions to annotations
+         */
+        public this(Position[] positions, Map map) {
+            fPositions= positions;
+            fIndex= 0;
+            fMap= map;
+            fNext= findNext();
+        }
+
+        /* (non-Javadoc)
+         * @see java.util.Iterator#hasNext()
+         */
+        public bool hasNext() {
+            return fNext !is null;
+        }
+
+        /* (non-Javadoc)
+         * @see java.util.Iterator#next()
+         */
+        public Object next() {
+            Object result= fNext;
+            fNext= findNext();
+            return result;
+        }
+
+        /* (non-Javadoc)
+         * @see java.util.Iterator#remove()
+         */
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        private Object findNext() {
+            while (fIndex < fPositions.length) {
+                Position position= fPositions[fIndex];
+                fIndex++;
+                if (fMap.containsKey(position))
+                    return fMap.get(position);
+            }
+
+            return null;
+        }
+    }
+
+    /**
+     * A single iterator builds its behavior based on a sequence of iterators.
+     *
+     * @since 3.1
+     */
+    private static class MetaIterator : Iterator {
+
+        /** The iterator over a list of iterators. */
+        private Iterator fSuperIterator;
+        /** The current iterator. */
+        private Iterator fCurrent;
+        /** The current element. */
+        private Object fCurrentElement;
+
+
+        public this(Iterator iterator) {
+            fSuperIterator= iterator;
+            fCurrent= cast(Iterator) fSuperIterator.next(); // there is at least one.
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+
+        public bool hasNext() {
+            if (fCurrentElement !is null)
+                return true;
+
+            if (fCurrent.hasNext()) {
+                fCurrentElement= fCurrent.next();
+                return true;
+            } else if (fSuperIterator.hasNext()) {
+                fCurrent= cast(Iterator) fSuperIterator.next();
+                return hasNext();
+            } else
+                return false;
+        }
+
+        public Object next() {
+            if (!hasNext())
+                throw new NoSuchElementException(null);
+
+            Object element= fCurrentElement;
+            fCurrentElement= null;
+            return element;
+        }
+    }
+
+    /**
+     * Internal annotation model listener for forwarding annotation model changes from the attached models to the
+     * registered listeners of the outer most annotation model.
+     *
+     * @since 3.0
+     */
+    private class InternalModelListener : IAnnotationModelListener, IAnnotationModelListenerExtension {
+
+        /*
+         * @see dwtx.jface.text.source.IAnnotationModelListener#modelChanged(dwtx.jface.text.source.IAnnotationModel)
+         */
+        public void modelChanged(IAnnotationModel model) {
+            this.outer.fireModelChanged(new AnnotationModelEvent(model, true));
+        }
+
+        /*
+         * @see dwtx.jface.text.source.IAnnotationModelListenerExtension#modelChanged(dwtx.jface.text.source.AnnotationModelEvent)
+         */
+        public void modelChanged(AnnotationModelEvent event) {
+            this.outer.fireModelChanged(event);
+        }
+    }
+
+    /**
+     * The list of managed annotations
+     * @deprecated since 3.0 use <code>getAnnotationMap</code> instead
+     */
+    protected Map fAnnotations;
+    /**
+     * The map which maps {@link Position} to {@link Annotation}.
+     * @since 3.4
+     **/
+    private IdentityHashMap fPositions;
+    /** The list of annotation model listeners */
+    protected ArrayList fAnnotationModelListeners;
+    /** The document connected with this model */
+    protected IDocument fDocument;
+    /** The number of open connections to the same document */
+    private int fOpenConnections= 0;
+    /** The document listener for tracking whether document positions might have been changed. */
+    private IDocumentListener fDocumentListener;
+    /** The flag indicating whether the document positions might have been changed. */
+    private bool fDocumentChanged= true;
+    /**
+     * The model's attachment.
+     * @since 3.0
+     */
+    private Map fAttachments;
+    /**
+     * The annotation model listener on attached sub-models.
+     * @since 3.0
+     */
+    private IAnnotationModelListener fModelListener;
+    /**
+     * The current annotation model event.
+     * @since 3.0
+     */
+    private AnnotationModelEvent fModelEvent;
+    /**
+     * The modification stamp.
+     * @since 3.0
+     */
+    private Object fModificationStamp;
+    /**
+     * Creates a new annotation model. The annotation is empty, i.e. does not
+     * manage any annotations and is not connected to any document.
+     */
+    public this() {
+        fAttachments= new HashMap();
+        fModelListener= new InternalModelListener();
+        fModificationStamp= new Object();
+        fAnnotations= new AnnotationMap(10);
+        fPositions= new IdentityHashMap(10);
+        fAnnotationModelListeners= new ArrayList(2);
+
+        fDocumentListener= new class()  IDocumentListener {
+
+            public void documentAboutToBeChanged(DocumentEvent event) {
+            }
+
+            public void documentChanged(DocumentEvent event) {
+                fDocumentChanged= true;
+            }
+        };
+    }
+
+    /**
+     * Returns the annotation map internally used by this annotation model.
+     *
+     * @return the annotation map internally used by this annotation model
+     * @since 3.0
+     */
+    protected IAnnotationMap getAnnotationMap() {
+        return cast(IAnnotationMap) fAnnotations;
+    }
+
+    /*
+     * @see dwtx.jface.text.ISynchronizable#getLockObject()
+     * @since 3.0
+     */
+    public Object getLockObject() {
+        return getAnnotationMap().getLockObject();
+    }
+
+    /*
+     * @see dwtx.jface.text.ISynchronizable#setLockObject(java.lang.Object)
+     * @since 3.0
+     */
+    public void setLockObject(Object lockObject) {
+        getAnnotationMap().setLockObject(lockObject);
+    }
+
+    /**
+     * Returns the current annotation model event. This is the event that will be sent out
+     * when calling <code>fireModelChanged</code>.
+     *
+     * @return the current annotation model event
+     * @since 3.0
+     */
+    protected final AnnotationModelEvent getAnnotationModelEvent() {
+        synchronized (getLockObject()) {
+            if (fModelEvent is null) {
+                fModelEvent= createAnnotationModelEvent();
+                fModelEvent.markWorldChange(false);
+                fModificationStamp= fModelEvent;
+            }
+            return fModelEvent;
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModel#addAnnotation(dwtx.jface.text.source.Annotation, dwtx.jface.text.Position)
+     */
+    public void addAnnotation(Annotation annotation, Position position) {
+        try {
+            addAnnotation(annotation, position, true);
+        } catch (BadLocationException e) {
+            // ignore invalid position
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModelExtension#replaceAnnotations(dwtx.jface.text.source.Annotation[], java.util.Map)
+     * @since 3.0
+     */
+    public void replaceAnnotations(Annotation[] annotationsToRemove, Map annotationsToAdd) {
+        try {
+            replaceAnnotations(annotationsToRemove, annotationsToAdd, true);
+        } catch (BadLocationException x) {
+        }
+    }
+
+    /**
+     * Replaces the given annotations in this model and if advised fires a
+     * model change event.
+     *
+     * @param annotationsToRemove the annotations to be removed
+     * @param annotationsToAdd the annotations to be added
+     * @param fireModelChanged <code>true</code> if a model change event
+     *            should be fired, <code>false</code> otherwise
+     * @throws BadLocationException in case an annotation should be added at an
+     *             invalid position
+     * @since 3.0
+     */
+    protected void replaceAnnotations(Annotation[] annotationsToRemove, Map annotationsToAdd, bool fireModelChanged_)  {
+
+        if (annotationsToRemove !is null) {
+            for (int i= 0, length= annotationsToRemove.length; i < length; i++)
+                removeAnnotation(annotationsToRemove[i], false);
+        }
+
+        if (annotationsToAdd !is null) {
+            Iterator iter= annotationsToAdd.entrySet().iterator();
+            while (iter.hasNext()) {
+                Map.Entry mapEntry= cast(Map.Entry) iter.next();
+                Annotation annotation= cast(Annotation) mapEntry.getKey();
+                Position position= cast(Position) mapEntry.getValue();
+                addAnnotation(annotation, position, false);
+            }
+        }
+
+        if (fireModelChanged_)
+            fireModelChanged();
+    }
+
+    /**
+     * Adds the given annotation to this model. Associates the
+     * annotation with the given position. If requested, all annotation
+     * model listeners are informed about this model change. If the annotation
+     * is already managed by this model nothing happens.
+     *
+     * @param annotation the annotation to add
+     * @param position the associate position
+     * @param fireModelChanged indicates whether to notify all model listeners
+     * @throws BadLocationException if the position is not a valid document position
+     */
+    protected void addAnnotation(Annotation annotation, Position position, bool fireModelChanged_)  {
+        if (!fAnnotations.containsKey(annotation)) {
+
+            addPosition(fDocument, position);
+            fAnnotations.put(annotation, position);
+            fPositions.put(position, annotation);
+            synchronized (getLockObject()) {
+                getAnnotationModelEvent().annotationAdded(annotation);
+            }
+
+            if (fireModelChanged_)
+                fireModelChanged();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModel#addAnnotationModelListener(dwtx.jface.text.source.IAnnotationModelListener)
+     */
+    public void addAnnotationModelListener(IAnnotationModelListener listener) {
+        if (!fAnnotationModelListeners.contains(cast(Object)listener)) {
+            fAnnotationModelListeners.add(cast(Object)listener);
+            if ( cast(IAnnotationModelListenerExtension)listener ) {
+                IAnnotationModelListenerExtension extension= cast(IAnnotationModelListenerExtension) listener;
+                AnnotationModelEvent event= createAnnotationModelEvent();
+                event.markSealed();
+                extension.modelChanged(event);
+            } else
+                listener.modelChanged(this);
+        }
+    }
+
+    /**
+     * Adds the given position to the default position category of the
+     * given document.
+     *
+     * @param document the document to which to add the position
+     * @param position the position to add
+     * @throws BadLocationException if the position is not a valid document position
+     */
+    protected void addPosition(IDocument document, Position position)  {
+        if (document !is null)
+            document.addPosition(position);
+    }
+
+    /**
+     * Removes the given position from the default position category of the
+     * given document.
+     *
+     * @param document the document to which to add the position
+     * @param position the position to add
+     *
+     * @since 3.0
+     */
+    protected void removePosition(IDocument document, Position position) {
+        if (document !is null)
+            document.removePosition(position);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModel#connect(dwtx.jface.text.IDocument)
+     */
+    public void connect(IDocument document) {
+        Assert.isTrue(fDocument is null || fDocument is document);
+
+        if (fDocument is null) {
+            fDocument= document;
+            Iterator e= getAnnotationMap().valuesIterator();
+            while (e.hasNext())
+                try {
+                    addPosition(fDocument, cast(Position) e.next());
+                } catch (BadLocationException x) {
+                    // ignore invalid position
+                }
+        }
+
+        ++ fOpenConnections;
+        if (fOpenConnections is 1) {
+            fDocument.addDocumentListener(fDocumentListener);
+            connected();
+        }
+
+        for (Iterator it= fAttachments.keySet().iterator(); it.hasNext();) {
+            IAnnotationModel model= cast(IAnnotationModel) fAttachments.get(it.next());
+            model.connect(document);
+        }
+    }
+
+    /**
+     * Hook method. Is called as soon as this model becomes connected to a document.
+     * Subclasses may re-implement.
+     */
+    protected void connected() {
+    }
+
+    /**
+     * Hook method. Is called as soon as this model becomes disconnected from its document.
+     * Subclasses may re-implement.
+     */
+    protected void disconnected() {
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModel#disconnect(dwtx.jface.text.IDocument)
+     */
+    public void disconnect(IDocument document) {
+
+        Assert.isTrue(fDocument is document);
+
+        for (Iterator it= fAttachments.keySet().iterator(); it.hasNext();) {
+            IAnnotationModel model= cast(IAnnotationModel) fAttachments.get(it.next());
+            model.disconnect(document);
+        }
+
+        -- fOpenConnections;
+        if (fOpenConnections is 0) {
+
+            disconnected();
+            fDocument.removeDocumentListener(fDocumentListener);
+
+            if (fDocument !is null) {
+                Iterator e= getAnnotationMap().valuesIterator();
+                while (e.hasNext()) {
+                    Position p= cast(Position) e.next();
+                    removePosition(fDocument, p);
+                }
+                fDocument= null;
+            }
+        }
+    }
+
+    /**
+     * Informs all annotation model listeners that this model has been changed.
+     */
+    protected void fireModelChanged() {
+        AnnotationModelEvent modelEvent= null;
+
+        synchronized(getLockObject()) {
+            if (fModelEvent !is null) {
+                modelEvent= fModelEvent;
+                fModelEvent= null;
+            }
+        }
+
+        if (modelEvent !is null)
+            fireModelChanged(modelEvent);
+    }
+
+    /**
+     * Creates and returns a new annotation model event. Subclasses may override.
+     *
+     * @return a new and empty annotation model event
+     * @since 3.0
+     */
+    protected AnnotationModelEvent createAnnotationModelEvent() {
+        return new AnnotationModelEvent(this);
+    }
+
+    /**
+     * Informs all annotation model listeners that this model has been changed
+     * as described in the annotation model event. The event is sent out
+     * to all listeners implementing <code>IAnnotationModelListenerExtension</code>.
+     * All other listeners are notified by just calling <code>modelChanged(IAnnotationModel)</code>.
+     *
+     * @param event the event to be sent out to the listeners
+     * @since 2.0
+     */
+    protected void fireModelChanged(AnnotationModelEvent event) {
+
+        event.markSealed();
+
+        if (event.isEmpty())
+            return;
+
+        ArrayList v= new ArrayList(fAnnotationModelListeners);
+        Iterator e= v.iterator();
+        while (e.hasNext()) {
+            IAnnotationModelListener l= cast(IAnnotationModelListener) e.next();
+            if ( cast(IAnnotationModelListenerExtension)l )
+                (cast(IAnnotationModelListenerExtension) l).modelChanged(event);
+            else if (l !is null)
+                l.modelChanged(this);
+        }
+    }
+
+    /**
+     * Removes the given annotations from this model. If requested all
+     * annotation model listeners will be informed about this change.
+     * <code>modelInitiated</code> indicates whether the deletion has
+     * been initiated by this model or by one of its clients.
+     *
+     * @param annotations the annotations to be removed
+     * @param fireModelChanged indicates whether to notify all model listeners
+     * @param modelInitiated indicates whether this changes has been initiated by this model
+     */
+    protected void removeAnnotations(List annotations, bool fireModelChanged_, bool modelInitiated) {
+        if (annotations.size() > 0) {
+            Iterator e= annotations.iterator();
+            while (e.hasNext())
+                removeAnnotation(cast(Annotation) e.next(), false);
+
+            if (fireModelChanged_)
+                fireModelChanged();
+        }
+    }
+
+    /**
+     * Removes all annotations from the model whose associated positions have been
+     * deleted. If requested inform all model listeners about the change.
+     *
+     * @param fireModelChanged indicates whether to notify all model listeners
+     */
+    protected void cleanup(bool fireModelChanged_) {
+        cleanup(fireModelChanged_, true);
+    }
+
+    /**
+     * Removes all annotations from the model whose associated positions have been
+     * deleted. If requested inform all model listeners about the change. If requested
+     * a new thread is created for the notification of the model listeners.
+     *
+     * @param fireModelChanged indicates whether to notify all model listeners
+     * @param forkNotification <code>true</code> iff notification should be done in a new thread
+     * @since 3.0
+     */
+    private void cleanup(bool fireModelChanged_, bool forkNotification) {
+        if (fDocumentChanged) {
+            fDocumentChanged= false;
+
+            ArrayList deleted= new ArrayList();
+            Iterator e= getAnnotationMap().keySetIterator();
+            while (e.hasNext()) {
+                Annotation a= cast(Annotation) e.next();
+                Position p= cast(Position) fAnnotations.get(a);
+                if (p is null || p.isDeleted())
+                    deleted.add(a);
+            }
+
+            if (fireModelChanged_ && forkNotification) {
+                removeAnnotations(deleted, false, false);
+                synchronized (getLockObject()) {
+                    if (fModelEvent !is null)
+                        (new Thread ( &fireModelChanged )).start();
+                }
+            } else
+                removeAnnotations(deleted, fireModelChanged_, false);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModel#getAnnotationIterator()
+     */
+    public Iterator getAnnotationIterator() {
+        return getAnnotationIterator(true, true);
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 3.4
+     */
+    public Iterator getAnnotationIterator(int offset, int length, bool canStartBefore, bool canEndAfter) {
+        Iterator regionIterator= getRegionAnnotationIterator(offset, length, canStartBefore, canEndAfter);
+
+        if (fAttachments.isEmpty())
+            return regionIterator;
+
+        List iterators= new ArrayList(fAttachments.size() + 1);
+        iterators.add(cast(Object)regionIterator);
+        Iterator it= fAttachments.keySet().iterator();
+        while (it.hasNext()) {
+            IAnnotationModel attachment= cast(IAnnotationModel) fAttachments.get(it.next());
+            if ( cast(IAnnotationModelExtension2)attachment )
+                iterators.add(cast(Object)(cast(IAnnotationModelExtension2) attachment).getAnnotationIterator(offset, length, canStartBefore, canEndAfter));
+            else
+                iterators.add(new RegionIterator(attachment.getAnnotationIterator(), attachment, offset, length, canStartBefore, canEndAfter));
+        }
+
+        return new MetaIterator(iterators.iterator());
+    }
+
+    /**
+     * Returns an iterator as specified in {@link IAnnotationModelExtension2#getAnnotationIterator(int, int, bool, bool)}
+     *
+     * @param offset region start
+     * @param length region length
+     * @param canStartBefore position can start before region
+     * @param canEndAfter position can end after region
+     * @return an iterator to iterate over annotations in region
+     * @see IAnnotationModelExtension2#getAnnotationIterator(int, int, bool, bool)
+     * @since 3.4
+     */
+    private Iterator getRegionAnnotationIterator(int offset, int length, bool canStartBefore, bool canEndAfter) {
+        if (!( cast(AbstractDocument)fDocument ))
+            return new RegionIterator(getAnnotationIterator(true), this, offset, length, canStartBefore, canEndAfter);
+
+        AbstractDocument document= cast(AbstractDocument) fDocument;
+        cleanup(true);
+
+        try {
+            Position[] positions= document.getPositions(IDocument.DEFAULT_CATEGORY, offset, length, canStartBefore, canEndAfter);
+            return new AnnotationsInterator(positions, fPositions);
+        } catch (BadPositionCategoryException e) {
+            //can not happen
+            Assert.isTrue(false);
+            return null;
+        }
+    }
+
+    /**
+     * Returns all annotations managed by this model. <code>cleanup</code>
+     * indicates whether all annotations whose associated positions are
+     * deleted should previously be removed from the model. <code>recurse</code> indicates
+     * whether annotations of attached sub-models should also be returned.
+     *
+     * @param cleanup indicates whether annotations with deleted associated positions are removed
+     * @param recurse whether to return annotations managed by sub-models.
+     * @return all annotations managed by this model
+     * @since 3.0
+     */
+    private Iterator getAnnotationIterator(bool cleanup, bool recurse) {
+        Iterator iter= getAnnotationIterator(cleanup);
+        if (!recurse || fAttachments.isEmpty())
+            return iter;
+
+        List iterators= new ArrayList(fAttachments.size() + 1);
+        iterators.add(cast(Object)iter);
+        Iterator it= fAttachments.keySet().iterator();
+        while (it.hasNext())
+            iterators.add(cast(Object)(cast(IAnnotationModel) fAttachments.get(it.next())).getAnnotationIterator());
+
+        return new MetaIterator(iterators.iterator());
+    }
+
+    /**
+     * Returns all annotations managed by this model. <code>cleanup</code>
+     * indicates whether all annotations whose associated positions are
+     * deleted should previously be removed from the model.
+     *
+     * @param cleanup indicates whether annotations with deleted associated positions are removed
+     * @return all annotations managed by this model
+     */
+    protected Iterator getAnnotationIterator(bool cleanup_) {
+        if (cleanup_)
+            cleanup(true);
+
+        return getAnnotationMap().keySetIterator();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModel#getPosition(dwtx.jface.text.source.Annotation)
+     */
+    public Position getPosition(Annotation annotation) {
+        Position position= cast(Position) fAnnotations.get(annotation);
+        if (position !is null)
+            return position;
+
+        Iterator it= fAttachments.values().iterator();
+        while (position is null && it.hasNext())
+            position= (cast(IAnnotationModel) it.next()).getPosition(annotation);
+        return position;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModelExtension#removeAllAnnotations()
+     * @since 3.0
+     */
+    public void removeAllAnnotations() {
+        removeAllAnnotations(true);
+    }
+
+    /**
+     * Removes all annotations from the annotation model. If requested
+     * inform all model change listeners about this change.
+     *
+     * @param fireModelChanged indicates whether to notify all model listeners
+     */
+    protected void removeAllAnnotations(bool fireModelChanged_) {
+
+        if (fDocument !is null) {
+            Iterator e= getAnnotationMap().keySetIterator();
+            while (e.hasNext()) {
+                Annotation a= cast(Annotation) e.next();
+                Position p= cast(Position) fAnnotations.get(a);
+                removePosition(fDocument, p);
+//              p.delete_();
+                synchronized (getLockObject()) {
+                    getAnnotationModelEvent().annotationRemoved(a, p);
+                }
+            }
+        }
+
+        fAnnotations.clear();
+        fPositions.clear();
+
+        if (fireModelChanged_)
+            fireModelChanged();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModel#removeAnnotation(dwtx.jface.text.source.Annotation)
+     */
+    public void removeAnnotation(Annotation annotation) {
+        removeAnnotation(annotation, true);
+    }
+
+    /**
+     * Removes the given annotation from the annotation model.
+     * If requested inform all model change listeners about this change.
+     *
+     * @param annotation the annotation to be removed
+     * @param fireModelChanged indicates whether to notify all model listeners
+     */
+    protected void removeAnnotation(Annotation annotation, bool fireModelChanged_) {
+        if (fAnnotations.containsKey(annotation)) {
+
+            Position p= null;
+            p= cast(Position) fAnnotations.get(annotation);
+            if (fDocument !is null) {
+                removePosition(fDocument, p);
+//              p.delete_();
+            }
+
+            fAnnotations.remove(annotation);
+            fPositions.remove(p);
+            synchronized (getLockObject()) {
+                getAnnotationModelEvent().annotationRemoved(annotation, p);
+            }
+
+            if (fireModelChanged_)
+                fireModelChanged();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModelExtension#modifyAnnotationPosition(dwtx.jface.text.source.Annotation, dwtx.jface.text.Position)
+     * @since 3.0
+     */
+    public void modifyAnnotationPosition(Annotation annotation, Position position) {
+        modifyAnnotationPosition(annotation, position, true);
+    }
+
+    /**
+     * Modifies the associated position of the given annotation to the given
+     * position. If the annotation is not yet managed by this annotation model,
+     * the annotation is added. When the position is <code>null</code>, the
+     * annotation is removed from the model.
+     * <p>
+     * If requested, all annotation model change listeners will be informed
+     * about the change.
+     *
+     * @param annotation the annotation whose associated position should be
+     *            modified
+     * @param position the position to whose values the associated position
+     *            should be changed
+     * @param fireModelChanged indicates whether to notify all model listeners
+     * @since 3.0
+     */
+    protected void modifyAnnotationPosition(Annotation annotation, Position position, bool fireModelChanged_) {
+        if (position is null) {
+            removeAnnotation(annotation, fireModelChanged_);
+        } else {
+            Position p= cast(Position) fAnnotations.get(annotation);
+            if (p !is null) {
+
+                if (position.getOffset() !is p.getOffset() || position.getLength() !is p.getLength()) {
+                    fDocument.removePosition(p);
+                    p.setOffset(position.getOffset());
+                    p.setLength(position.getLength());
+                    try {
+                        fDocument.addPosition(p);
+                    } catch (BadLocationException e) {
+                        // ignore invalid position
+                    }
+                }
+                synchronized (getLockObject()) {
+                    getAnnotationModelEvent().annotationChanged(annotation);
+                }
+                if (fireModelChanged_)
+                    fireModelChanged();
+
+            } else {
+                try {
+                    addAnnotation(annotation, position, fireModelChanged_);
+                } catch (BadLocationException x) {
+                    // ignore invalid position
+                }
+            }
+        }
+    }
+
+    /**
+     * Modifies the given annotation if the annotation is managed by this
+     * annotation model.
+     * <p>
+     * If requested, all annotation model change listeners will be informed
+     * about the change.
+     *
+     * @param annotation the annotation to be modified
+     * @param fireModelChanged indicates whether to notify all model listeners
+     * @since 3.0
+     */
+    protected void modifyAnnotation(Annotation annotation, bool fireModelChanged_) {
+        if (fAnnotations.containsKey(annotation)) {
+            synchronized (getLockObject()) {
+                getAnnotationModelEvent().annotationChanged(annotation);
+            }
+            if (fireModelChanged_)
+                fireModelChanged();
+        }
+    }
+
+    /*
+     * @see IAnnotationModel#removeAnnotationModelListener(IAnnotationModelListener)
+     */
+    public void removeAnnotationModelListener(IAnnotationModelListener listener) {
+        fAnnotationModelListeners.remove(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModelExtension#attach(java.lang.Object, java.lang.Object)
+     * @since 3.0
+     */
+    public void addAnnotationModel(Object key, IAnnotationModel attachment) {
+        Assert.isNotNull(cast(Object)attachment);
+        if (!fAttachments.containsValue(cast(Object)attachment)) {
+            fAttachments.put(key, cast(Object)attachment);
+            for (int i= 0; i < fOpenConnections; i++)
+                attachment.connect(fDocument);
+            attachment.addAnnotationModelListener(fModelListener);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModelExtension#get(java.lang.Object)
+     * @since 3.0
+     */
+    public IAnnotationModel getAnnotationModel(Object key) {
+        return cast(IAnnotationModel) fAttachments.get(key);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModelExtension#detach(java.lang.Object)
+     * @since 3.0
+     */
+    public IAnnotationModel removeAnnotationModel(Object key) {
+        IAnnotationModel ret= cast(IAnnotationModel) fAttachments.remove(key);
+        if (ret !is null) {
+            for (int i= 0; i < fOpenConnections; i++)
+                ret.disconnect(fDocument);
+            ret.removeAnnotationModelListener(fModelListener);
+        }
+        return ret;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModelExtension#getModificationStamp()
+     * @since 3.0
+     */
+    public Object getModificationStamp() {
+        return fModificationStamp;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/AnnotationModelEvent.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,330 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.AnnotationModelEvent;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+import dwtx.jface.text.Position;
+
+
+/**
+ * Specification of changes applied to annotation models. The event carries the
+ * changed annotation model as well as added, removed, and modified annotations.
+ * <p>
+ * An event can be sealed. Afterwards it can not be modified. Thus, the normal
+ * process is that an empty event is created, filled with the changed
+ * information, and before it is sent to the listeners, the event is sealed.
+ *
+ * @see dwtx.jface.text.source.IAnnotationModel
+ * @see dwtx.jface.text.source.IAnnotationModelListenerExtension
+ * @since 2.0
+ */
+public class AnnotationModelEvent {
+
+    /** The model this event refers to. */
+    private IAnnotationModel fAnnotationModel;
+    /**
+     * The added annotations.
+     * @since 3.0
+     */
+    private Set fAddedAnnotations;
+    /**
+     * The removed annotations.
+     * @since 3.0
+     */
+    private Map fRemovedAnnotations;
+    /**
+     * The changed annotations.
+     * @since 3.0
+     */
+    private Set fChangedAnnotations;
+    /**
+     * Indicates that this event does not contain detailed information.
+     * @since 3.0
+     */
+    private bool fIsWorldChange;
+    /**
+     * The modification stamp.
+     * @since 3.0
+     */
+    private Object fModificationStamp;
+
+    /**
+     * Creates a new annotation model event for the given model.
+     *
+     * @param model the model
+     */
+    public this(IAnnotationModel model) {
+        this(model, true);
+    }
+
+    /**
+     * Creates a new annotation model event for the given model.
+     *
+     * @param model the model
+     * @param isWorldChange <code>true</code> if world change
+     * @since 3.0
+     */
+    public this(IAnnotationModel model, bool isWorldChange) {
+        fAddedAnnotations= new HashSet();
+        fRemovedAnnotations= new HashMap();
+        fChangedAnnotations= new HashSet();
+
+        fAnnotationModel= model;
+        fIsWorldChange= isWorldChange;
+    }
+
+    /**
+     * Returns the model this event refers to.
+     *
+     * @return the model this events belongs to
+     */
+    public IAnnotationModel getAnnotationModel() {
+        return fAnnotationModel;
+    }
+
+    /**
+     * Adds the given annotation to the set of annotations that are reported as
+     * being added from the model. If this event is considered a world change,
+     * it is no longer so after this method has successfully finished.
+     *
+     * @param annotation the added annotation
+     * @since 3.0
+     */
+    public void annotationAdded(Annotation annotation) {
+        fAddedAnnotations.add(annotation);
+        fIsWorldChange= false;
+    }
+
+    /**
+     * Returns the added annotations.
+     *
+     * @return the added annotations
+     * @since 3.0
+     */
+    public Annotation[] getAddedAnnotations() {
+        int size= fAddedAnnotations.size();
+        Annotation[] added= new Annotation[size];
+        fAddedAnnotations.toArray(added);
+        return added;
+    }
+
+    /**
+     * Adds the given annotation to the set of annotations that are reported as
+     * being removed from the model. If this event is considered a world
+     * change, it is no longer so after this method has successfully finished.
+     *
+     * @param annotation the removed annotation
+     * @since 3.0
+     */
+    public void annotationRemoved(Annotation annotation) {
+        annotationRemoved(annotation, null);
+    }
+
+    /**
+     * Adds the given annotation to the set of annotations that are reported as
+     * being removed from the model. If this event is considered a world
+     * change, it is no longer so after this method has successfully finished.
+     *
+     * @param annotation the removed annotation
+     * @param position the position of the removed annotation
+     * @since 3.0
+     */
+    public void annotationRemoved(Annotation annotation, Position position) {
+        fRemovedAnnotations.put(annotation, position);
+        fIsWorldChange= false;
+    }
+
+    /**
+     * Returns the removed annotations.
+     *
+     * @return the removed annotations
+     * @since 3.0
+     */
+    public Annotation[] getRemovedAnnotations() {
+        int size= fRemovedAnnotations.size();
+        Annotation[] removed= new Annotation[size];
+        fRemovedAnnotations.keySet().toArray(removed);
+        return removed;
+    }
+
+    /**
+     * Returns the position of the removed annotation at that point in time
+     * when the annotation has been removed.
+     *
+     * @param annotation the removed annotation
+     * @return the position of the removed annotation or <code>null</code>
+     * @since 3.0
+     */
+    public Position getPositionOfRemovedAnnotation(Annotation annotation) {
+        return cast(Position) fRemovedAnnotations.get(annotation);
+    }
+
+    /**
+     * Adds the given annotation to the set of annotations that are reported as
+     * being changed from the model. If this event is considered a world
+     * change, it is no longer so after this method has successfully finished.
+     *
+     * @param annotation the changed annotation
+     * @since 3.0
+     */
+    public void annotationChanged(Annotation annotation) {
+        fChangedAnnotations.add(annotation);
+        fIsWorldChange= false;
+    }
+
+    /**
+     * Returns the changed annotations.
+     *
+     * @return the changed annotations
+     * @since 3.0
+     */
+    public Annotation[] getChangedAnnotations() {
+        int size= fChangedAnnotations.size();
+        Annotation[] changed= new Annotation[size];
+        fChangedAnnotations.toArray(changed);
+        return changed;
+    }
+
+    /**
+     * Returns whether this annotation model event is empty or not. If this
+     * event represents a world change, this method returns <code>false</code>
+     * although the event does not carry any added, removed, or changed
+     * annotations.
+     *
+     * @return <code>true</code> if this event is empty
+     * @since 3.0
+     */
+    public bool isEmpty() {
+        return !fIsWorldChange && fAddedAnnotations.isEmpty() && fRemovedAnnotations.isEmpty() && fChangedAnnotations.isEmpty();
+    }
+
+    /**
+     * Returns whether this annotation model events contains detailed
+     * information about the modifications applied to the event annotation
+     * model or whether it represents a world change. I.e. everything in the
+     * model might have changed.
+     *
+     * @return <code>true</code> if world change, <code>false</code> otherwise
+     * @since 3.0
+     */
+    public bool isWorldChange() {
+        return fIsWorldChange;
+    }
+
+    /**
+     * Marks this event as world change according to the given flag.
+     *
+     * @param isWorldChange <code>true</code> if this event is a world change, <code>false</code> otherwise
+     * @since 3.0
+     */
+    void markWorldChange(bool isWorldChange) {
+        fIsWorldChange= isWorldChange;
+    }
+
+    /**
+     * Returns whether this annotation model event is still valid.
+     *
+     * @return <code>true</code> if this event is still valid, <code>false</code> otherwise
+     * @since 3.0
+     */
+    public bool isValid() {
+        if (fModificationStamp !is null && cast(IAnnotationModelExtension)fAnnotationModel ) {
+            IAnnotationModelExtension extension= cast(IAnnotationModelExtension) fAnnotationModel;
+            return fModificationStamp is extension.getModificationStamp();
+        }
+        return true;
+    }
+
+    /**
+     * Seals this event. Any direct modification to the annotation model after the event has been sealed
+     * invalidates this event.
+     *
+     * @since 3.0
+     */
+    public void markSealed() {
+        if ( cast(IAnnotationModelExtension)fAnnotationModel ) {
+            IAnnotationModelExtension extension= cast(IAnnotationModelExtension) fAnnotationModel;
+            fModificationStamp= extension.getModificationStamp();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/AnnotationPainter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1794 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.AnnotationPainter;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.text.convert.Format;
+import tango.io.Stdout;
+
+import dwt.DWT;
+import dwt.DWTException;
+import dwt.custom.StyleRange;
+import dwt.custom.StyledText;
+import dwt.events.PaintEvent;
+import dwt.events.PaintListener;
+import dwt.graphics.Color;
+import dwt.graphics.GC;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.graphics.TextStyle;
+import dwt.widgets.Display;
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.Platform;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IPaintPositionManager;
+import dwtx.jface.text.IPainter;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextInputListener;
+import dwtx.jface.text.ITextPresentationListener;
+import dwtx.jface.text.ITextViewerExtension2;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.JFaceTextUtil;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextPresentation;
+
+
+    /**
+     * A drawing strategy draws the decoration for an annotation onto the text widget.
+     *
+     * @since 3.0
+     */
+    public interface IDrawingStrategy {
+        /**
+         * Draws a decoration for an annotation onto the specified GC at the given text range. There
+         * are two different invocation modes of the <code>draw</code> method:
+         * <ul>
+         * <li><strong>drawing mode:</strong> the passed GC is the graphics context of a paint
+         * event occurring on the text widget. The strategy should draw the decoration onto the
+         * graphics context, such that the decoration appears at the given range in the text
+         * widget.</li>
+         * <li><strong>clearing mode:</strong> the passed GC is <code>null</code>. In this case
+         * the strategy must invalidate enough of the text widget's client area to cover any
+         * decoration drawn in drawing mode. This can usually be accomplished by calling
+         * {@linkplain StyledText#redrawRange(int, int, bool) textWidget.redrawRange(offset, length, true)}.</li>
+         * </ul>
+         *
+         * @param annotation the annotation to be drawn
+         * @param gc the graphics context, <code>null</code> when in clearing mode
+         * @param textWidget the text widget to draw on
+         * @param offset the offset of the line
+         * @param length the length of the line
+         * @param color the color of the line
+         */
+        void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color);
+    }
+
+    alias IDrawingStrategy AnnotationPainter_IDrawingStrategy;
+
+/**
+ * Paints decorations for annotations provided by an annotation model and/or
+ * highlights them in the associated source viewer.
+ * <p>
+ * The annotation painter can be configured with drawing strategies. A drawing
+ * strategy defines the visual presentation of a particular type of annotation
+ * decoration.</p>
+ * <p>
+ * Clients usually instantiate and configure objects of this class.</p>
+ *
+ * @since 2.1
+ */
+public class AnnotationPainter : IPainter, PaintListener, IAnnotationModelListener, IAnnotationModelListenerExtension, ITextPresentationListener {
+
+    /**
+     * Squiggles drawing strategy.
+     *
+     * @since 3.0
+     * @deprecated As of 3.4, replaced by {@link AnnotationPainter.UnderlineStrategy}
+     */
+    public static class SquigglesStrategy : IDrawingStrategy {
+
+        /*
+         * @see dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(dwtx.jface.text.source.Annotation, dwt.graphics.GC, dwt.custom.StyledText, int, int, dwt.graphics.Color)
+         * @since 3.0
+         */
+        public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) {
+            if (gc !is null) {
+
+                if (length < 1)
+                    return;
+
+                Point left= textWidget.getLocationAtOffset(offset);
+                Point right= textWidget.getLocationAtOffset(offset + length);
+                Rectangle rect= textWidget.getTextBounds(offset, offset + length - 1);
+                left.x= rect.x;
+                right.x= rect.x + rect.width;
+
+                int[] polyline= computePolyline(left, right, textWidget.getBaseline(offset), textWidget.getLineHeight(offset));
+
+                gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance
+                gc.setLineStyle(DWT.LINE_SOLID);
+                gc.setForeground(color);
+                gc.drawPolyline(polyline);
+
+            } else {
+                textWidget.redrawRange(offset, length, true);
+            }
+        }
+
+        /**
+         * Computes an array of alternating x and y values which are the corners of the squiggly line of the
+         * given height between the given end points.
+         *
+         * @param left the left end point
+         * @param right the right end point
+         * @param baseline the font's baseline
+         * @param lineHeight the height of the line
+         * @return the array of alternating x and y values which are the corners of the squiggly line
+         */
+        private int[] computePolyline(Point left, Point right, int baseline, int lineHeight) {
+
+            final int WIDTH= 4; // must be even
+            final int HEIGHT= 2; // can be any number
+
+            int peaks= (right.x - left.x) / WIDTH;
+            if (peaks is 0 && right.x - left.x > 2)
+                peaks= 1;
+
+            int leftX= left.x;
+
+            // compute (number of point) * 2
+            int length_= ((2 * peaks) + 1) * 2;
+            if (length_ < 0)
+                return new int[0];
+
+            int[] coordinates= new int[length_];
+
+            // cache peeks' y-coordinates
+            int top= left.y + Math.min(baseline + 1, lineHeight - HEIGHT - 1);
+            int bottom= top + HEIGHT;
+
+            // populate array with peek coordinates
+            for (int i= 0; i < peaks; i++) {
+                int index= 4 * i;
+                coordinates[index]= leftX + (WIDTH * i);
+                coordinates[index+1]= bottom;
+                coordinates[index+2]= coordinates[index] + WIDTH/2;
+                coordinates[index+3]= top;
+            }
+
+            // the last down flank is missing
+            coordinates[length_-2]= Math.min(Math.max(0, right.x - 1), left.x + (WIDTH * peaks));
+            coordinates[length_-1]= bottom;
+
+            return coordinates;
+        }
+    }
+
+    /**
+     * Drawing strategy that does nothing.
+     *
+     * @since 3.0
+     */
+    public static final class NullStrategy : IDrawingStrategy {
+
+        /*
+         * @see dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(dwtx.jface.text.source.Annotation, dwt.graphics.GC, dwt.custom.StyledText, int, int, dwt.graphics.Color)
+         * @since 3.0
+         */
+        public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) {
+            // do nothing
+        }
+    }
+
+
+    /**
+     * A text style painting strategy draws the decoration for an annotation
+     * onto the text widget by applying a {@link TextStyle} on a given
+     * {@link StyleRange}.
+     *
+     * @since 3.4
+     */
+    public interface ITextStyleStrategy {
+
+        /**
+         * Applies a text style on the given <code>StyleRange</code>.
+         *
+         * @param styleRange the style range on which to apply the text style
+         * @param annotationColor the color of the annotation
+         */
+        void applyTextStyle(StyleRange styleRange, Color annotationColor);
+    }
+
+
+    /**
+     * @since 3.4
+     */
+    public static final class HighlightingStrategy : ITextStyleStrategy {
+        public void applyTextStyle(StyleRange styleRange, Color annotationColor) {
+            styleRange.background= annotationColor;
+        }
+    }
+
+
+    /**
+     * Underline text style strategy.
+     *
+     * @since 3.4
+     */
+    public static final class UnderlineStrategy : ITextStyleStrategy {
+
+        int fUnderlineStyle;
+
+        public this(int style) {
+            Assert.isLegal(style is DWT.UNDERLINE_SINGLE || style is DWT.UNDERLINE_DOUBLE || style is DWT.UNDERLINE_ERROR || style is DWT.UNDERLINE_SQUIGGLE);
+            fUnderlineStyle= style;
+        }
+
+        public void applyTextStyle(StyleRange styleRange, Color annotationColor) {
+            styleRange.underline= true;
+            styleRange.underlineStyle= fUnderlineStyle;
+            styleRange.underlineColor= annotationColor;
+        }
+    }
+
+
+    /**
+     * Box text style strategy.
+     *
+     * @since 3.4
+     */
+    public static final class BoxStrategy : ITextStyleStrategy {
+
+        int fBorderStyle;
+
+        public this(int style) {
+            Assert.isLegal(style is DWT.BORDER_DASH || style is DWT.BORDER_DASH || style is DWT.BORDER_SOLID);
+            fBorderStyle= style;
+        }
+
+        public void applyTextStyle(StyleRange styleRange, Color annotationColor) {
+            styleRange.borderStyle= fBorderStyle;
+            styleRange.borderColor= annotationColor;
+        }
+    }
+
+
+    /**
+     * Implementation of <code>IRegion</code> that can be reused
+     * by setting the offset and the length.
+     */
+    private static class ReusableRegion : Position , IRegion {
+        public override int getOffset(){
+            return super.getOffset();
+        }
+        public override int getLength(){
+            return super.getLength();
+        }
+    }
+
+    /**
+     * Tells whether this class is in debug mode.
+     * @since 3.0
+     */
+    private static bool DEBUG_;
+    private static bool DEBUG_init = false;
+    private static bool DEBUG(){
+        if( !DEBUG_init ){
+            DEBUG_init = true;
+            DEBUG_ = "true".equalsIgnoreCase(Platform.getDebugOption("dwtx.jface.text/debug/AnnotationPainter"));  //$NON-NLS-1$//$NON-NLS-2$
+        }
+        return DEBUG_;
+    }
+
+    /**
+     * The squiggly painter strategy.
+     * @since 3.0
+     */
+    private static IDrawingStrategy SQUIGGLES_STRATEGY_;
+    private static IDrawingStrategy SQUIGGLES_STRATEGY(){
+        if( SQUIGGLES_STRATEGY_ is null ){
+            synchronized( AnnotationPainter.classinfo ){
+                if( SQUIGGLES_STRATEGY_ is null ){
+                    SQUIGGLES_STRATEGY_ = new SquigglesStrategy();
+                }
+            }
+        }
+        return SQUIGGLES_STRATEGY_;
+    }
+
+
+    /**
+     * This strategy is used to mark the <code>null</code> value in the chache
+     * maps.
+     *
+     * @since 3.4
+     */
+    private static IDrawingStrategy NULL_STRATEGY_;
+    private static IDrawingStrategy NULL_STRATEGY(){
+        if( NULL_STRATEGY_ is null ){
+            synchronized( AnnotationPainter.classinfo ){
+                if( NULL_STRATEGY_ is null ){
+                    NULL_STRATEGY_= new NullStrategy();
+                }
+            }
+        }
+        return NULL_STRATEGY_;
+    }
+    /**
+     * The squiggles painter id.
+     * @since 3.0
+     */
+    private static Object SQUIGGLES_;
+    private static Object SQUIGGLES(){
+        if( SQUIGGLES_ is null ){
+            synchronized( AnnotationPainter.classinfo ){
+                if( SQUIGGLES_ is null ){
+                    SQUIGGLES_= new Object();
+                }
+            }
+        }
+        return SQUIGGLES_;
+    }
+    /**
+     * The squiggly painter strategy.
+     *
+     * @since 3.4
+     */
+    private static ITextStyleStrategy HIGHLIGHTING_STRATEGY_;
+    private static ITextStyleStrategy HIGHLIGHTING_STRATEGY(){
+        if( HIGHLIGHTING_STRATEGY_ is null ){
+            synchronized( AnnotationPainter.classinfo ){
+                if( HIGHLIGHTING_STRATEGY_ is null ){
+                    HIGHLIGHTING_STRATEGY_= new HighlightingStrategy();
+                }
+            }
+        }
+        return HIGHLIGHTING_STRATEGY_;
+    }
+
+    /**
+     * The highlighting text style strategy id.
+     *
+     * @since 3.4
+     */
+    private static Object HIGHLIGHTING_;
+    private static Object HIGHLIGHTING(){
+        if( HIGHLIGHTING_ is null ){
+            synchronized( AnnotationPainter.classinfo ){
+                if( HIGHLIGHTING_ is null ){
+                    HIGHLIGHTING_= new Object();
+                }
+            }
+        }
+        return HIGHLIGHTING_;
+    }
+
+    /**
+     * The presentation information (decoration) for an annotation.  Each such
+     * object represents one decoration drawn on the text area, such as squiggly lines
+     * and underlines.
+     */
+    private static class Decoration {
+        /** The position of this decoration */
+        private Position fPosition;
+        /** The color of this decoration */
+        private Color fColor;
+        /**
+         * The annotation's layer
+         * @since 3.0
+         */
+        private int fLayer;
+        /**
+         * The painting strategy for this decoration.
+         * @since 3.0
+         */
+        private Object fPaintingStrategy;
+    }
+
+
+    /** Indicates whether this painter is active */
+    private bool fIsActive= false;
+    /** Indicates whether this painter is managing decorations */
+    private bool fIsPainting= false;
+    /** Indicates whether this painter is setting its annotation model */
+    private /+volatile+/ bool  fIsSettingModel= false;
+    /** The associated source viewer */
+    private ISourceViewer fSourceViewer;
+    /** The cached widget of the source viewer */
+    private StyledText fTextWidget;
+    /** The annotation model providing the annotations to be drawn */
+    private IAnnotationModel fModel;
+    /** The annotation access */
+    private IAnnotationAccess fAnnotationAccess;
+    /**
+     * The map with decorations
+     * @since 3.0
+     */
+    private Map fDecorationsMap; // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=50767
+    /**
+     * The map with of highlighted decorations.
+     * @since 3.0
+     */
+    private Map fHighlightedDecorationsMap;
+    /**
+     * Mutex for highlighted decorations map.
+     * @since 3.0
+     */
+    private Object fDecorationMapLock;
+    /**
+     * Mutex for for decorations map.
+     * @since 3.0
+     */
+    private Object fHighlightedDecorationsMapLock;
+    /**
+     * Maps an annotation type to its registered color.
+     *
+     * @see #setAnnotationTypeColor(Object, Color)
+     */
+    private Map fAnnotationType2Color;
+
+    /**
+     * Cache that maps the annotation type to its color.
+     * @since 3.4
+     */
+    private Map fCachedAnnotationType2Color;
+    /**
+     * The range in which the current highlight annotations can be found.
+     * @since 3.0
+     */
+    private Position fCurrentHighlightAnnotationRange= null;
+    /**
+     * The range in which all added, removed and changed highlight
+     * annotations can be found since the last world change.
+     * @since 3.0
+     */
+    private Position fTotalHighlightAnnotationRange= null;
+    /**
+     * The range in which the currently drawn annotations can be found.
+     * @since 3.3
+     */
+    private Position fCurrentDrawRange= null;
+    /**
+     * The range in which all added, removed and changed drawn
+     * annotations can be found since the last world change.
+     * @since 3.3
+     */
+    private Position fTotalDrawRange= null;
+    /**
+     * The text input listener.
+     * @since 3.0
+     */
+    private ITextInputListener fTextInputListener;
+    /**
+     * Flag which tells that a new document input is currently being set.
+     * @since 3.0
+     */
+    private bool fInputDocumentAboutToBeChanged;
+    /**
+     * Maps annotation types to painting strategy identifiers.
+     *
+     * @see #addAnnotationType(Object, Object)
+     * @since 3.0
+     */
+    private Map fAnnotationType2PaintingStrategyId;
+    /**
+     * Maps annotation types to painting strategy identifiers.
+     * @since 3.4
+     */
+    private Map fCachedAnnotationType2PaintingStrategy;
+
+    /**
+     * Maps painting strategy identifiers to painting strategies.
+     *
+     * @since 3.0
+     */
+    private Map fPaintingStrategyId2PaintingStrategy;
+
+    /**
+     * Reuse this region for performance reasons.
+     * @since 3.3
+     */
+    private ReusableRegion fReusableRegion;
+
+    /**
+     * Creates a new annotation painter for the given source viewer and with the
+     * given annotation access. The painter is not initialized, i.e. no
+     * annotation types are configured to be painted.
+     *
+     * @param sourceViewer the source viewer for this painter
+     * @param access the annotation access for this painter
+     */
+    public this(ISourceViewer sourceViewer, IAnnotationAccess access) {
+        fDecorationsMap= new HashMap(); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=50767
+        fHighlightedDecorationsMap= new HashMap(); // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=50767
+        fDecorationMapLock= new Object();
+        fHighlightedDecorationsMapLock= new Object();
+        fAnnotationType2Color= new HashMap();
+        fCachedAnnotationType2Color= new HashMap();
+        fReusableRegion= new ReusableRegion();
+        fAnnotationType2PaintingStrategyId= new HashMap();
+        fCachedAnnotationType2PaintingStrategy= new HashMap();
+        fPaintingStrategyId2PaintingStrategy= new HashMap();
+
+        fSourceViewer= sourceViewer;
+        fAnnotationAccess= access;
+        fTextWidget= sourceViewer.getTextWidget();
+
+        // default drawing strategies: squiggles were the only decoration style before version 3.0
+        fPaintingStrategyId2PaintingStrategy.put(SQUIGGLES, cast(Object)SQUIGGLES_STRATEGY);
+        fPaintingStrategyId2PaintingStrategy.put(HIGHLIGHTING, cast(Object)HIGHLIGHTING_STRATEGY);
+    }
+
+    /**
+     * Returns whether this painter has to draw any squiggles.
+     *
+     * @return <code>true</code> if there are squiggles to be drawn, <code>false</code> otherwise
+     */
+    private bool hasDecorations() {
+        synchronized (fDecorationMapLock) {
+            return !fDecorationsMap.isEmpty();
+        }
+    }
+
+    /**
+     * Enables painting. This painter registers a paint listener with the
+     * source viewer's widget.
+     */
+    private void enablePainting() {
+        if (!fIsPainting && hasDecorations()) {
+            fIsPainting= true;
+            fTextWidget.addPaintListener(this);
+            handleDrawRequest(null);
+        }
+    }
+
+    /**
+     * Disables painting, if is has previously been enabled. Removes
+     * any paint listeners registered with the source viewer's widget.
+     *
+     * @param redraw <code>true</code> if the widget should be redrawn after disabling
+     */
+    private void disablePainting(bool redraw) {
+        if (fIsPainting) {
+            fIsPainting= false;
+            fTextWidget.removePaintListener(this);
+            if (redraw && hasDecorations())
+                handleDrawRequest(null);
+        }
+    }
+
+    /**
+     * Sets the annotation model for this painter. Registers this painter
+     * as listener of the give model, if the model is not <code>null</code>.
+     *
+     * @param model the annotation model
+     */
+    private void setModel(IAnnotationModel model) {
+        if (fModel !is model) {
+            if (fModel !is null)
+                fModel.removeAnnotationModelListener(this);
+            fModel= model;
+            if (fModel !is null) {
+                try {
+                    fIsSettingModel= true;
+                    fModel.addAnnotationModelListener(this);
+                } finally {
+                    fIsSettingModel= false;
+                }
+            }
+        }
+    }
+
+    /**
+     * Updates the set of decorations based on the current state of
+     * the painter's annotation model.
+     *
+     * @param event the annotation model event
+     */
+    private void catchupWithModel(AnnotationModelEvent event) {
+
+        synchronized (fDecorationMapLock) {
+            if (fDecorationsMap is null)
+                return;
+        }
+
+        IRegion clippingRegion= computeClippingRegion(null, true);
+        IDocument document= fSourceViewer.getDocument();
+
+        int highlightAnnotationRangeStart= Integer.MAX_VALUE;
+        int highlightAnnotationRangeEnd= -1;
+
+        int drawRangeStart= Integer.MAX_VALUE;
+        int drawRangeEnd= -1;
+
+        if (fModel !is null) {
+
+            Map decorationsMap;
+            Map highlightedDecorationsMap;
+
+            // Clone decoration maps
+            synchronized (fDecorationMapLock) {
+                decorationsMap= new HashMap(fDecorationsMap);
+            }
+            synchronized (fHighlightedDecorationsMapLock) {
+                highlightedDecorationsMap= new HashMap(fHighlightedDecorationsMap);
+            }
+
+            bool isWorldChange= false;
+
+            Iterator e;
+            if (event is null || event.isWorldChange()) {
+                isWorldChange= true;
+
+                if (DEBUG && event is null)
+                    System.out_.println("AP: INTERNAL CHANGE"); //$NON-NLS-1$
+
+                Iterator iter= decorationsMap.entrySet().iterator();
+                while (iter.hasNext()) {
+                    Map.Entry entry= cast(Map.Entry)iter.next();
+                    Annotation annotation= cast(Annotation)entry.getKey();
+                    Decoration decoration= cast(Decoration)entry.getValue();
+                    drawDecoration(decoration, null, annotation, clippingRegion, document);
+                }
+
+                decorationsMap.clear();
+
+                highlightedDecorationsMap.clear();
+
+                e= fModel.getAnnotationIterator();
+
+
+            } else {
+
+                // Remove annotations
+                Annotation[] removedAnnotations= event.getRemovedAnnotations();
+                for (int i=0, length= removedAnnotations.length; i < length; i++) {
+                    Annotation annotation= removedAnnotations[i];
+                    Decoration decoration= cast(Decoration)highlightedDecorationsMap.remove(annotation);
+                    if (decoration !is null) {
+                        Position position= decoration.fPosition;
+                        if (position !is null) {
+                            highlightAnnotationRangeStart= Math.min(highlightAnnotationRangeStart, position.offset);
+                            highlightAnnotationRangeEnd= Math.max(highlightAnnotationRangeEnd, position.offset + position.length);
+                        }
+                    }
+                    decoration= cast(Decoration)decorationsMap.remove(annotation);
+                    if (decoration !is null) {
+                        drawDecoration(decoration, null, annotation, clippingRegion, document);
+                        Position position= decoration.fPosition;
+                        if (position !is null) {
+                            drawRangeStart= Math.min(drawRangeStart, position.offset);
+                            drawRangeEnd= Math.max(drawRangeEnd, position.offset + position.length);
+                        }
+                    }
+
+                }
+
+                // Update existing annotations
+                Annotation[] changedAnnotations= event.getChangedAnnotations();
+                for (int i=0, length= changedAnnotations.length; i < length; i++) {
+                    Annotation annotation= changedAnnotations[i];
+
+                    bool isHighlighting= false;
+
+                    Decoration decoration= cast(Decoration)highlightedDecorationsMap.get(annotation);
+
+                    if (decoration !is null) {
+                        isHighlighting= true;
+                        // The call below updates the decoration - no need to create new decoration
+                        decoration= getDecoration(annotation, decoration);
+                        if (decoration is null)
+                            highlightedDecorationsMap.remove(annotation);
+                    } else {
+                        decoration= getDecoration(annotation, decoration);
+                        if (decoration !is null && cast(ITextStyleStrategy)decoration.fPaintingStrategy ) {
+                            highlightedDecorationsMap.put(annotation, decoration);
+                            isHighlighting= true;
+                        }
+                    }
+
+                    bool usesDrawingStrategy= !isHighlighting && decoration !is null;
+
+                    Position position= null;
+                    if (decoration is null)
+                        position= fModel.getPosition(annotation);
+                    else
+                        position= decoration.fPosition;
+
+                    if (position !is null && !position.isDeleted()) {
+                        if (isHighlighting) {
+                            highlightAnnotationRangeStart= Math.min(highlightAnnotationRangeStart, position.offset);
+                            highlightAnnotationRangeEnd= Math.max(highlightAnnotationRangeEnd, position.offset + position.length);
+                        }
+                        if (usesDrawingStrategy) {
+                            drawRangeStart= Math.min(drawRangeStart, position.offset);
+                            drawRangeEnd= Math.max(drawRangeEnd, position.offset + position.length);
+                        }
+                    } else {
+                        highlightedDecorationsMap.remove(annotation);
+                    }
+
+                    if (usesDrawingStrategy) {
+                        Decoration oldDecoration= cast(Decoration)decorationsMap.get(annotation);
+                        if (oldDecoration !is null) {
+                            drawDecoration(oldDecoration, null, annotation, clippingRegion, document);
+
+                        if (decoration !is null)
+                            decorationsMap.put(annotation, decoration);
+                        else if (oldDecoration !is null)
+                            decorationsMap.remove(annotation);
+                        }
+                    }
+                }
+
+                e= Arrays.asList(event.getAddedAnnotations()).iterator();
+            }
+
+            // Add new annotations
+            while (e.hasNext()) {
+                Annotation annotation= cast(Annotation) e.next();
+                Decoration pp= getDecoration(annotation, null);
+                if (pp !is null) {
+                    if (cast(IDrawingStrategy)pp.fPaintingStrategy ) {
+                        decorationsMap.put(annotation, pp);
+                        drawRangeStart= Math.min(drawRangeStart, pp.fPosition.offset);
+                        drawRangeEnd= Math.max(drawRangeEnd, pp.fPosition.offset + pp.fPosition.length);
+                    } else if (cast(ITextStyleStrategy)pp.fPaintingStrategy ) {
+                        highlightedDecorationsMap.put(annotation, pp);
+                        highlightAnnotationRangeStart= Math.min(highlightAnnotationRangeStart, pp.fPosition.offset);
+                        highlightAnnotationRangeEnd= Math.max(highlightAnnotationRangeEnd, pp.fPosition.offset + pp.fPosition.length);
+                    }
+
+                }
+            }
+
+            synchronized (fDecorationMapLock) {
+                fDecorationsMap= decorationsMap;
+                updateDrawRanges(drawRangeStart, drawRangeEnd, isWorldChange);
+            }
+
+            synchronized (fHighlightedDecorationsMapLock) {
+                fHighlightedDecorationsMap= highlightedDecorationsMap;
+                updateHighlightRanges(highlightAnnotationRangeStart, highlightAnnotationRangeEnd, isWorldChange);
+            }
+        } else {
+            // annotation model is null -> clear all
+            synchronized (fDecorationMapLock) {
+                fDecorationsMap.clear();
+            }
+            synchronized (fHighlightedDecorationsMapLock) {
+                fHighlightedDecorationsMap.clear();
+            }
+        }
+    }
+
+    /**
+     * Updates the remembered highlight ranges.
+     *
+     * @param highlightAnnotationRangeStart the start of the range
+     * @param highlightAnnotationRangeEnd   the end of the range
+     * @param isWorldChange                 tells whether the range belongs to a annotation model event reporting a world change
+     * @since 3.0
+     */
+    private void updateHighlightRanges(int highlightAnnotationRangeStart, int highlightAnnotationRangeEnd, bool isWorldChange) {
+        if (highlightAnnotationRangeStart !is Integer.MAX_VALUE) {
+
+            int maxRangeStart= highlightAnnotationRangeStart;
+            int maxRangeEnd= highlightAnnotationRangeEnd;
+
+            if (fTotalHighlightAnnotationRange !is null) {
+                maxRangeStart= Math.min(maxRangeStart, fTotalHighlightAnnotationRange.offset);
+                maxRangeEnd= Math.max(maxRangeEnd, fTotalHighlightAnnotationRange.offset + fTotalHighlightAnnotationRange.length);
+            }
+
+            if (fTotalHighlightAnnotationRange is null)
+                fTotalHighlightAnnotationRange= new Position(0);
+            if (fCurrentHighlightAnnotationRange is null)
+                fCurrentHighlightAnnotationRange= new Position(0);
+
+            if (isWorldChange) {
+                fTotalHighlightAnnotationRange.offset= highlightAnnotationRangeStart;
+                fTotalHighlightAnnotationRange.length= highlightAnnotationRangeEnd - highlightAnnotationRangeStart;
+                fCurrentHighlightAnnotationRange.offset= maxRangeStart;
+                fCurrentHighlightAnnotationRange.length= maxRangeEnd - maxRangeStart;
+            } else {
+                fTotalHighlightAnnotationRange.offset= maxRangeStart;
+                fTotalHighlightAnnotationRange.length= maxRangeEnd - maxRangeStart;
+                fCurrentHighlightAnnotationRange.offset=highlightAnnotationRangeStart;
+                fCurrentHighlightAnnotationRange.length= highlightAnnotationRangeEnd - highlightAnnotationRangeStart;
+            }
+        } else {
+            if (isWorldChange) {
+                fCurrentHighlightAnnotationRange= fTotalHighlightAnnotationRange;
+                fTotalHighlightAnnotationRange= null;
+            } else {
+                fCurrentHighlightAnnotationRange= null;
+            }
+        }
+
+        adaptToDocumentLength(fCurrentHighlightAnnotationRange);
+        adaptToDocumentLength(fTotalHighlightAnnotationRange);
+    }
+
+    /**
+     * Updates the remembered decoration ranges.
+     *
+     * @param drawRangeStart    the start of the range
+     * @param drawRangeEnd      the end of the range
+     * @param isWorldChange     tells whether the range belongs to a annotation model event reporting a world change
+     * @since 3.3
+     */
+    private void updateDrawRanges(int drawRangeStart, int drawRangeEnd, bool isWorldChange) {
+        if (drawRangeStart !is Integer.MAX_VALUE) {
+
+            int maxRangeStart= drawRangeStart;
+            int maxRangeEnd= drawRangeEnd;
+
+            if (fTotalDrawRange !is null) {
+                maxRangeStart= Math.min(maxRangeStart, fTotalDrawRange.offset);
+                maxRangeEnd= Math.max(maxRangeEnd, fTotalDrawRange.offset + fTotalDrawRange.length);
+            }
+
+            if (fTotalDrawRange is null)
+                fTotalDrawRange= new Position(0);
+            if (fCurrentDrawRange is null)
+                fCurrentDrawRange= new Position(0);
+
+            if (isWorldChange) {
+                fTotalDrawRange.offset= drawRangeStart;
+                fTotalDrawRange.length= drawRangeEnd - drawRangeStart;
+                fCurrentDrawRange.offset= maxRangeStart;
+                fCurrentDrawRange.length= maxRangeEnd - maxRangeStart;
+            } else {
+                fTotalDrawRange.offset= maxRangeStart;
+                fTotalDrawRange.length= maxRangeEnd - maxRangeStart;
+                fCurrentDrawRange.offset=drawRangeStart;
+                fCurrentDrawRange.length= drawRangeEnd - drawRangeStart;
+            }
+        } else {
+            if (isWorldChange) {
+                fCurrentDrawRange= fTotalDrawRange;
+                fTotalDrawRange= null;
+            } else {
+                fCurrentDrawRange= null;
+            }
+        }
+
+        adaptToDocumentLength(fCurrentDrawRange);
+        adaptToDocumentLength(fTotalDrawRange);
+    }
+
+    /**
+     * Adapts the given position to the document length.
+     *
+     * @param position the position to adapt
+     * @since 3.0
+     */
+    private void adaptToDocumentLength(Position position) {
+        if (position is null)
+            return;
+
+        int length= fSourceViewer.getDocument().getLength();
+        position.offset= Math.min(position.offset, length);
+        position.length= Math.min(position.length, length - position.offset);
+    }
+
+    /**
+     * Returns a decoration for the given annotation if this
+     * annotation is valid and shown by this painter.
+     *
+     * @param annotation            the annotation
+     * @param decoration            the decoration to be adapted and returned or <code>null</code> if a new one must be created
+     * @return the decoration or <code>null</code> if there's no valid one
+     * @since 3.0
+     */
+    private Decoration getDecoration(Annotation annotation, Decoration decoration) {
+
+        if (annotation.isMarkedDeleted())
+            return null;
+
+        String type= annotation.getType();
+
+        Object paintingStrategy= getPaintingStrategy(type);
+        if (paintingStrategy is null || cast(NullStrategy)paintingStrategy )
+            return null;
+
+        Color color= getColor(stringcast(type));
+        if (color is null)
+            return null;
+
+        Position position= fModel.getPosition(annotation);
+        if (position is null || position.isDeleted())
+            return null;
+
+        if (decoration is null)
+            decoration= new Decoration();
+
+        decoration.fPosition= position;
+        decoration.fColor= color;
+        if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) {
+            IAnnotationAccessExtension extension= cast(IAnnotationAccessExtension) fAnnotationAccess;
+            decoration.fLayer= extension.getLayer(annotation);
+        } else {
+            decoration.fLayer= IAnnotationAccessExtension.DEFAULT_LAYER;
+        }
+
+        decoration.fPaintingStrategy= paintingStrategy;
+
+        return decoration;
+    }
+
+    /**
+     * Returns the painting strategy for the given annotation.
+     *
+     * @param type the annotation type
+     * @return the annotation painter
+     * @since 3.0
+     */
+    private Object getPaintingStrategy(String type) {
+        Object strategy= fCachedAnnotationType2PaintingStrategy.get(type);
+        if (strategy !is null)
+            return strategy;
+
+        strategy= fPaintingStrategyId2PaintingStrategy.get(fAnnotationType2PaintingStrategyId.get(type));
+        if (strategy !is null) {
+            fCachedAnnotationType2PaintingStrategy.put(type, strategy);
+            return strategy;
+        }
+
+        if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) {
+            IAnnotationAccessExtension ext = cast(IAnnotationAccessExtension) fAnnotationAccess;
+            Object[] sts = ext.getSupertypes(stringcast(type));
+            for (int i= 0; i < sts.length; i++) {
+                strategy= fPaintingStrategyId2PaintingStrategy.get(fAnnotationType2PaintingStrategyId.get(sts[i]));
+                if (strategy !is null) {
+                    fCachedAnnotationType2PaintingStrategy.put(type, strategy);
+                    return strategy;
+                }
+            }
+        }
+
+        fCachedAnnotationType2PaintingStrategy.put(type, cast(Object)NULL_STRATEGY);
+        return null;
+
+    }
+
+    /**
+     * Returns the color for the given annotation type
+     *
+     * @param annotationType the annotation type
+     * @return the color
+     * @since 3.0
+     */
+    private Color getColor(Object annotationType) {
+        Color color= cast(Color)fCachedAnnotationType2Color.get(annotationType);
+        if (color !is null)
+            return color;
+
+        color= cast(Color)fAnnotationType2Color.get(annotationType);
+        if (color !is null) {
+            fCachedAnnotationType2Color.put(annotationType, color);
+            return color;
+        }
+
+        if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) {
+            IAnnotationAccessExtension extension= cast(IAnnotationAccessExtension) fAnnotationAccess;
+            Object[] superTypes= extension.getSupertypes(annotationType);
+            if (superTypes !is null) {
+                for (int i= 0; i < superTypes.length; i++) {
+                    color= cast(Color)fAnnotationType2Color.get(superTypes[i]);
+                    if (color !is null) {
+                        fCachedAnnotationType2Color.put(annotationType, color);
+                        return color;
+                    }
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Recomputes the squiggles to be drawn and redraws them.
+     *
+     * @param event the annotation model event
+     * @since 3.0
+     */
+    private void updatePainting(AnnotationModelEvent event) {
+        disablePainting(event is null);
+
+        catchupWithModel(event);
+
+        if (!fInputDocumentAboutToBeChanged)
+            invalidateTextPresentation();
+
+        enablePainting();
+    }
+
+    private void invalidateTextPresentation() {
+        IRegion r= null;
+        synchronized (fHighlightedDecorationsMapLock) {
+            if (fCurrentHighlightAnnotationRange !is null)
+                r= new Region(fCurrentHighlightAnnotationRange.getOffset(), fCurrentHighlightAnnotationRange.getLength());
+        }
+        if (r is null)
+            return;
+
+        if ( cast(ITextViewerExtension2)fSourceViewer ) {
+            if (DEBUG)
+                System.out_.println(Format("AP: invalidating offset: {}, length= {}", r.getOffset(), r.getLength())); //$NON-NLS-1$ //$NON-NLS-2$
+
+            (cast(ITextViewerExtension2)fSourceViewer).invalidateTextPresentation(r.getOffset(), r.getLength());
+
+        } else {
+            fSourceViewer.invalidateTextPresentation();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextPresentationListener#applyTextPresentation(dwtx.jface.text.TextPresentation)
+     * @since 3.0
+     */
+    public void applyTextPresentation(TextPresentation tp) {
+        Set decorations;
+
+        synchronized (fHighlightedDecorationsMapLock) {
+            if (fHighlightedDecorationsMap is null || fHighlightedDecorationsMap.isEmpty())
+                return;
+
+            decorations= new HashSet(fHighlightedDecorationsMap.entrySet());
+        }
+
+        IRegion region= tp.getExtent();
+
+        if (DEBUG)
+            System.out_.println(Format("AP: applying text presentation offset: {}, length= {}", region.getOffset(), region.getLength())); //$NON-NLS-1$ //$NON-NLS-2$
+
+        for (int layer= 0, maxLayer= 1; layer < maxLayer; layer++) {
+
+            for (Iterator iter= decorations.iterator(); iter.hasNext();) {
+                Map.Entry entry= cast(Map.Entry)iter.next();
+
+                Annotation a= cast(Annotation)entry.getKey();
+                if (a.isMarkedDeleted())
+                    continue;
+
+                Decoration pp = cast(Decoration)entry.getValue();
+
+                maxLayer= Math.max(maxLayer, pp.fLayer + 1); // dynamically update layer maximum
+                if (pp.fLayer !is layer) // wrong layer: skip annotation
+                    continue;
+
+                Position p= pp.fPosition;
+                if ( cast(ITextViewerExtension5)fSourceViewer ) {
+                    ITextViewerExtension5 extension3= cast(ITextViewerExtension5) fSourceViewer;
+                    if (null is extension3.modelRange2WidgetRange(new Region(p.getOffset(), p.getLength())))
+                        continue;
+                } else if (!fSourceViewer.overlapsWithVisibleRegion(p.offset, p.length)) {
+                    continue;
+                }
+
+                int regionEnd= region.getOffset() + region.getLength();
+                int pEnd= p.getOffset() + p.getLength();
+                if (pEnd >= region.getOffset() && regionEnd > p.getOffset()) {
+                    int start= Math.max(p.getOffset(), region.getOffset());
+                    int end= Math.min(regionEnd, pEnd);
+                    int length= Math.max(end - start, 0);
+                    StyleRange styleRange= new StyleRange(start, length, null, null);
+                    (cast(ITextStyleStrategy)pp.fPaintingStrategy).applyTextStyle(styleRange, pp.fColor);
+                    tp.mergeStyleRange(styleRange);
+                }
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModelListener#modelChanged(dwtx.jface.text.source.IAnnotationModel)
+     */
+    public synchronized void modelChanged(IAnnotationModel model) {
+        if (DEBUG)
+            System.err.println("AP: OLD API of AnnotationModelListener called"); //$NON-NLS-1$
+
+        modelChanged(new AnnotationModelEvent(model));
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationModelListenerExtension#modelChanged(dwtx.jface.text.source.AnnotationModelEvent)
+     */
+    public void modelChanged(AnnotationModelEvent event) {
+        Display textWidgetDisplay;
+        try {
+            StyledText textWidget= fTextWidget;
+            if (textWidget is null || textWidget.isDisposed())
+                return;
+            textWidgetDisplay= textWidget.getDisplay();
+        } catch (DWTException ex) {
+            if (ex.code is DWT.ERROR_WIDGET_DISPOSED)
+                return;
+            throw ex;
+        }
+
+        if (fIsSettingModel) {
+            // inside the UI thread -> no need for posting
+            if (textWidgetDisplay is Display.getCurrent())
+                updatePainting(event);
+            else {
+                /*
+                 * we can throw away the changes since
+                 * further update painting will happen
+                 */
+                return;
+            }
+        } else {
+            if (DEBUG && event !is null && event.isWorldChange()) {
+                System.out_.println("AP: WORLD CHANGED, stack trace follows:"); //$NON-NLS-1$
+                ExceptionPrintStackTrace( new Exception(""), Stdout );
+            }
+
+            // XXX: posting here is a problem for annotations that are being
+            // removed and the positions of which are not updated to document
+            // changes any more. If the document gets modified between
+            // now and running the posted runnable, the position information
+            // is not accurate any longer.
+            textWidgetDisplay.asyncExec( dgRunnable( (AnnotationModelEvent event_){
+                if (fTextWidget !is null && !fTextWidget.isDisposed())
+                    updatePainting(event_);
+            }, event ));
+        }
+    }
+
+    /**
+     * Sets the color in which the squiggly for the given annotation type should be drawn.
+     *
+     * @param annotationType the annotation type
+     * @param color the color
+     */
+    public void setAnnotationTypeColor(Object annotationType, Color color) {
+        if (color !is null)
+            fAnnotationType2Color.put(annotationType, color);
+        else
+            fAnnotationType2Color.remove(annotationType);
+        fCachedAnnotationType2Color.clear();
+    }
+
+    /**
+     * Adds the given annotation type to the list of annotation types whose
+     * annotations should be painted by this painter using squiggly drawing. If the annotation  type
+     * is already in this list, this method is without effect.
+     *
+     * @param annotationType the annotation type
+     */
+    public void addAnnotationType(Object annotationType) {
+        addAnnotationType(annotationType, SQUIGGLES);
+    }
+
+    /**
+     * Adds the given annotation type to the list of annotation types whose
+     * annotations should be painted by this painter using the given drawing strategy.
+     * If the annotation type is already in this list, the old drawing strategy gets replaced.
+     *
+     * @param annotationType the annotation type
+     * @param drawingStrategyID the id of the drawing strategy that should be used for this annotation type
+     * @since 3.0
+     */
+    public void addAnnotationType(Object annotationType, Object drawingStrategyID) {
+        fAnnotationType2PaintingStrategyId.put(annotationType, drawingStrategyID);
+        fCachedAnnotationType2PaintingStrategy.clear();
+
+        if (fTextInputListener is null) {
+            fTextInputListener= new class()  ITextInputListener {
+
+                /*
+                 * @see dwtx.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument)
+                 */
+                public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
+                    fInputDocumentAboutToBeChanged= true;
+                }
+
+                /*
+                 * @see dwtx.jface.text.ITextInputListener#inputDocumentChanged(dwtx.jface.text.IDocument, dwtx.jface.text.IDocument)
+                 */
+                public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+                    fInputDocumentAboutToBeChanged= false;
+                }
+            };
+            fSourceViewer.addTextInputListener(fTextInputListener);
+        }
+
+    }
+
+    /**
+     * Registers a new drawing strategy under the given ID. If there is already a
+     * strategy registered under <code>id</code>, the old strategy gets replaced.
+     * <p>The given id can be referenced when adding annotation types, see
+     * {@link #addAnnotationType(Object, Object)}.</p>
+     *
+     * @param id the identifier under which the strategy can be referenced, not <code>null</code>
+     * @param strategy the new strategy
+     * @since 3.0
+     */
+    public void addDrawingStrategy(Object id, IDrawingStrategy strategy) {
+        // don't permit null as null is used to signal that an annotation type is not
+        // registered with a specific strategy, and that its annotation hierarchy should be searched
+        if (id is null)
+            throw new IllegalArgumentException(null);
+        fPaintingStrategyId2PaintingStrategy.put(id, cast(Object)strategy);
+        fCachedAnnotationType2PaintingStrategy.clear();
+    }
+
+    /**
+     * Registers a new drawing strategy under the given ID. If there is already
+     * a strategy registered under <code>id</code>, the old strategy gets
+     * replaced.
+     * <p>
+     * The given id can be referenced when adding annotation types, see
+     * {@link #addAnnotationType(Object, Object)}.
+     * </p>
+     *
+     * @param id the identifier under which the strategy can be referenced, not <code>null</code>
+     * @param strategy the new strategy
+     * @since 3.4
+     */
+    public void addTextStyleStrategy(Object id, ITextStyleStrategy strategy) {
+        // don't permit null as null is used to signal that an annotation type is not
+        // registered with a specific strategy, and that its annotation hierarchy should be searched
+        if (id is null)
+            throw new IllegalArgumentException(null);
+        fPaintingStrategyId2PaintingStrategy.put(id, cast(Object)strategy);
+        fCachedAnnotationType2PaintingStrategy.clear();
+    }
+
+    /**
+     * Adds the given annotation type to the list of annotation types whose
+     * annotations should be highlighted this painter. If the annotation  type
+     * is already in this list, this method is without effect.
+     *
+     * @param annotationType the annotation type
+     * @since 3.0
+     */
+    public void addHighlightAnnotationType(Object annotationType) {
+        addAnnotationType(annotationType, HIGHLIGHTING);
+    }
+
+    /**
+     * Removes the given annotation type from the list of annotation types whose
+     * annotations are painted by this painter. If the annotation type is not
+     * in this list, this method is without effect.
+     *
+     * @param annotationType the annotation type
+     */
+    public void removeAnnotationType(Object annotationType) {
+        fCachedAnnotationType2PaintingStrategy.clear();
+        fAnnotationType2PaintingStrategyId.remove(annotationType);
+        if (fAnnotationType2PaintingStrategyId.isEmpty() && fTextInputListener !is null) {
+            fSourceViewer.removeTextInputListener(fTextInputListener);
+            fTextInputListener= null;
+            fInputDocumentAboutToBeChanged= false;
+        }
+    }
+
+    /**
+     * Removes the given annotation type from the list of annotation types whose
+     * annotations are highlighted by this painter. If the annotation type is not
+     * in this list, this method is without effect.
+     *
+     * @param annotationType the annotation type
+     * @since 3.0
+     */
+    public void removeHighlightAnnotationType(Object annotationType) {
+        removeAnnotationType(annotationType);
+    }
+
+    /**
+     * Clears the list of annotation types whose annotations are
+     * painted by this painter.
+     */
+    public void removeAllAnnotationTypes() {
+        fCachedAnnotationType2PaintingStrategy.clear();
+        fAnnotationType2PaintingStrategyId.clear();
+        if (fTextInputListener !is null) {
+            fSourceViewer.removeTextInputListener(fTextInputListener);
+            fTextInputListener= null;
+        }
+    }
+
+    /**
+     * Returns whether the list of annotation types whose annotations are painted
+     * by this painter contains at least on element.
+     *
+     * @return <code>true</code> if there is an annotation type whose annotations are painted
+     */
+    public bool isPaintingAnnotations() {
+        return !fAnnotationType2PaintingStrategyId.isEmpty();
+    }
+
+    /*
+     * @see dwtx.jface.text.IPainter#dispose()
+     */
+    public void dispose() {
+
+        if (fAnnotationType2Color !is null) {
+            fAnnotationType2Color.clear();
+            fAnnotationType2Color= null;
+        }
+
+        if (fCachedAnnotationType2Color !is null) {
+            fCachedAnnotationType2Color.clear();
+            fCachedAnnotationType2Color= null;
+        }
+
+        if (fCachedAnnotationType2PaintingStrategy !is null) {
+            fCachedAnnotationType2PaintingStrategy.clear();
+            fCachedAnnotationType2PaintingStrategy= null;
+        }
+
+        if (fAnnotationType2PaintingStrategyId !is null) {
+            fAnnotationType2PaintingStrategyId.clear();
+            fAnnotationType2PaintingStrategyId= null;
+        }
+
+        fTextWidget= null;
+        fSourceViewer= null;
+        fAnnotationAccess= null;
+        fModel= null;
+        synchronized (fDecorationMapLock) {
+            fDecorationsMap= null;
+        }
+        synchronized (fHighlightedDecorationsMapLock) {
+            fHighlightedDecorationsMap= null;
+        }
+    }
+
+    /**
+     * Returns the document offset of the upper left corner of the source viewer's view port,
+     * possibly including partially visible lines.
+     *
+     * @return the document offset if the upper left corner of the view port
+     */
+    private int getInclusiveTopIndexStartOffset() {
+
+        if (fTextWidget !is null && !fTextWidget.isDisposed()) {
+            int top= JFaceTextUtil.getPartialTopIndex(fSourceViewer);
+            try {
+                IDocument document= fSourceViewer.getDocument();
+                return document.getLineOffset(top);
+            } catch (BadLocationException x) {
+            }
+        }
+
+        return -1;
+    }
+
+    /**
+     * Returns the first invisible document offset of the lower right corner of the source viewer's view port,
+     * possibly including partially visible lines.
+     *
+     * @return the first invisible document offset of the lower right corner of the view port
+     */
+    private int getExclusiveBottomIndexEndOffset() {
+
+        if (fTextWidget !is null && !fTextWidget.isDisposed()) {
+            int bottom= JFaceTextUtil.getPartialBottomIndex(fSourceViewer);
+            try {
+                IDocument document= fSourceViewer.getDocument();
+
+                if (bottom >= document.getNumberOfLines())
+                    bottom= document.getNumberOfLines() - 1;
+
+                return document.getLineOffset(bottom) + document.getLineLength(bottom);
+            } catch (BadLocationException x) {
+            }
+        }
+
+        return -1;
+    }
+
+    /*
+     * @see dwt.events.PaintListener#paintControl(dwt.events.PaintEvent)
+     */
+    public void paintControl(PaintEvent event) {
+        if (fTextWidget !is null)
+            handleDrawRequest(event);
+    }
+
+    /**
+     * Handles the request to draw the annotations using the given graphical context.
+     *
+     * @param event the paint event or <code>null</code>
+     */
+    private void handleDrawRequest(PaintEvent event) {
+
+        if (fTextWidget is null) {
+            // is already disposed
+            return;
+        }
+
+        IRegion clippingRegion= computeClippingRegion(event, false);
+        if (clippingRegion is null)
+            return;
+
+        int vOffset= clippingRegion.getOffset();
+        int vLength= clippingRegion.getLength();
+
+        final GC gc= event !is null ? event.gc : null;
+
+        // Clone decorations
+        Collection decorations;
+        synchronized (fDecorationMapLock) {
+            decorations= new ArrayList(fDecorationsMap.size());
+            decorations.addAll(fDecorationsMap.entrySet());
+        }
+
+        /*
+         * Create a new list of annotations to be drawn, since removing from decorations is more
+         * expensive. One bucket per drawing layer. Use linked lists as addition is cheap here.
+         */
+        ArrayList toBeDrawn= new ArrayList(10);
+        for (Iterator e = decorations.iterator(); e.hasNext();) {
+            Map.Entry entry= cast(Map.Entry)e.next();
+
+            Annotation a= cast(Annotation)entry.getKey();
+            Decoration pp = cast(Decoration)entry.getValue();
+            // prune any annotation that is not drawable or does not need drawing
+            if (!(a.isMarkedDeleted() || skip(a) || !pp.fPosition.overlapsWith(vOffset, vLength))) {
+                // ensure sized appropriately
+                for (int i= toBeDrawn.size(); i <= pp.fLayer; i++)
+                    toBeDrawn.add(new LinkedList());
+                (cast(List) toBeDrawn.get(pp.fLayer)).add(cast(Object)entry);
+            }
+        }
+        IDocument document= fSourceViewer.getDocument();
+        for (Iterator it= toBeDrawn.iterator(); it.hasNext();) {
+            List layer= cast(List) it.next();
+            for (Iterator e = layer.iterator(); e.hasNext();) {
+                Map.Entry entry= cast(Map.Entry)e.next();
+                Annotation a= cast(Annotation)entry.getKey();
+                Decoration pp = cast(Decoration)entry.getValue();
+                drawDecoration(pp, gc, a, clippingRegion, document);
+            }
+        }
+    }
+
+    private void drawDecoration(Decoration pp, GC gc, Annotation annotation, IRegion clippingRegion, IDocument document) {
+        if (clippingRegion is null)
+            return;
+
+        if (!(cast(IDrawingStrategy)pp.fPaintingStrategy ))
+            return;
+
+        IDrawingStrategy drawingStrategy= cast(IDrawingStrategy)pp.fPaintingStrategy;
+
+        int clippingOffset= clippingRegion.getOffset();
+        int clippingLength= clippingRegion.getLength();
+
+        Position p= pp.fPosition;
+        try {
+
+            int startLine= document.getLineOfOffset(p.getOffset());
+            int lastInclusive= Math.max(p.getOffset(), p.getOffset() + p.getLength() - 1);
+            int endLine= document.getLineOfOffset(lastInclusive);
+
+            for (int i= startLine; i <= endLine; i++) {
+                int lineOffset= document.getLineOffset(i);
+                int paintStart= Math.max(lineOffset, p.getOffset());
+                String lineDelimiter= document.getLineDelimiter(i);
+                int delimiterLength= lineDelimiter !is null ? lineDelimiter.length() : 0;
+                int paintLength= Math.min(lineOffset + document.getLineLength(i) - delimiterLength, p.getOffset() + p.getLength()) - paintStart;
+                if (paintLength >= 0 && overlapsWith(paintStart, paintLength, clippingOffset, clippingLength)) {
+                    // otherwise inside a line delimiter
+                    IRegion widgetRange= getWidgetRange(paintStart, paintLength);
+                    if (widgetRange !is null) {
+                        drawingStrategy.draw(annotation, gc, fTextWidget, widgetRange.getOffset(), widgetRange.getLength(), pp.fColor);
+                    }
+                }
+            }
+
+        } catch (BadLocationException x) {
+        }
+    }
+
+    /**
+     * Computes the model (document) region that is covered by the paint event's clipping region. If
+     * <code>event</code> is <code>null</code>, the model range covered by the visible editor
+     * area (viewport) is returned.
+     *
+     * @param event the paint event or <code>null</code> to use the entire viewport
+     * @param isClearing tells whether the clipping is need for clearing an annotation
+     * @return the model region comprised by either the paint event's clipping region or the
+     *         viewport
+     * @since 3.2
+     */
+    private IRegion computeClippingRegion(PaintEvent event, bool isClearing) {
+        if (event is null) {
+
+            if (!isClearing && fCurrentDrawRange !is null)
+                return new Region(fCurrentDrawRange.offset, fCurrentDrawRange.length);
+
+            // trigger a repaint of the entire viewport
+            int vOffset= getInclusiveTopIndexStartOffset();
+            if (vOffset is -1)
+                return null;
+
+            // http://bugs.eclipse.org/bugs/show_bug.cgi?id=17147
+            int vLength= getExclusiveBottomIndexEndOffset() - vOffset;
+
+            return new Region(vOffset, vLength);
+        }
+
+        int widgetOffset;
+        try {
+            int widgetClippingStartOffset= fTextWidget.getOffsetAtLocation(new Point(0, event.y));
+            int firstWidgetLine= fTextWidget.getLineAtOffset(widgetClippingStartOffset);
+            widgetOffset= fTextWidget.getOffsetAtLine(firstWidgetLine);
+        } catch (IllegalArgumentException ex1) {
+            try {
+                int firstVisibleLine= JFaceTextUtil.getPartialTopIndex(fTextWidget);
+                widgetOffset= fTextWidget.getOffsetAtLine(firstVisibleLine);
+            } catch (IllegalArgumentException ex2) { // above try code might fail too
+                widgetOffset= 0;
+            }
+        }
+
+        int widgetEndOffset;
+        try {
+            int widgetClippingEndOffset= fTextWidget.getOffsetAtLocation(new Point(0, event.y + event.height));
+            int lastWidgetLine= fTextWidget.getLineAtOffset(widgetClippingEndOffset);
+            widgetEndOffset= fTextWidget.getOffsetAtLine(lastWidgetLine + 1);
+        } catch (IllegalArgumentException ex1) {
+            // happens if the editor is not "full", e.g. the last line of the document is visible in the editor
+            try {
+                int lastVisibleLine= JFaceTextUtil.getPartialBottomIndex(fTextWidget);
+                if (lastVisibleLine is fTextWidget.getLineCount() - 1)
+                    // last line
+                    widgetEndOffset= fTextWidget.getCharCount();
+                else
+                    widgetEndOffset= fTextWidget.getOffsetAtLine(lastVisibleLine + 1) - 1;
+            } catch (IllegalArgumentException ex2) { // above try code might fail too
+                widgetEndOffset= fTextWidget.getCharCount();
+            }
+        }
+
+        IRegion clippingRegion= getModelRange(widgetOffset, widgetEndOffset - widgetOffset);
+
+        return clippingRegion;
+    }
+
+    /**
+     * Should the given annotation be skipped when handling draw requests?
+     *
+     * @param annotation the annotation
+     * @return <code>true</code> iff the given annotation should be
+     *         skipped when handling draw requests
+     * @since 3.0
+     */
+    protected bool skip(Annotation annotation) {
+        return false;
+    }
+
+    /**
+     * Returns the widget region that corresponds to the
+     * given offset and length in the viewer's document.
+     *
+     * @param modelOffset the model offset
+     * @param modelLength the model length
+     * @return the corresponding widget region
+     */
+    private IRegion getWidgetRange(int modelOffset, int modelLength) {
+        fReusableRegion.setOffset(modelOffset);
+        fReusableRegion.setLength(modelLength);
+
+        if (fReusableRegion is null || fReusableRegion.getOffset() is Integer.MAX_VALUE)
+            return null;
+
+        if ( cast(ITextViewerExtension5)fSourceViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) fSourceViewer;
+            return extension.modelRange2WidgetRange(fReusableRegion);
+        }
+
+        IRegion region= fSourceViewer.getVisibleRegion();
+        int offset= region.getOffset();
+        int length= region.getLength();
+
+        if (overlapsWith(fReusableRegion, region)) {
+            int p1= Math.max(offset, fReusableRegion.getOffset());
+            int p2= Math.min(offset + length, fReusableRegion.getOffset() + fReusableRegion.getLength());
+            return new Region(p1 - offset, p2 - p1);
+        }
+        return null;
+    }
+
+    /**
+     * Returns the model region that corresponds to the given region in the
+     * viewer's text widget.
+     *
+     * @param offset the offset in the viewer's widget
+     * @param length the length in the viewer's widget
+     * @return the corresponding document region
+     * @since 3.2
+     */
+    private IRegion getModelRange(int offset, int length) {
+        if (offset is Integer.MAX_VALUE)
+            return null;
+
+        if ( cast(ITextViewerExtension5)fSourceViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) fSourceViewer;
+            return extension.widgetRange2ModelRange(new Region(offset, length));
+        }
+
+        IRegion region= fSourceViewer.getVisibleRegion();
+        return new Region(region.getOffset() + offset, length);
+    }
+
+    /**
+     * Checks whether the intersection of the given text ranges
+     * is empty or not.
+     *
+     * @param range1 the first range to check
+     * @param range2 the second range to check
+     * @return <code>true</code> if intersection is not empty
+     */
+    private bool overlapsWith(IRegion range1, IRegion range2) {
+        return overlapsWith(range1.getOffset(), range1.getLength(), range2.getOffset(), range2.getLength());
+    }
+
+    /**
+     * Checks whether the intersection of the given text ranges
+     * is empty or not.
+     *
+     * @param offset1 offset of the first range
+     * @param length1 length of the first range
+     * @param offset2 offset of the second range
+     * @param length2 length of the second range
+     * @return <code>true</code> if intersection is not empty
+     */
+    private bool overlapsWith(int offset1, int length1, int offset2, int length2) {
+        int end= offset2 + length2;
+        int thisEnd= offset1 + length1;
+
+        if (length2 > 0) {
+            if (length1 > 0)
+                return offset1 < end && offset2 < thisEnd;
+            return  offset2 <= offset1 && offset1 < end;
+        }
+
+        if (length1 > 0)
+            return offset1 <= offset2 && offset2 < thisEnd;
+        return offset1 is offset2;
+    }
+
+    /*
+     * @see dwtx.jface.text.IPainter#deactivate(bool)
+     */
+    public void deactivate(bool redraw) {
+        if (fIsActive) {
+            fIsActive= false;
+            disablePainting(redraw);
+            setModel(null);
+            catchupWithModel(null);
+        }
+    }
+
+    /**
+     * Returns whether the given reason causes a repaint.
+     *
+     * @param reason the reason
+     * @return <code>true</code> if repaint reason, <code>false</code> otherwise
+     * @since 3.0
+     */
+    protected bool isRepaintReason(int reason) {
+        return CONFIGURATION is reason || INTERNAL is reason;
+    }
+
+    /**
+     * Retrieves the annotation model from the given source viewer.
+     *
+     * @param sourceViewer the source viewer
+     * @return the source viewer's annotation model or <code>null</code> if none can be found
+     * @since 3.0
+     */
+    protected IAnnotationModel findAnnotationModel(ISourceViewer sourceViewer) {
+        if(sourceViewer !is null)
+            return sourceViewer.getAnnotationModel();
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.IPainter#paint(int)
+     */
+    public void paint(int reason) {
+        if (fSourceViewer.getDocument() is null) {
+            deactivate(false);
+            return;
+        }
+
+        if (!fIsActive) {
+            IAnnotationModel model= findAnnotationModel(fSourceViewer);
+            if (model !is null) {
+                fIsActive= true;
+                setModel(model);
+            }
+        } else if (isRepaintReason(reason))
+            updatePainting(null);
+    }
+
+    /*
+     * @see dwtx.jface.text.IPainter#setPositionManager(dwtx.jface.text.IPaintPositionManager)
+     */
+    public void setPositionManager(IPaintPositionManager manager) {
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/AnnotationRulerColumn.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1042 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Nikolay Botev <bono8106@hotmail.com> - [projection] Editor loses keyboard focus when expanding folded region - https://bugs.eclipse.org/bugs/show_bug.cgi?id=184255
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.AnnotationRulerColumn;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+
+
+
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.events.MouseMoveListener;
+import dwt.events.PaintEvent;
+import dwt.events.PaintListener;
+import dwt.graphics.Cursor;
+import dwt.graphics.Font;
+import dwt.graphics.GC;
+import dwt.graphics.Image;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Canvas;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextListener;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.IViewportListener;
+import dwtx.jface.text.JFaceTextUtil;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.TextEvent;
+
+
+/**
+ * A vertical ruler column showing graphical representations of annotations.
+ * Will become final.
+ * <p>
+ * Do not subclass.
+ * </p>
+ *
+ * @since 2.0
+ */
+public class AnnotationRulerColumn : IVerticalRulerColumn, IVerticalRulerInfo, IVerticalRulerInfoExtension {
+
+    /**
+     * Internal listener class.
+     */
+    class InternalListener : IViewportListener, IAnnotationModelListener, ITextListener {
+
+        /*
+         * @see IViewportListener#viewportChanged(int)
+         */
+        public void viewportChanged(int verticalPosition) {
+            if (verticalPosition !is fScrollPos)
+                redraw();
+        }
+
+        /*
+         * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
+         */
+        public void modelChanged(IAnnotationModel model) {
+            postRedraw();
+        }
+
+        /*
+         * @see ITextListener#textChanged(TextEvent)
+         */
+        public void textChanged(TextEvent e) {
+            if (e.getViewerRedrawState())
+                postRedraw();
+        }
+    }
+
+    /**
+     * Implementation of <code>IRegion</code> that can be reused
+     * by setting the offset and the length.
+     */
+    private static class ReusableRegion : Position , IRegion {
+        public override int getLength(){
+            return super.getLength();
+        }
+        public override int getOffset(){
+            return super.getOffset();
+        }
+    }
+
+    /**
+     * Pair of an annotation and their associated position. Used inside the paint method
+     * for sorting annotations based on the offset of their position.
+     * @since 3.0
+     */
+    private static class Tuple {
+        Annotation annotation;
+        Position position;
+
+        this(Annotation annotation, Position position) {
+            this.annotation= annotation;
+            this.position= position;
+        }
+    }
+
+    /**
+     * Comparator for <code>Tuple</code>s.
+     * @since 3.0
+     */
+    private static class TupleComparator : Comparator {
+        /*
+         * @see java.util.Comparator#compare(java.lang.Object, java.lang.Object)
+         */
+        public int compare(Object o1, Object o2) {
+            Position p1= (cast(Tuple) o1).position;
+            Position p2= (cast(Tuple) o2).position;
+            return p1.getOffset() - p2.getOffset();
+        }
+    }
+
+    /** This column's parent ruler */
+    private CompositeRuler fParentRuler;
+    /** The cached text viewer */
+    private ITextViewer fCachedTextViewer;
+    /** The cached text widget */
+    private StyledText fCachedTextWidget;
+    /** The ruler's canvas */
+    private Canvas fCanvas;
+    /** The vertical ruler's model */
+    private IAnnotationModel fModel;
+    /** Cache for the actual scroll position in pixels */
+    private int fScrollPos;
+    /** The buffer for double buffering */
+    private Image fBuffer;
+    /** The internal listener */
+    private InternalListener fInternalListener;
+    /** The width of this vertical ruler */
+    private int fWidth;
+    /** Switch for enabling/disabling the setModel method. */
+    private bool fAllowSetModel= true;
+    /**
+     * The list of annotation types to be shown in this ruler.
+     * @since 3.0
+     */
+    private Set fConfiguredAnnotationTypes;
+    /**
+     * The list of allowed annotation types to be shown in this ruler.
+     * An allowed annotation type maps to <code>true</code>, a disallowed
+     * to <code>false</code>.
+     * @since 3.0
+     */
+    private Map fAllowedAnnotationTypes;
+    /**
+     * The annotation access extension.
+     * @since 3.0
+     */
+    private IAnnotationAccessExtension fAnnotationAccessExtension;
+    /**
+     * The hover for this column.
+     * @since 3.0
+     */
+    private IAnnotationHover fHover;
+    /**
+     * The cached annotations.
+     * @since 3.0
+     */
+    private List fCachedAnnotations;
+    /**
+     * The comparator for sorting annotations according to the offset of their position.
+     * @since 3.0
+     */
+    private Comparator fTupleComparator;
+    /**
+     * The hit detection cursor.
+     * @since 3.0
+     */
+    private Cursor fHitDetectionCursor;
+    /**
+     * The last cursor.
+     * @since 3.0
+     */
+    private Cursor fLastCursor;
+    /**
+     * This ruler's mouse listener.
+     * @since 3.0
+     */
+    private MouseListener fMouseListener;
+
+    private void instanceInit(){
+        fInternalListener= new InternalListener();
+        fConfiguredAnnotationTypes= new HashSet();
+        fAllowedAnnotationTypes= new HashMap();
+        fCachedAnnotations= new ArrayList();
+        fTupleComparator= new TupleComparator();
+    }
+    /**
+     * Constructs this column with the given arguments.
+     *
+     * @param model the annotation model to get the annotations from
+     * @param width the width of the vertical ruler
+     * @param annotationAccess the annotation access
+     * @since 3.0
+     */
+    public this(IAnnotationModel model, int width, IAnnotationAccess annotationAccess) {
+        this(width, annotationAccess);
+        fAllowSetModel= false;
+        fModel= model;
+        fModel.addAnnotationModelListener(fInternalListener);
+    }
+
+    /**
+     * Constructs this column with the given arguments.
+     *
+     * @param width the width of the vertical ruler
+     * @param annotationAccess the annotation access
+     * @since 3.0
+     */
+    public this(int width, IAnnotationAccess annotationAccess) {
+        instanceInit();
+        fWidth= width;
+        if ( cast(IAnnotationAccessExtension)annotationAccess )
+            fAnnotationAccessExtension= cast(IAnnotationAccessExtension) annotationAccess;
+    }
+
+    /**
+     * Constructs this column with the given arguments.
+     *
+     * @param model the annotation model to get the annotations from
+     * @param width the width of the vertical ruler
+     */
+    public this(IAnnotationModel model, int width) {
+        instanceInit();
+        fWidth= width;
+        fAllowSetModel= false;
+        fModel= model;
+        fModel.addAnnotationModelListener(fInternalListener);
+    }
+
+    /**
+     * Constructs this column with the given width.
+     *
+     * @param width the width of the vertical ruler
+     */
+    public this(int width) {
+        instanceInit();
+        fWidth= width;
+    }
+
+    /*
+     * @see IVerticalRulerColumn#getControl()
+     */
+    public Control getControl() {
+        return fCanvas;
+    }
+
+    /*
+     * @see IVerticalRulerColumn#getWidth()
+     */
+    public int getWidth() {
+        return fWidth;
+    }
+
+    /*
+     * @see IVerticalRulerColumn#createControl(CompositeRuler, Composite)
+     */
+    public Control createControl(CompositeRuler parentRuler, Composite parentControl) {
+
+        fParentRuler= parentRuler;
+        fCachedTextViewer= parentRuler.getTextViewer();
+        fCachedTextWidget= fCachedTextViewer.getTextWidget();
+
+        fHitDetectionCursor= new Cursor(parentControl.getDisplay(), DWT.CURSOR_HAND);
+
+        fCanvas= createCanvas(parentControl);
+
+        fCanvas.addPaintListener(new class()  PaintListener {
+            public void paintControl(PaintEvent event) {
+                if (fCachedTextViewer !is null)
+                    doubleBufferPaint(event.gc);
+            }
+        });
+
+        fCanvas.addDisposeListener(new class()  DisposeListener {
+            public void widgetDisposed(DisposeEvent e) {
+                handleDispose();
+                fCachedTextViewer= null;
+                fCachedTextWidget= null;
+            }
+        });
+
+        fMouseListener= new class()  MouseListener {
+            public void mouseUp(MouseEvent event) {
+                int lineNumber;
+                if (isPropagatingMouseListener()) {
+                    fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+                    lineNumber= fParentRuler.getLineOfLastMouseButtonActivity();
+                } else
+                    lineNumber= fParentRuler.toDocumentLineNumber(event.y);
+
+                if (1 is event.button)
+                    mouseClicked(lineNumber);
+            }
+
+            public void mouseDown(MouseEvent event) {
+                if (isPropagatingMouseListener())
+                    fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+            }
+
+            public void mouseDoubleClick(MouseEvent event) {
+                int lineNumber;
+                if (isPropagatingMouseListener()) {
+                    fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+                    lineNumber= fParentRuler.getLineOfLastMouseButtonActivity();
+                } else
+                    lineNumber= fParentRuler.toDocumentLineNumber(event.y);
+
+                if (1 is event.button)
+                    mouseDoubleClicked(lineNumber);
+            }
+        };
+        fCanvas.addMouseListener(fMouseListener);
+
+        fCanvas.addMouseMoveListener(new class()  MouseMoveListener {
+            /*
+             * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent)
+             * @since 3.0
+             */
+            public void mouseMove(MouseEvent e) {
+                handleMouseMove(e);
+            }
+        });
+
+        if (fCachedTextViewer !is null) {
+            fCachedTextViewer.addViewportListener(fInternalListener);
+            fCachedTextViewer.addTextListener(fInternalListener);
+        }
+
+        return fCanvas;
+    }
+
+    /**
+     * Creates a canvas with the given parent.
+     *
+     * @param parent the parent
+     * @return the created canvas
+     */
+    private Canvas createCanvas(Composite parent) {
+        return new class(parent, DWT.NO_BACKGROUND | DWT.NO_FOCUS)  Canvas {
+            this( Composite p, int s ){
+                super(p,s);
+            }
+            /*
+             * @see dwt.widgets.Control#addMouseListener(dwt.events.MouseListener)
+             * @since 3.0
+             */
+            public void addMouseListener(MouseListener listener) {
+                if (isPropagatingMouseListener() || listener is fMouseListener)
+                    super.addMouseListener(listener);
+            }
+        };
+    }
+
+    /**
+     * Tells whether this ruler column propagates mouse listener
+     * events to its parent.
+     *
+     * @return <code>true</code> if propagating to parent
+     * @since 3.0
+     */
+    protected bool isPropagatingMouseListener() {
+        return true;
+    }
+
+    /**
+     * Hook method for a mouse double click event on the given ruler line.
+     *
+     * @param rulerLine the ruler line
+     */
+    protected void mouseDoubleClicked(int rulerLine) {
+    }
+
+    /**
+     * Hook method for a mouse click event on the given ruler line.
+     *
+     * @param rulerLine the ruler line
+     * @since 3.0
+     */
+    protected void mouseClicked(int rulerLine) {
+    }
+
+    /**
+     * Handles mouse moves.
+     *
+     * @param event the mouse move event
+     */
+    private void handleMouseMove(MouseEvent event) {
+        fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+        if (fCachedTextViewer !is null) {
+            int line= toDocumentLineNumber(event.y);
+            Cursor cursor= (hasAnnotation(line) ? fHitDetectionCursor : null);
+            if (cursor !is fLastCursor) {
+                fCanvas.setCursor(cursor);
+                fLastCursor= cursor;
+            }
+        }
+    }
+
+    /**
+     * Tells whether the given line contains an annotation.
+     *
+     * @param lineNumber the line number
+     * @return <code>true</code> if the given line contains an annotation
+     */
+    protected bool hasAnnotation(int lineNumber) {
+
+        IAnnotationModel model= fModel;
+        if ( cast(IAnnotationModelExtension)fModel )
+            model= (cast(IAnnotationModelExtension)fModel).getAnnotationModel(SourceViewer.MODEL_ANNOTATION_MODEL);
+
+        if (model is null)
+            return false;
+
+        IRegion line;
+        try {
+            IDocument d= fCachedTextViewer.getDocument();
+            if (d is null)
+                return false;
+
+            line= d.getLineInformation(lineNumber);
+        }  catch (BadLocationException ex) {
+            return false;
+        }
+
+        int lineStart= line.getOffset();
+        int lineLength= line.getLength();
+
+        Iterator e;
+        if ( cast(IAnnotationModelExtension2)fModel )
+            e= (cast(IAnnotationModelExtension2)fModel).getAnnotationIterator(lineStart, lineLength + 1, true, true);
+        else
+            e= model.getAnnotationIterator();
+
+        while (e.hasNext()) {
+            Annotation a= cast(Annotation) e.next();
+
+            if (a.isMarkedDeleted())
+                continue;
+
+            if (skip(a))
+                continue;
+
+            Position p= model.getPosition(a);
+            if (p is null || p.isDeleted())
+                continue;
+
+            if (p.overlapsWith(lineStart, lineLength) || p.length is 0 && p.offset is lineStart + lineLength)
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Disposes the ruler's resources.
+     */
+    private void handleDispose() {
+
+        if (fCachedTextViewer !is null) {
+            fCachedTextViewer.removeViewportListener(fInternalListener);
+            fCachedTextViewer.removeTextListener(fInternalListener);
+        }
+
+        if (fModel !is null)
+            fModel.removeAnnotationModelListener(fInternalListener);
+
+        if (fBuffer !is null) {
+            fBuffer.dispose();
+            fBuffer= null;
+        }
+
+        if (fHitDetectionCursor !is null) {
+            fHitDetectionCursor.dispose();
+            fHitDetectionCursor= null;
+        }
+
+        fConfiguredAnnotationTypes.clear();
+        fAllowedAnnotationTypes.clear();
+        fAnnotationAccessExtension= null;
+    }
+
+    /**
+     * Double buffer drawing.
+     *
+     * @param dest the GC to draw into
+     */
+    private void doubleBufferPaint(GC dest) {
+
+        Point size= fCanvas.getSize();
+
+        if (size.x <= 0 || size.y <= 0)
+            return;
+
+        if (fBuffer !is null) {
+            Rectangle r= fBuffer.getBounds();
+            if (r.width !is size.x || r.height !is size.y) {
+                fBuffer.dispose();
+                fBuffer= null;
+            }
+        }
+        if (fBuffer is null)
+            fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
+
+        GC gc= new GC(fBuffer);
+        gc.setFont(fCachedTextWidget.getFont());
+        try {
+            gc.setBackground(fCanvas.getBackground());
+            gc.fillRectangle(0, 0, size.x, size.y);
+
+            if ( cast(ITextViewerExtension5)fCachedTextViewer )
+                doPaint1(gc);
+            else
+                doPaint(gc);
+        } finally {
+            gc.dispose();
+        }
+
+        dest.drawImage(fBuffer, 0, 0);
+    }
+
+    /**
+     * Returns the document offset of the upper left corner of the source viewer's
+     * view port, possibly including partially visible lines.
+     *
+     * @return document offset of the upper left corner including partially visible lines
+     */
+    protected int getInclusiveTopIndexStartOffset() {
+        if (fCachedTextWidget is null || fCachedTextWidget.isDisposed())
+            return -1;
+
+        IDocument document= fCachedTextViewer.getDocument();
+        if (document is null)
+            return -1;
+
+        int top= JFaceTextUtil.getPartialTopIndex(fCachedTextViewer);
+        try {
+            return document.getLineOffset(top);
+        } catch (BadLocationException x) {
+            return -1;
+        }
+    }
+
+    /**
+     * Returns the first invisible document offset of the lower right corner of the source viewer's view port,
+     * possibly including partially visible lines.
+     *
+     * @return the first invisible document offset of the lower right corner of the view port
+     */
+    private int getExclusiveBottomIndexEndOffset() {
+        if (fCachedTextWidget is null || fCachedTextWidget.isDisposed())
+            return -1;
+
+        IDocument document= fCachedTextViewer.getDocument();
+        if (document is null)
+            return -1;
+
+        int bottom= JFaceTextUtil.getPartialBottomIndex(fCachedTextViewer);
+        try {
+            if (bottom >= document.getNumberOfLines())
+                bottom= document.getNumberOfLines() - 1;
+            return document.getLineOffset(bottom) + document.getLineLength(bottom);
+        } catch (BadLocationException x) {
+            return -1;
+        }
+    }
+
+    /**
+     * Draws the vertical ruler w/o drawing the Canvas background.
+     *
+     * @param gc the GC to draw into
+     */
+    protected void doPaint(GC gc) {
+
+        if (fModel is null || fCachedTextViewer is null)
+            return;
+
+        int topLeft= getInclusiveTopIndexStartOffset();
+        // http://dev.eclipse.org/bugs/show_bug.cgi?id=14938
+        // http://dev.eclipse.org/bugs/show_bug.cgi?id=22487
+        // we want the exclusive offset (right after the last character)
+        int bottomRight= getExclusiveBottomIndexEndOffset();
+        int viewPort= bottomRight - topLeft;
+
+        fScrollPos= fCachedTextWidget.getTopPixel();
+        Point dimension= fCanvas.getSize();
+
+        IDocument doc= fCachedTextViewer.getDocument();
+        if (doc is null)
+            return;
+
+        int topLine= -1, bottomLine= -1;
+        try {
+            IRegion region= fCachedTextViewer.getVisibleRegion();
+            topLine= doc.getLineOfOffset(region.getOffset());
+            bottomLine= doc.getLineOfOffset(region.getOffset() + region.getLength());
+        } catch (BadLocationException x) {
+            return;
+        }
+
+        // draw Annotations
+        Rectangle r= new Rectangle(0, 0, 0, 0);
+        int maxLayer= 1;    // loop at least once through layers.
+
+        for (int layer= 0; layer < maxLayer; layer++) {
+            Iterator iter;
+            if ( cast(IAnnotationModelExtension2)fModel )
+                iter= (cast(IAnnotationModelExtension2)fModel).getAnnotationIterator(topLeft, viewPort + 1, true, true);
+            else
+                iter= fModel.getAnnotationIterator();
+
+            while (iter.hasNext()) {
+                Annotation annotation= cast(Annotation) iter.next();
+
+                int lay= IAnnotationAccessExtension.DEFAULT_LAYER;
+                if (fAnnotationAccessExtension !is null)
+                    lay= fAnnotationAccessExtension.getLayer(annotation);
+                maxLayer= Math.max(maxLayer, lay+1);    // dynamically update layer maximum
+                if (lay !is layer)   // wrong layer: skip annotation
+                    continue;
+
+                if (skip(annotation))
+                    continue;
+
+                Position position= fModel.getPosition(annotation);
+                if (position is null)
+                    continue;
+
+                // https://bugs.eclipse.org/bugs/show_bug.cgi?id=20284
+                // Position.overlapsWith returns false if the position just starts at the end
+                // of the specified range. If the position has zero length, we want to include it anyhow
+                int viewPortSize= position.getLength() is 0 ? viewPort + 1 : viewPort;
+                if (!position.overlapsWith(topLeft, viewPortSize))
+                    continue;
+
+                try {
+
+                    int offset= position.getOffset();
+                    int length= position.getLength();
+
+                    int startLine= doc.getLineOfOffset(offset);
+                    if (startLine < topLine)
+                        startLine= topLine;
+
+                    int endLine= startLine;
+                    if (length > 0)
+                        endLine= doc.getLineOfOffset(offset + length - 1);
+                    if (endLine > bottomLine)
+                        endLine= bottomLine;
+
+                    startLine -= topLine;
+                    endLine -= topLine;
+
+                    r.x= 0;
+                    r.y= JFaceTextUtil.computeLineHeight(fCachedTextWidget, 0, startLine, startLine)  - fScrollPos;
+
+                    r.width= dimension.x;
+                    int lines= endLine - startLine;
+
+                    r.height= JFaceTextUtil.computeLineHeight(fCachedTextWidget, startLine, endLine + 1, lines + 1);
+
+                    if (r.y < dimension.y && fAnnotationAccessExtension !is null)  // annotation within visible area
+                        fAnnotationAccessExtension.paint(annotation, gc, fCanvas, r);
+
+                } catch (BadLocationException x) {
+                }
+            }
+        }
+    }
+
+    /**
+     * Draws the vertical ruler w/o drawing the Canvas background. Implementation based
+     * on <code>ITextViewerExtension5</code>. Will replace <code>doPaint(GC)</code>.
+     *
+     * @param gc the GC to draw into
+     */
+    protected void doPaint1(GC gc) {
+
+        if (fModel is null || fCachedTextViewer is null)
+            return;
+
+        ITextViewerExtension5 extension= cast(ITextViewerExtension5) fCachedTextViewer;
+
+        fScrollPos= fCachedTextWidget.getTopPixel();
+        Point dimension= fCanvas.getSize();
+
+        int vOffset= getInclusiveTopIndexStartOffset();
+        int vLength= getExclusiveBottomIndexEndOffset() - vOffset;
+
+        // draw Annotations
+        Rectangle r= new Rectangle(0, 0, 0, 0);
+        ReusableRegion range= new ReusableRegion();
+
+        int minLayer= Integer.MAX_VALUE, maxLayer= Integer.MIN_VALUE;
+        fCachedAnnotations.clear();
+        Iterator iter;
+        if ( cast(IAnnotationModelExtension2)fModel )
+            iter= (cast(IAnnotationModelExtension2)fModel).getAnnotationIterator(vOffset, vLength + 1, true, true);
+        else
+            iter= fModel.getAnnotationIterator();
+
+        while (iter.hasNext()) {
+            Annotation annotation= cast(Annotation) iter.next();
+
+            if (skip(annotation))
+                continue;
+
+            Position position= fModel.getPosition(annotation);
+            if (position is null)
+                continue;
+
+            // https://bugs.eclipse.org/bugs/show_bug.cgi?id=217710
+            int extendedVLength= position.getLength() is 0 ? vLength + 1 : vLength;
+            if (!position.overlapsWith(vOffset, extendedVLength))
+                continue;
+
+            int lay= IAnnotationAccessExtension.DEFAULT_LAYER;
+            if (fAnnotationAccessExtension !is null)
+                lay= fAnnotationAccessExtension.getLayer(annotation);
+
+            minLayer= Math.min(minLayer, lay);
+            maxLayer= Math.max(maxLayer, lay);
+            fCachedAnnotations.add(new Tuple(annotation, position));
+        }
+        Collections.sort(fCachedAnnotations, fTupleComparator);
+
+        for (int layer= minLayer; layer <= maxLayer; layer++) {
+            for (int i= 0, n= fCachedAnnotations.size(); i < n; i++) {
+                Tuple tuple= cast(Tuple) fCachedAnnotations.get(i);
+                Annotation annotation= tuple.annotation;
+                Position position= tuple.position;
+
+                int lay= IAnnotationAccessExtension.DEFAULT_LAYER;
+                if (fAnnotationAccessExtension !is null)
+                    lay= fAnnotationAccessExtension.getLayer(annotation);
+                if (lay !is layer)   // wrong layer: skip annotation
+                    continue;
+
+                range.setOffset(position.getOffset());
+                range.setLength(position.getLength());
+                IRegion widgetRegion= extension.modelRange2WidgetRange(range);
+                if (widgetRegion is null)
+                    continue;
+
+                int startLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset());
+                if (startLine is -1)
+                    continue;
+
+                int endLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset() + Math.max(widgetRegion.getLength() -1, 0));
+                if (endLine is -1)
+                    continue;
+
+                r.x= 0;
+                r.y= JFaceTextUtil.computeLineHeight(fCachedTextWidget, 0, startLine, startLine)  - fScrollPos;
+
+                r.width= dimension.x;
+                int lines= endLine - startLine;
+                r.height= JFaceTextUtil.computeLineHeight(fCachedTextWidget, startLine, endLine + 1, lines + 1);
+
+                if (r.y < dimension.y && fAnnotationAccessExtension !is null)  // annotation within visible area
+                    fAnnotationAccessExtension.paint(annotation, gc, fCanvas, r);
+            }
+        }
+
+        fCachedAnnotations.clear();
+    }
+
+
+    /**
+     * Post a redraw request for this column into the UI thread.
+     */
+    private void postRedraw() {
+        if (fCanvas !is null && !fCanvas.isDisposed()) {
+            Display d= fCanvas.getDisplay();
+            if (d !is null) {
+                d.asyncExec(new class()  Runnable {
+                    public void run() {
+                        redraw();
+                    }
+                });
+            }
+        }
+    }
+
+    /*
+     * @see IVerticalRulerColumn#redraw()
+     */
+    public void redraw() {
+        if (fCanvas !is null && !fCanvas.isDisposed()) {
+            GC gc= new GC(fCanvas);
+            doubleBufferPaint(gc);
+            gc.dispose();
+        }
+    }
+
+    /*
+     * @see IVerticalRulerColumn#setModel
+     */
+    public void setModel(IAnnotationModel model) {
+        if (fAllowSetModel && model !is fModel) {
+
+            if (fModel !is null)
+                fModel.removeAnnotationModelListener(fInternalListener);
+
+            fModel= model;
+
+            if (fModel !is null)
+                fModel.addAnnotationModelListener(fInternalListener);
+
+            postRedraw();
+        }
+    }
+
+    /*
+     * @see IVerticalRulerColumn#setFont(Font)
+     */
+    public void setFont(Font font) {
+    }
+
+    /**
+     * Returns the cached text viewer.
+     *
+     * @return the cached text viewer
+     */
+    protected ITextViewer getCachedTextViewer() {
+        return fCachedTextViewer;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getModel()
+     */
+    public IAnnotationModel getModel() {
+        return fModel;
+    }
+
+    /**
+     * Adds the given annotation type to this annotation ruler column. Starting
+     * with this call, annotations of the given type are shown in this annotation
+     * ruler column.
+     *
+     * @param annotationType the annotation type
+     * @since 3.0
+     */
+    public void addAnnotationType(Object annotationType) {
+        fConfiguredAnnotationTypes.add(annotationType);
+        fAllowedAnnotationTypes.clear();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfo#getLineOfLastMouseButtonActivity()
+     * @since 3.0
+     */
+    public int getLineOfLastMouseButtonActivity() {
+        return fParentRuler.getLineOfLastMouseButtonActivity();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfo#toDocumentLineNumber(int)
+     * @since 3.0
+     */
+    public int toDocumentLineNumber(int y_coordinate) {
+        return fParentRuler.toDocumentLineNumber(y_coordinate);
+    }
+
+    /**
+     * Removes the given annotation type from this annotation ruler column.
+     * Annotations of the given type are no longer shown in this annotation
+     * ruler column.
+     *
+     * @param annotationType the annotation type
+     * @since 3.0
+     */
+    public void removeAnnotationType(Object annotationType) {
+        fConfiguredAnnotationTypes.remove(annotationType);
+        fAllowedAnnotationTypes.clear();
+    }
+
+    /**
+     * Returns whether the given annotation should be skipped by the drawing
+     * routine.
+     *
+     * @param annotation the annotation
+     * @return <code>true</code> if annotation of the given type should be
+     *         skipped, <code>false</code> otherwise
+     * @since 3.0
+     */
+    private bool skip(Annotation annotation) {
+        Object annotationType= stringcast(annotation.getType());
+        Boolean allowed= cast(Boolean) fAllowedAnnotationTypes.get(annotationType);
+        if (allowed !is null)
+            return !allowed.booleanValue();
+
+        bool skip= skip(annotationType);
+        fAllowedAnnotationTypes.put(annotationType, !skip ? Boolean.TRUE : Boolean.FALSE);
+        return skip;
+    }
+
+    /**
+     * Computes whether the annotation of the given type should be skipped or
+     * not.
+     *
+     * @param annotationType the annotation type
+     * @return <code>true</code> if annotation should be skipped, <code>false</code>
+     *         otherwise
+     * @since 3.0
+     */
+    private bool skip(Object annotationType) {
+        if (fAnnotationAccessExtension !is null) {
+            Iterator e= fConfiguredAnnotationTypes.iterator();
+            while (e.hasNext()) {
+                if (fAnnotationAccessExtension.isSubtype(annotationType, e.next()))
+                    return false;
+            }
+            return true;
+        }
+        return !fConfiguredAnnotationTypes.contains(annotationType);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getHover()
+     * @since 3.0
+     */
+    public IAnnotationHover getHover() {
+        return fHover;
+    }
+
+    /**
+     * @param hover The hover to set.
+     * @since 3.0
+     */
+    public void setHover(IAnnotationHover hover) {
+        fHover= hover;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener)
+     * @since 3.0
+     */
+    public void addVerticalRulerListener(IVerticalRulerListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener)
+     * @since 3.0
+     */
+    public void removeVerticalRulerListener(IVerticalRulerListener listener) {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ChangeRulerColumn.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,631 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.ChangeRulerColumn;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.events.MouseMoveListener;
+import dwt.events.PaintEvent;
+import dwt.events.PaintListener;
+import dwt.graphics.Color;
+import dwt.graphics.Font;
+import dwt.graphics.GC;
+import dwt.graphics.Image;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Canvas;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.internal.text.revisions.RevisionPainter;
+import dwtx.jface.internal.text.source.DiffPainter;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextListener;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.IViewportListener;
+import dwtx.jface.text.JFaceTextUtil;
+import dwtx.jface.text.TextEvent;
+import dwtx.jface.text.revisions.IRevisionRulerColumn;
+import dwtx.jface.text.revisions.RevisionInformation;
+import dwtx.jface.viewers.ISelectionProvider;
+
+/**
+ * A vertical ruler column displaying line numbers and serving as a UI for quick diff.
+ * Clients instantiate and configure object of this class.
+ *
+ * @since 3.0
+ */
+public final class ChangeRulerColumn : IVerticalRulerColumn, IVerticalRulerInfo, IVerticalRulerInfoExtension, IChangeRulerColumn, IRevisionRulerColumn {
+    /**
+     * Handles all the mouse interaction in this line number ruler column.
+     */
+    private class MouseHandler : MouseListener, MouseMoveListener {
+
+        /*
+         * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent)
+         */
+        public void mouseUp(MouseEvent event) {
+        }
+
+        /*
+         * @see dwt.events.MouseListener#mouseDown(dwt.events.MouseEvent)
+         */
+        public void mouseDown(MouseEvent event) {
+            fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+        }
+
+        /*
+         * @see dwt.events.MouseListener#mouseDoubleClick(dwt.events.MouseEvent)
+         */
+        public void mouseDoubleClick(MouseEvent event) {
+            fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+        }
+
+        /*
+         * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent)
+         */
+        public void mouseMove(MouseEvent event) {
+            fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+        }
+    }
+
+    /**
+     * Internal listener class.
+     */
+    private class InternalListener : IViewportListener, ITextListener {
+
+        /*
+         * @see IViewportListener#viewportChanged(int)
+         */
+        public void viewportChanged(int verticalPosition) {
+            if (verticalPosition !is fScrollPos)
+                redraw();
+        }
+
+        /*
+         * @see ITextListener#textChanged(TextEvent)
+         */
+        public void textChanged(TextEvent event) {
+
+            if (!event.getViewerRedrawState())
+                return;
+
+            if (fSensitiveToTextChanges || event.getDocumentEvent() is null)
+                postRedraw();
+
+        }
+    }
+
+    /**
+     * The view(port) listener.
+     */
+    private /+const+/ InternalListener fInternalListener;
+    /**
+     * The mouse handler.
+     * @since 3.2
+     */
+    private /+const+/ MouseHandler fMouseHandler;
+    /**
+     * The revision painter.
+     * @since 3.2
+     */
+    private const RevisionPainter fRevisionPainter;
+    /**
+     * The diff info painter.
+     * @since 3.2
+     */
+    private const DiffPainter fDiffPainter;
+
+    /** This column's parent ruler */
+    private CompositeRuler fParentRuler;
+    /** Cached text viewer */
+    private ITextViewer fCachedTextViewer;
+    /** Cached text widget */
+    private StyledText fCachedTextWidget;
+    /** The columns canvas */
+    private Canvas fCanvas;
+    /** The background color */
+    private Color fBackground;
+    /** The ruler's annotation model. */
+    private IAnnotationModel fAnnotationModel;
+    /** The width of the change ruler column. */
+    private const int fWidth= 5;
+
+    /** Cache for the actual scroll position in pixels */
+    private int fScrollPos;
+    /** The buffer for double buffering */
+    private Image fBuffer;
+    /** Indicates whether this column reacts on text change events */
+    private bool fSensitiveToTextChanges= false;
+
+    private void instanceInit(){
+        fInternalListener= new InternalListener();
+        fMouseHandler= new MouseHandler();
+    }
+    /**
+     * Creates a new ruler column.
+     *
+     * @deprecated since 3.2 use {@link #ChangeRulerColumn(ISharedTextColors)} instead
+     */
+    public this() {
+        instanceInit();
+        fRevisionPainter= null;
+        fDiffPainter= new DiffPainter(this, null);
+    }
+
+    /**
+     * Creates a new revision ruler column.
+     *
+     * @param sharedColors the colors to look up RGBs
+     * @since 3.2
+     */
+    public this(ISharedTextColors sharedColors) {
+        instanceInit();
+        Assert.isNotNull(cast(Object)sharedColors);
+        fRevisionPainter= new RevisionPainter(this, sharedColors);
+        fDiffPainter= new DiffPainter(this, null); // no shading
+    }
+
+    /**
+     * Returns the System background color for list widgets.
+     *
+     * @return the System background color for list widgets
+     */
+    private Color getBackground() {
+        if (fBackground is null)
+            return fCachedTextWidget.getDisplay().getSystemColor(DWT.COLOR_LIST_BACKGROUND);
+        return fBackground;
+    }
+
+    /*
+     * @see IVerticalRulerColumn#createControl(CompositeRuler, Composite)
+     */
+    public Control createControl(CompositeRuler parentRuler, Composite parentControl) {
+
+        fParentRuler= parentRuler;
+        fCachedTextViewer= parentRuler.getTextViewer();
+        fCachedTextWidget= fCachedTextViewer.getTextWidget();
+
+        fCanvas= new Canvas(parentControl, DWT.NONE);
+        fCanvas.setBackground(getBackground());
+
+        fCanvas.addPaintListener(new class()  PaintListener {
+            public void paintControl(PaintEvent event) {
+                if (fCachedTextViewer !is null)
+                    doubleBufferPaint(event.gc);
+            }
+        });
+
+        fCanvas.addDisposeListener(new class()  DisposeListener {
+            public void widgetDisposed(DisposeEvent e) {
+                handleDispose();
+                fCachedTextViewer= null;
+                fCachedTextWidget= null;
+            }
+        });
+
+        fCanvas.addMouseListener(fMouseHandler);
+        fCanvas.addMouseMoveListener(fMouseHandler);
+
+        if (fCachedTextViewer !is null) {
+
+            fCachedTextViewer.addViewportListener(fInternalListener);
+            fCachedTextViewer.addTextListener(fInternalListener);
+        }
+
+        fRevisionPainter.setParentRuler(parentRuler);
+        fDiffPainter.setParentRuler(parentRuler);
+
+        return fCanvas;
+    }
+
+    /**
+     * Disposes the column's resources.
+     */
+    protected void handleDispose() {
+
+        if (fCachedTextViewer !is null) {
+            fCachedTextViewer.removeViewportListener(fInternalListener);
+            fCachedTextViewer.removeTextListener(fInternalListener);
+        }
+
+        if (fBuffer !is null) {
+            fBuffer.dispose();
+            fBuffer= null;
+        }
+    }
+
+    /**
+     * Double buffer drawing.
+     *
+     * @param dest the GC to draw into
+     */
+    private void doubleBufferPaint(GC dest) {
+
+        Point size= fCanvas.getSize();
+
+        if (size.x <= 0 || size.y <= 0)
+            return;
+
+        if (fBuffer !is null) {
+            Rectangle r= fBuffer.getBounds();
+            if (r.width !is size.x || r.height !is size.y) {
+                fBuffer.dispose();
+                fBuffer= null;
+            }
+        }
+        if (fBuffer is null)
+            fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
+
+        GC gc= new GC(fBuffer);
+        gc.setFont(fCanvas.getFont());
+
+        try {
+            gc.setBackground(getBackground());
+            gc.fillRectangle(0, 0, size.x, size.y);
+
+            doPaint(gc);
+        } finally {
+            gc.dispose();
+        }
+
+        dest.drawImage(fBuffer, 0, 0);
+    }
+
+    /**
+     * Returns the view port height in lines.
+     *
+     * @return the view port height in lines
+     * @deprecated as of 3.2 the number of lines in the viewport cannot be computed because
+     *             StyledText supports variable line heights
+     */
+    protected int getVisibleLinesInViewport() {
+        // Hack to reduce amount of copied code.
+        return LineNumberRulerColumn.getVisibleLinesInViewport(fCachedTextWidget);
+    }
+
+    /**
+     * Returns <code>true</code> if the viewport displays the entire viewer contents, i.e. the
+     * viewer is not vertically scrollable.
+     *
+     * @return <code>true</code> if the viewport displays the entire contents, <code>false</code> otherwise
+     * @since 3.2
+     */
+    protected final bool isViewerCompletelyShown() {
+        return JFaceTextUtil.isShowingEntireContents(fCachedTextWidget);
+    }
+
+    /**
+     * Draws the ruler column.
+     *
+     * @param gc the GC to draw into
+     */
+    private void doPaint(GC gc) {
+        ILineRange visibleModelLines= computeVisibleModelLines();
+        if (visibleModelLines is null)
+            return;
+
+        fSensitiveToTextChanges= isViewerCompletelyShown();
+
+        fScrollPos= fCachedTextWidget.getTopPixel();
+
+        fRevisionPainter.paint(gc, visibleModelLines);
+        if (!fRevisionPainter.hasInformation()) // don't paint quick diff colors if revisions are painted
+            fDiffPainter.paint(gc, visibleModelLines);
+    }
+
+    /*
+     * @see IVerticalRulerColumn#redraw()
+     */
+    public void redraw() {
+
+        if (fCachedTextViewer !is null && fCanvas !is null && !fCanvas.isDisposed()) {
+            GC gc= new GC(fCanvas);
+            doubleBufferPaint(gc);
+            gc.dispose();
+        }
+    }
+
+    /*
+     * @see IVerticalRulerColumn#setFont(Font)
+     */
+    public void setFont(Font font) {
+    }
+
+    /**
+     * Returns the parent (composite) ruler of this ruler column.
+     *
+     * @return the parent ruler
+     * @since 3.0
+     */
+    private CompositeRuler getParentRuler() {
+        return fParentRuler;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfo#getLineOfLastMouseButtonActivity()
+     */
+    public int getLineOfLastMouseButtonActivity() {
+        return getParentRuler().getLineOfLastMouseButtonActivity();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfo#toDocumentLineNumber(int)
+     */
+    public int toDocumentLineNumber(int y_coordinate) {
+        return getParentRuler().toDocumentLineNumber(y_coordinate);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getHover()
+     */
+    public IAnnotationHover getHover() {
+        int activeLine= getParentRuler().getLineOfLastMouseButtonActivity();
+        if (fRevisionPainter.hasHover(activeLine))
+            return fRevisionPainter.getHover();
+        if (fDiffPainter.hasHover(activeLine))
+            return fDiffPainter.getHover();
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IChangeRulerColumn#setHover(dwtx.jface.text.source.IAnnotationHover)
+     */
+    public void setHover(IAnnotationHover hover) {
+        fRevisionPainter.setHover(hover);
+        fDiffPainter.setHover(hover);
+    }
+
+    /*
+     * @see IVerticalRulerColumn#setModel(IAnnotationModel)
+     */
+    public void setModel(IAnnotationModel model) {
+        setAnnotationModel(model);
+        fRevisionPainter.setModel(model);
+        fDiffPainter.setModel(model);
+    }
+
+    private void setAnnotationModel(IAnnotationModel model) {
+        if (fAnnotationModel !is model)
+            fAnnotationModel= model;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IChangeRulerColumn#setBackground(dwt.graphics.Color)
+     */
+    public void setBackground(Color background) {
+        fBackground= background;
+        if (fCanvas !is null && !fCanvas.isDisposed())
+            fCanvas.setBackground(getBackground());
+        fRevisionPainter.setBackground(background);
+        fDiffPainter.setBackground(background);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IChangeRulerColumn#setAddedColor(dwt.graphics.Color)
+     */
+    public void setAddedColor(Color addedColor) {
+        fDiffPainter.setAddedColor(addedColor);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IChangeRulerColumn#setChangedColor(dwt.graphics.Color)
+     */
+    public void setChangedColor(Color changedColor) {
+        fDiffPainter.setChangedColor(changedColor);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IChangeRulerColumn#setDeletedColor(dwt.graphics.Color)
+     */
+    public void setDeletedColor(Color deletedColor) {
+        fDiffPainter.setDeletedColor(deletedColor);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getModel()
+     */
+    public IAnnotationModel getModel() {
+        return fAnnotationModel;
+    }
+
+    /*
+     * @see IVerticalRulerColumn#getControl()
+     */
+    public Control getControl() {
+        return fCanvas;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfo#getWidth()
+     */
+    public int getWidth() {
+        return fWidth;
+    }
+
+    /**
+     * Triggers a redraw in the display thread.
+     */
+    protected final void postRedraw() {
+        if (fCanvas !is null && !fCanvas.isDisposed()) {
+            Display d= fCanvas.getDisplay();
+            if (d !is null) {
+                d.asyncExec(new class()  Runnable {
+                    public void run() {
+                        redraw();
+                    }
+                });
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener)
+     */
+    public void addVerticalRulerListener(IVerticalRulerListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener)
+     */
+    public void removeVerticalRulerListener(IVerticalRulerListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    /**
+     * Computes the document based line range visible in the text widget.
+     *
+     * @return the document based line range visible in the text widget
+     * @since 3.2
+     */
+    private final ILineRange computeVisibleModelLines() {
+        IDocument doc= fCachedTextViewer.getDocument();
+        if (doc is null)
+            return null;
+
+        int topLine;
+        IRegion coverage;
+
+        if ( cast(ITextViewerExtension5)fCachedTextViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) fCachedTextViewer;
+
+            // ITextViewer.getTopIndex returns the fully visible line, but we want the partially
+            // visible one
+            int widgetTopLine= JFaceTextUtil.getPartialTopIndex(fCachedTextWidget);
+            topLine= extension.widgetLine2ModelLine(widgetTopLine);
+
+            coverage= extension.getModelCoverage();
+
+        } else {
+            topLine= JFaceTextUtil.getPartialTopIndex(fCachedTextViewer);
+            coverage= fCachedTextViewer.getVisibleRegion();
+        }
+
+        int bottomLine= fCachedTextViewer.getBottomIndex();
+        if (bottomLine !is -1)
+            ++ bottomLine;
+
+        // clip by coverage window
+        try {
+            int firstLine= doc.getLineOfOffset(coverage.getOffset());
+            if (firstLine > topLine)
+                topLine= firstLine;
+
+            int lastLine= doc.getLineOfOffset(coverage.getOffset() + coverage.getLength());
+            if (lastLine < bottomLine || bottomLine is -1)
+                bottomLine= lastLine;
+        } catch (BadLocationException x) {
+            ExceptionPrintStackTrace(x);
+            return null;
+        }
+
+        ILineRange visibleModelLines= new LineRange(topLine, bottomLine - topLine + 1);
+        return visibleModelLines;
+    }
+
+    /*
+     * @see dwtx.jface.text.revisions.IRevisionRulerColumn#setRevisionInformation(dwtx.jface.text.revisions.RevisionInformation)
+     */
+    public void setRevisionInformation(RevisionInformation info) {
+        fRevisionPainter.setRevisionInformation(info);
+        fRevisionPainter.setBackground(getBackground());
+    }
+
+    /**
+     * Returns the revision selection provider.
+     *
+     * @return the revision selection provider
+     * @since 3.2
+     */
+    public ISelectionProvider getRevisionSelectionProvider() {
+        return fRevisionPainter.getRevisionSelectionProvider();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/CompositeRuler.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,942 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.CompositeRuler;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.ControlListener;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.FocusListener;
+import dwt.events.HelpListener;
+import dwt.events.KeyListener;
+import dwt.events.MouseListener;
+import dwt.events.MouseMoveListener;
+import dwt.events.MouseTrackListener;
+import dwt.events.PaintListener;
+import dwt.events.TraverseListener;
+import dwt.graphics.Font;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Canvas;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Event;
+import dwt.widgets.Layout;
+import dwt.widgets.Listener;
+import dwt.widgets.Menu;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension;
+import dwtx.jface.text.ITextViewerExtension5;
+
+
+/**
+ * Standard implementation of
+ * {@link dwtx.jface.text.source.IVerticalRuler}.
+ * <p>
+ * This ruler does not have a a visual representation of its own. The
+ * presentation comes from the configurable list of vertical ruler columns. Such
+ * columns must implement the
+ * {@link dwtx.jface.text.source.IVerticalRulerColumn}. interface.</p>
+ * <p>
+ * Clients may instantiate and configure this class.</p>
+ *
+ * @see dwtx.jface.text.source.IVerticalRulerColumn
+ * @see dwtx.jface.text.ITextViewer
+ * @since 2.0
+ */
+public class CompositeRuler : IVerticalRuler, IVerticalRulerExtension, IVerticalRulerInfoExtension {
+
+
+    /**
+     * Layout of the composite vertical ruler. Arranges the list of columns.
+     */
+    class RulerLayout : Layout {
+
+        /**
+         * Creates the new ruler layout.
+         */
+        protected this() {
+        }
+
+        /*
+         * @see Layout#computeSize(Composite, int, int, bool)
+         */
+        protected Point computeSize(Composite composite, int wHint, int hHint, bool flushCache) {
+            Control[] children= composite.getChildren();
+            Point size= new Point(0, 0);
+            for (int i= 0; i < children.length; i++) {
+                Point s= children[i].computeSize(DWT.DEFAULT, DWT.DEFAULT, flushCache);
+                size.x += s.x;
+                size.y= Math.max(size.y, s.y);
+            }
+            size.x += (Math.max(0, children.length -1) * fGap);
+            return size;
+        }
+
+        /*
+         * @see Layout#layout(Composite, bool)
+         */
+        protected void layout(Composite composite, bool flushCache) {
+            Rectangle clArea= composite.getClientArea();
+            int rulerHeight= clArea.height;
+
+            int x= 0;
+            Iterator e= fDecorators.iterator();
+            while (e.hasNext()) {
+                IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next();
+                int columnWidth= column.getWidth();
+                column.getControl().setBounds(x, 0, columnWidth, rulerHeight);
+                x += (columnWidth + fGap);
+            }
+        }
+    }
+
+    /**
+     * A canvas that adds listeners to all its children. Used by the implementation of the
+     * vertical ruler to propagate listener additions and removals to the ruler's columns.
+     */
+    static class CompositeRulerCanvas : Canvas {
+
+        /**
+         * Keeps the information for which event type a listener object has been added.
+         */
+        static class ListenerInfo {
+            ClassInfo fClass;
+            EventListener fListener;
+        }
+
+        /** The list of listeners added to this canvas. */
+        private List fCachedListeners;
+        /**
+         * Internal listener for opening the context menu.
+         * @since 3.0
+         */
+        private Listener fMenuDetectListener;
+
+        /**
+         * Creates a new composite ruler canvas.
+         *
+         * @param parent the parent composite
+         * @param style the DWT styles
+         */
+        public this(Composite parent, int style) {
+            fCachedListeners= new ArrayList();
+
+            super(parent, style);
+            fMenuDetectListener= new class()  Listener {
+                public void handleEvent(Event event) {
+                    if (event.type is DWT.MenuDetect) {
+                        Menu menu= getMenu();
+                        if (menu !is null) {
+                            menu.setLocation(event.x, event.y);
+                            menu.setVisible(true);
+                        }
+                    }
+                }
+            };
+            super.addDisposeListener(new class()  DisposeListener {
+                public void widgetDisposed(DisposeEvent e) {
+                    if (fCachedListeners !is null) {
+                        fCachedListeners.clear();
+                        fCachedListeners= null;
+                    }
+                }
+            });
+        }
+
+        /**
+         * Adds the given listener object as listener of the given type (<code>clazz</code>) to
+         * the given control.
+         *
+         * @param clazz the listener type
+         * @param control the control to add the listener to
+         * @param listener the listener to be added
+         */
+        private void addListener(ClassInfo clazz, Control control, EventListener listener) {
+            if (ControlListener.classinfo.opEquals(clazz)) {
+                control. addControlListener(cast(ControlListener) listener);
+                return;
+            }
+            if (FocusListener.classinfo.opEquals(clazz)) {
+                control. addFocusListener(cast(FocusListener) listener);
+                return;
+            }
+            if (HelpListener.classinfo.opEquals(clazz)) {
+                control. addHelpListener(cast(HelpListener) listener);
+                return;
+            }
+            if (KeyListener.classinfo.opEquals(clazz)) {
+                control. addKeyListener(cast(KeyListener) listener);
+                return;
+            }
+            if (MouseListener.classinfo.opEquals(clazz)) {
+                control. addMouseListener(cast(MouseListener) listener);
+                return;
+            }
+            if (MouseMoveListener.classinfo.opEquals(clazz)) {
+                control. addMouseMoveListener(cast(MouseMoveListener) listener);
+                return;
+            }
+            if (MouseTrackListener.classinfo.opEquals(clazz)) {
+                control. addMouseTrackListener(cast(MouseTrackListener) listener);
+                return;
+            }
+            if (PaintListener.classinfo.opEquals(clazz)) {
+                control. addPaintListener(cast(PaintListener) listener);
+                return;
+            }
+            if (TraverseListener.classinfo.opEquals(clazz)) {
+                control. addTraverseListener(cast(TraverseListener) listener);
+                return;
+            }
+            if (DisposeListener.classinfo.opEquals(clazz)) {
+                control. addDisposeListener(cast(DisposeListener) listener);
+                return;
+            }
+        }
+
+        /**
+         * Removes the given listener object as listener of the given type (<code>clazz</code>) from
+         * the given control.
+         *
+         * @param clazz the listener type
+         * @param control the control to remove the listener from
+         * @param listener the listener to be removed
+         */
+        private void removeListener(ClassInfo clazz, Control control, EventListener listener) {
+            if (ControlListener.classinfo.opEquals(clazz)) {
+                control. removeControlListener(cast(ControlListener) listener);
+                return;
+            }
+            if (FocusListener.classinfo.opEquals(clazz)) {
+                control. removeFocusListener(cast(FocusListener) listener);
+                return;
+            }
+            if (HelpListener.classinfo.opEquals(clazz)) {
+                control. removeHelpListener(cast(HelpListener) listener);
+                return;
+            }
+            if (KeyListener.classinfo.opEquals(clazz)) {
+                control. removeKeyListener(cast(KeyListener) listener);
+                return;
+            }
+            if (MouseListener.classinfo.opEquals(clazz)) {
+                control. removeMouseListener(cast(MouseListener) listener);
+                return;
+            }
+            if (MouseMoveListener.classinfo.opEquals(clazz)) {
+                control. removeMouseMoveListener(cast(MouseMoveListener) listener);
+                return;
+            }
+            if (MouseTrackListener.classinfo.opEquals(clazz)) {
+                control. removeMouseTrackListener(cast(MouseTrackListener) listener);
+                return;
+            }
+            if (PaintListener.classinfo.opEquals(clazz)) {
+                control. removePaintListener(cast(PaintListener) listener);
+                return;
+            }
+            if (TraverseListener.classinfo.opEquals(clazz)) {
+                control. removeTraverseListener(cast(TraverseListener) listener);
+                return;
+            }
+            if (DisposeListener.classinfo.opEquals(clazz)) {
+                control. removeDisposeListener(cast(DisposeListener) listener);
+                return;
+            }
+        }
+
+        /**
+         * Adds the given listener object to the internal book keeping under
+         * the given listener type (<code>clazz</code>).
+         *
+         * @param clazz the listener type
+         * @param listener the listener object
+         */
+        private void addListener(ClassInfo clazz, EventListener listener) {
+            Control[] children= getChildren();
+            for (int i= 0; i < children.length; i++) {
+                if (children[i] !is null && !children[i].isDisposed())
+                    addListener(clazz, children[i], listener);
+            }
+
+            ListenerInfo info= new ListenerInfo();
+            info.fClass= clazz;
+            info.fListener= listener;
+            fCachedListeners.add(info);
+        }
+
+        /**
+         * Removes the given listener object from the internal book keeping under
+         * the given listener type (<code>clazz</code>).
+         *
+         * @param clazz the listener type
+         * @param listener the listener object
+         */
+        private void removeListener(ClassInfo clazz, EventListener listener) {
+            int length= fCachedListeners.size();
+            for (int i= 0; i < length; i++) {
+                ListenerInfo info= cast(ListenerInfo) fCachedListeners.get(i);
+                if (listener is info.fListener && clazz.opEquals(info.fClass)) {
+                    fCachedListeners.remove(i);
+                    break;
+                }
+            }
+
+            Control[] children= getChildren();
+            for (int i= 0; i < children.length; i++) {
+                if (children[i] !is null && !children[i].isDisposed())
+                    removeListener(clazz, children[i], listener);
+            }
+        }
+
+        /**
+         * Tells this canvas that a child has been added.
+         *
+         * @param child the child
+         */
+        public void childAdded(Control child) {
+            if (child !is null && !child.isDisposed()) {
+                int length= fCachedListeners.size();
+                for (int i= 0; i < length; i++) {
+                    ListenerInfo info= cast(ListenerInfo) fCachedListeners.get(i);
+                    addListener(info.fClass, child, info.fListener);
+                }
+                child.addListener(DWT.MenuDetect, fMenuDetectListener);
+            }
+        }
+
+        /**
+         * Tells this canvas that a child has been removed.
+         *
+         * @param child the child
+         */
+        public void childRemoved(Control child) {
+            if (child !is null && !child.isDisposed()) {
+                int length= fCachedListeners.size();
+                for (int i= 0; i < length; i++) {
+                    ListenerInfo info= cast(ListenerInfo) fCachedListeners.get(i);
+                    removeListener(info.fClass, child, info.fListener);
+                }
+                child.removeListener(DWT.MenuDetect, fMenuDetectListener);
+            }
+        }
+
+        /*
+         * @see Control#removeControlListener(ControlListener)
+         */
+        public void removeControlListener(ControlListener listener) {
+            removeListener(ControlListener.classinfo, listener);
+            super.removeControlListener(listener);
+        }
+
+        /*
+         * @see Control#removeFocusListener(FocusListener)
+         */
+        public void removeFocusListener(FocusListener listener) {
+            removeListener(FocusListener.classinfo, listener);
+            super.removeFocusListener(listener);
+        }
+
+        /*
+         * @see Control#removeHelpListener(HelpListener)
+         */
+        public void removeHelpListener(HelpListener listener) {
+            removeListener(HelpListener.classinfo, listener);
+            super.removeHelpListener(listener);
+        }
+
+        /*
+         * @see Control#removeKeyListener(KeyListener)
+         */
+        public void removeKeyListener(KeyListener listener) {
+            removeListener(KeyListener.classinfo, listener);
+            super.removeKeyListener(listener);
+        }
+
+        /*
+         * @see Control#removeMouseListener(MouseListener)
+         */
+        public void removeMouseListener(MouseListener listener) {
+            removeListener(MouseListener.classinfo, listener);
+            super.removeMouseListener(listener);
+        }
+
+        /*
+         * @see Control#removeMouseMoveListener(MouseMoveListener)
+         */
+        public void removeMouseMoveListener(MouseMoveListener listener) {
+            removeListener(MouseMoveListener.classinfo, listener);
+            super.removeMouseMoveListener(listener);
+        }
+
+        /*
+         * @see Control#removeMouseTrackListener(MouseTrackListener)
+         */
+        public void removeMouseTrackListener(MouseTrackListener listener) {
+            removeListener(MouseTrackListener.classinfo, listener);
+            super.removeMouseTrackListener(listener);
+        }
+
+        /*
+         * @see Control#removePaintListener(PaintListener)
+         */
+        public void removePaintListener(PaintListener listener) {
+            removeListener(PaintListener.classinfo, listener);
+            super.removePaintListener(listener);
+        }
+
+        /*
+         * @see Control#removeTraverseListener(TraverseListener)
+         */
+        public void removeTraverseListener(TraverseListener listener) {
+            removeListener(TraverseListener.classinfo, listener);
+            super.removeTraverseListener(listener);
+        }
+
+        /*
+         * @see Widget#removeDisposeListener(DisposeListener)
+         */
+        public void removeDisposeListener(DisposeListener listener) {
+            removeListener(DisposeListener.classinfo, listener);
+            super.removeDisposeListener(listener);
+        }
+
+        /*
+         * @seeControl#addControlListener(ControlListener)
+         */
+        public void addControlListener(ControlListener listener) {
+            super.addControlListener(listener);
+            addListener(ControlListener.classinfo, listener);
+        }
+
+        /*
+         * @see Control#addFocusListener(FocusListener)
+         */
+        public void addFocusListener(FocusListener listener) {
+            super.addFocusListener(listener);
+            addListener(FocusListener.classinfo, listener);
+        }
+
+        /*
+         * @see Control#addHelpListener(HelpListener)
+         */
+        public void addHelpListener(HelpListener listener) {
+            super.addHelpListener(listener);
+            addListener(HelpListener.classinfo, listener);
+        }
+
+        /*
+         * @see Control#addKeyListener(KeyListener)
+         */
+        public void addKeyListener(KeyListener listener) {
+            super.addKeyListener(listener);
+            addListener(KeyListener.classinfo, listener);
+        }
+
+        /*
+         * @see Control#addMouseListener(MouseListener)
+         */
+        public void addMouseListener(MouseListener listener) {
+            super.addMouseListener(listener);
+            addListener(MouseListener.classinfo, listener);
+        }
+
+        /*
+         * @see Control#addMouseMoveListener(MouseMoveListener)
+         */
+        public void addMouseMoveListener(MouseMoveListener listener) {
+            super.addMouseMoveListener(listener);
+            addListener(MouseMoveListener.classinfo, listener);
+        }
+
+        /*
+         * @see Control#addMouseTrackListener(MouseTrackListener)
+         */
+        public void addMouseTrackListener(MouseTrackListener listener) {
+            super.addMouseTrackListener(listener);
+            addListener(MouseTrackListener.classinfo, listener);
+        }
+
+        /*
+         * @seeControl#addPaintListener(PaintListener)
+         */
+        public void addPaintListener(PaintListener listener) {
+            super.addPaintListener(listener);
+            addListener(PaintListener.classinfo, listener);
+        }
+
+        /*
+         * @see Control#addTraverseListener(TraverseListener)
+         */
+        public void addTraverseListener(TraverseListener listener) {
+            super.addTraverseListener(listener);
+            addListener(TraverseListener.classinfo, listener);
+        }
+
+        /*
+         * @see Widget#addDisposeListener(DisposeListener)
+         */
+        public void addDisposeListener(DisposeListener listener) {
+            super.addDisposeListener(listener);
+            addListener(DisposeListener.classinfo, listener);
+        }
+    }
+
+    /** The ruler's viewer */
+    private ITextViewer fTextViewer;
+    /** The ruler's canvas to which to add the ruler columns */
+    private CompositeRulerCanvas fComposite;
+    /** The ruler's annotation model */
+    private IAnnotationModel fModel;
+    /** The list of columns */
+    private List fDecorators;
+    /** The cached location of the last mouse button activity */
+    private Point fLocation;
+    /** The cached line of the list mouse button activity */
+    private int fLastMouseButtonActivityLine= -1;
+    /** The gap between the individual columns of this composite ruler */
+    private int fGap;
+    /**
+     * The set of annotation listeners.
+     * @since 3.0
+     */
+    private Set fAnnotationListeners;
+
+
+    /**
+     * Constructs a new composite vertical ruler.
+     */
+    public this() {
+        this(0);
+    }
+
+    /**
+     * Constructs a new composite ruler with the given gap between its columns.
+     *
+     * @param gap
+     */
+    public this(int gap) {
+        fDecorators= new ArrayList(2);
+        fLocation= new Point(-1, -1);
+        fAnnotationListeners= new HashSet();
+
+        fGap= gap;
+    }
+
+    /**
+     * Inserts the given column at the specified slot to this composite ruler.
+     * Columns are counted from left to right.
+     *
+     * @param index the index
+     * @param rulerColumn the decorator to be inserted
+     */
+    public void addDecorator(int index, IVerticalRulerColumn rulerColumn) {
+        rulerColumn.setModel(getModel());
+
+        if (index > fDecorators.size())
+            fDecorators.add(cast(Object)rulerColumn);
+        else
+            fDecorators.add(index, cast(Object)rulerColumn);
+
+        if (fComposite !is null && !fComposite.isDisposed()) {
+            rulerColumn.createControl(this, fComposite);
+            fComposite.childAdded(rulerColumn.getControl());
+            layoutTextViewer();
+        }
+    }
+
+    /**
+     * Removes the decorator in the specified slot from this composite ruler.
+     *
+     * @param index the index
+     */
+    public void removeDecorator(int index) {
+        IVerticalRulerColumn rulerColumn= cast(IVerticalRulerColumn) fDecorators.get(index);
+        removeDecorator(rulerColumn);
+    }
+
+    /**
+     * Removes the given decorator from the composite ruler.
+     *
+     * @param rulerColumn the ruler column to be removed
+     * @since 3.0
+     */
+    public void removeDecorator(IVerticalRulerColumn rulerColumn) {
+        fDecorators.remove(cast(Object)rulerColumn);
+        if (rulerColumn !is null) {
+            Control cc= rulerColumn.getControl();
+            if (cc !is null && !cc.isDisposed()) {
+                fComposite.childRemoved(cc);
+                cc.dispose();
+            }
+        }
+        layoutTextViewer();
+    }
+
+    /**
+     * Layouts the text viewer. This also causes this ruler to get
+     * be layouted.
+     */
+    private void layoutTextViewer() {
+
+        Control parent= fTextViewer.getTextWidget();
+
+        if ( cast(ITextViewerExtension)fTextViewer ) {
+            ITextViewerExtension extension= cast(ITextViewerExtension) fTextViewer;
+            parent= extension.getControl();
+        }
+
+        if ( cast(Composite)parent  && !parent.isDisposed())
+            (cast(Composite) parent).layout(true);
+    }
+
+    /*
+     * @see IVerticalRuler#getControl()
+     */
+    public Control getControl() {
+        return fComposite;
+    }
+
+    /*
+     * @see IVerticalRuler#createControl(Composite, ITextViewer)
+     */
+    public Control createControl(Composite parent, ITextViewer textViewer) {
+
+        fTextViewer= textViewer;
+
+        fComposite= new CompositeRulerCanvas(parent, DWT.NONE);
+        fComposite.setLayout(new RulerLayout());
+
+        Iterator iter= fDecorators.iterator();
+        while (iter.hasNext()) {
+            IVerticalRulerColumn column= cast(IVerticalRulerColumn) iter.next();
+            column.createControl(this, fComposite);
+            fComposite.childAdded(column.getControl());
+        }
+
+        return fComposite;
+    }
+
+    /*
+     * @see IVerticalRuler#setModel(IAnnotationModel)
+     */
+    public void setModel(IAnnotationModel model) {
+
+        fModel= model;
+
+        Iterator e= fDecorators.iterator();
+        while (e.hasNext()) {
+            IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next();
+            column.setModel(model);
+        }
+    }
+
+    /*
+     * @see IVerticalRuler#getModel()
+     */
+    public IAnnotationModel getModel() {
+        return fModel;
+    }
+
+    /*
+     * @see IVerticalRuler#update()
+     */
+    public void update() {
+        if (fComposite !is null && !fComposite.isDisposed()) {
+            Display d= fComposite.getDisplay();
+            if (d !is null) {
+                d.asyncExec(new class()  Runnable {
+                    public void run() {
+                        immediateUpdate();
+                    }
+                });
+            }
+        }
+    }
+
+    /**
+     * Immediately redraws the entire ruler (without asynchronous posting).
+     *
+     * @since 3.2
+     */
+    public void immediateUpdate() {
+        Iterator e= fDecorators.iterator();
+        while (e.hasNext()) {
+            IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next();
+            column.redraw();
+        }
+    }
+
+    /*
+     * @see IVerticalRulerExtension#setFont(Font)
+     */
+    public void setFont(Font font) {
+        Iterator e= fDecorators.iterator();
+        while (e.hasNext()) {
+            IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next();
+            column.setFont(font);
+        }
+    }
+
+    /*
+     * @see IVerticalRulerInfo#getWidth()
+     */
+    public int getWidth() {
+        int width= 0;
+        Iterator e= fDecorators.iterator();
+        while (e.hasNext()) {
+            IVerticalRulerColumn column= cast(IVerticalRulerColumn) e.next();
+            width += (column.getWidth() + fGap);
+        }
+        return Math.max(0, width - fGap);
+    }
+
+    /*
+     * @see IVerticalRulerInfo#getLineOfLastMouseButtonActivity()
+     */
+    public int getLineOfLastMouseButtonActivity() {
+        if (fLastMouseButtonActivityLine is -1)
+            fLastMouseButtonActivityLine= toDocumentLineNumber(fLocation.y);
+        else if (fTextViewer.getDocument() is null || fLastMouseButtonActivityLine >= fTextViewer.getDocument().getNumberOfLines())
+            fLastMouseButtonActivityLine= -1;
+        return fLastMouseButtonActivityLine;
+    }
+
+    /*
+     * @see IVerticalRulerInfo#toDocumentLineNumber(int)
+     */
+    public int toDocumentLineNumber(int y_coordinate) {
+        if (fTextViewer is null || y_coordinate is -1)
+            return -1;
+
+        StyledText text= fTextViewer.getTextWidget();
+        int line= text.getLineIndex(y_coordinate);
+
+        if (line is text.getLineCount() - 1) {
+            // check whether y_coordinate exceeds last line
+            if (y_coordinate > text.getLinePixel(line + 1))
+                return -1;
+        }
+
+        return widgetLine2ModelLine(fTextViewer, line);
+    }
+
+    /**
+     * Returns the line in the given viewer's document that correspond to the given
+     * line of the viewer's widget.
+     *
+     * @param viewer the viewer
+     * @param widgetLine the widget line
+     * @return the corresponding line the viewer's document
+     * @since 2.1
+     */
+    protected final static int widgetLine2ModelLine(ITextViewer viewer, int widgetLine) {
+
+        if ( cast(ITextViewerExtension5)viewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) viewer;
+            return extension.widgetLine2ModelLine(widgetLine);
+        }
+
+        try {
+            IRegion r= viewer.getVisibleRegion();
+            IDocument d= viewer.getDocument();
+            return widgetLine += d.getLineOfOffset(r.getOffset());
+        } catch (BadLocationException x) {
+        }
+        return widgetLine;
+    }
+
+    /**
+     * Returns this ruler's text viewer.
+     *
+     * @return this ruler's text viewer
+     */
+    public ITextViewer getTextViewer() {
+        return fTextViewer;
+    }
+
+    /*
+     * @see IVerticalRulerExtension#setLocationOfLastMouseButtonActivity(int, int)
+     */
+    public void setLocationOfLastMouseButtonActivity(int x, int y) {
+        fLocation.x= x;
+        fLocation.y= y;
+        fLastMouseButtonActivityLine= -1;
+    }
+
+    /**
+     * Returns an iterator over the <code>IVerticalRulerColumns</code> that make up this
+     * composite column.
+     *
+     * @return an iterator over the contained columns.
+     * @since 3.0
+     */
+    public Iterator getDecoratorIterator() {
+        Assert.isNotNull(cast(Object)fDecorators, "fDecorators must be initialized"); //$NON-NLS-1$
+        return fDecorators.iterator();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getHover()
+     * @since 3.0
+     */
+    public IAnnotationHover getHover() {
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener)
+     * @since 3.0
+     */
+    public void addVerticalRulerListener(IVerticalRulerListener listener) {
+        fAnnotationListeners.add(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener)
+     * @since 3.0
+     */
+    public void removeVerticalRulerListener(IVerticalRulerListener listener) {
+        fAnnotationListeners.remove(cast(Object)listener);
+    }
+
+    /**
+     * Fires the annotation selected event to all registered vertical ruler
+     * listeners.
+     * TODO use robust iterators
+     *
+     * @param event the event to fire
+     * @since 3.0
+     */
+    public void fireAnnotationSelected(VerticalRulerEvent event) {
+        // forward to listeners
+        for (Iterator it= fAnnotationListeners.iterator(); it.hasNext();) {
+            IVerticalRulerListener listener= cast(IVerticalRulerListener) it.next();
+            listener.annotationSelected(event);
+        }
+    }
+
+    /**
+     * Fires the annotation default selected event to all registered vertical
+     * ruler listeners.
+     * TODO use robust iterators
+     *
+     * @param event the event to fire
+     * @since 3.0
+     */
+    public void fireAnnotationDefaultSelected(VerticalRulerEvent event) {
+        // forward to listeners
+        for (Iterator it= fAnnotationListeners.iterator(); it.hasNext();) {
+            IVerticalRulerListener listener= cast(IVerticalRulerListener) it.next();
+            listener.annotationDefaultSelected(event);
+        }
+    }
+
+    /**
+     * Informs all registered vertical ruler listeners that the content menu on a selected annotation\
+     * is about to be shown.
+     * TODO use robust iterators
+     *
+     * @param event the event to fire
+     * @param menu the menu that is about to be shown
+     * @since 3.0
+     */
+    public void fireAnnotationContextMenuAboutToShow(VerticalRulerEvent event, Menu menu) {
+        // forward to listeners
+        for (Iterator it= fAnnotationListeners.iterator(); it.hasNext();) {
+            IVerticalRulerListener listener= cast(IVerticalRulerListener) it.next();
+            listener.annotationContextMenuAboutToShow(event, menu);
+        }
+    }
+
+    /**
+     * Relayouts the receiver.
+     *
+     * @since 3.3
+     */
+    public void relayout() {
+        layoutTextViewer();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ContentAssistantFacade.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.ContentAssistantFacade;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwtx.core.commands.IHandler;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.contentassist.ICompletionListener;
+import dwtx.jface.text.contentassist.IContentAssistant;
+import dwtx.jface.text.contentassist.IContentAssistantExtension2;
+import dwtx.jface.text.contentassist.IContentAssistantExtension4;
+
+
+/**
+ * Facade to allow minimal access to the given content assistant.
+ * <p>
+ * The offered API access can grow over time.
+ * </p>
+ *
+ * @since 3.4
+ */
+public final class ContentAssistantFacade {
+
+    private IContentAssistant fContentAssistant;
+
+    /**
+     * Creates a new facade.
+     *
+     * @param contentAssistant the content assistant which implements {@link IContentAssistantExtension2} and {@link IContentAssistantExtension4}
+     */
+    public this(IContentAssistant contentAssistant) {
+        Assert.isLegal(cast(IContentAssistantExtension4)contentAssistant && cast(IContentAssistantExtension4)contentAssistant );
+        fContentAssistant= contentAssistant;
+    }
+
+    /**
+     * Returns the handler for the given command identifier.
+     * <p>
+     * The same handler instance will be returned when called a more than once
+     * with the same command identifier.
+     * </p>
+     *
+     * @param commandId the command identifier
+     * @return the handler for the given command identifier
+     * @throws IllegalArgumentException if the command is not supported by this
+     *             content assistant
+     * @throws IllegalStateException if called when the content assistant is
+     *             uninstalled
+     */
+    public IHandler getHandler(String commandId) {
+        if (fContentAssistant is null)
+            throw new IllegalStateException();
+        return (cast(IContentAssistantExtension4)fContentAssistant).getHandler(commandId);
+    }
+
+    /**
+     * Adds a completion listener that will be informed before proposals are
+     * computed.
+     *
+     * @param listener the listener
+     * @throws IllegalStateException if called when the content assistant is
+     *             uninstalled
+     */
+    public void addCompletionListener(ICompletionListener listener) {
+        if (fContentAssistant is null)
+            throw new IllegalStateException();
+        (cast(IContentAssistantExtension2)fContentAssistant).addCompletionListener(listener);
+    }
+
+    /**
+     * Removes a completion listener.
+     *
+     * @param listener the listener to remove
+     * @throws IllegalStateException if called when the content assistant is
+     *             uninstalled
+     */
+    public void removeCompletionListener(ICompletionListener listener) {
+        (cast(IContentAssistantExtension2)fContentAssistant).removeCompletionListener(listener);
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/DefaultAnnotationHover.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,302 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.DefaultAnnotationHover;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.source.projection.AnnotationBag;
+
+/**
+ * Standard implementation of {@link dwtx.jface.text.source.IAnnotationHover}.
+ *
+ * @since 3.2
+ */
+public class DefaultAnnotationHover : IAnnotationHover {
+
+
+    /**
+     * Tells whether the line number should be shown when no annotation is found
+     * under the cursor.
+     *
+     * @since 3.4
+     */
+    private bool fShowLineNumber;
+
+    /**
+     * Creates a new default annotation hover.
+     *
+     * @since 3.4
+     */
+    public this() {
+        this(false);
+    }
+
+    /**
+     * Creates a new default annotation hover.
+     *
+     * @param showLineNumber <code>true</code> if the line number should be shown when no annotation is found
+     * @since 3.4
+     */
+    public this(bool showLineNumber) {
+        fShowLineNumber= showLineNumber;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationHover#getHoverInfo(dwtx.jface.text.source.ISourceViewer, int)
+     */
+    public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+        List javaAnnotations= getAnnotationsForLine(sourceViewer, lineNumber);
+        if (javaAnnotations !is null) {
+
+            if (javaAnnotations.size() is 1) {
+
+                // optimization
+                Annotation annotation= cast(Annotation) javaAnnotations.get(0);
+                String message= annotation.getText();
+                if (message !is null && message.trim().length() > 0)
+                    return formatSingleMessage(message);
+
+            } else {
+
+                List messages= new ArrayList();
+
+                Iterator e= javaAnnotations.iterator();
+                while (e.hasNext()) {
+                    Annotation annotation= cast(Annotation) e.next();
+                    String message= annotation.getText();
+                    if (message !is null && message.trim().length() > 0)
+                        messages.add(message.trim());
+                }
+
+                if (messages.size() is 1)
+                    return formatSingleMessage(stringcast(messages.get(0)));
+
+                if (messages.size() > 1)
+                    return formatMultipleMessages(messages);
+            }
+        }
+
+        if (fShowLineNumber && lineNumber > -1)
+            return JFaceTextMessages.getFormattedString("DefaultAnnotationHover.lineNumber", stringcast(Integer.toString(lineNumber + 1)) ); //$NON-NLS-1$
+
+        return null;
+    }
+
+    /**
+     * Tells whether the annotation should be included in
+     * the computation.
+     *
+     * @param annotation the annotation to test
+     * @return <code>true</code> if the annotation is included in the computation
+     */
+    protected bool isIncluded(Annotation annotation) {
+        return true;
+    }
+
+    /**
+     * Hook method to format the given single message.
+     * <p>
+     * Subclasses can change this to create a different
+     * format like HTML.
+     * </p>
+     *
+     * @param message the message to format
+     * @return the formatted message
+     */
+    protected String formatSingleMessage(String message) {
+        return message;
+    }
+
+    /**
+     * Hook method to formats the given messages.
+     * <p>
+     * Subclasses can change this to create a different
+     * format like HTML.
+     * </p>
+     *
+     * @param messages the messages to format
+     * @return the formatted message
+     */
+    protected String formatMultipleMessages(List messages) {
+        StringBuffer buffer= new StringBuffer();
+        buffer.append(JFaceTextMessages.getString("DefaultAnnotationHover.multipleMarkers")); //$NON-NLS-1$
+
+        Iterator e= messages.iterator();
+        while (e.hasNext()) {
+            buffer.append('\n');
+            String listItemText= stringcast( e.next());
+            buffer.append(JFaceTextMessages.getFormattedString("DefaultAnnotationHover.listItem", stringcast(listItemText ))); //$NON-NLS-1$
+        }
+        return buffer.toString();
+    }
+
+    private bool isRulerLine(Position position, IDocument document, int line) {
+        if (position.getOffset() > -1 && position.getLength() > -1) {
+            try {
+                return line is document.getLineOfOffset(position.getOffset());
+            } catch (BadLocationException x) {
+            }
+        }
+        return false;
+    }
+
+    private IAnnotationModel getAnnotationModel(ISourceViewer viewer) {
+        if ( cast(ISourceViewerExtension2)viewer ) {
+            ISourceViewerExtension2 extension= cast(ISourceViewerExtension2) viewer;
+            return extension.getVisualAnnotationModel();
+        }
+        return viewer.getAnnotationModel();
+    }
+
+    private bool isDuplicateAnnotation(Map messagesAtPosition, Position position, String message) {
+        if (messagesAtPosition.containsKey(position)) {
+            Object value= messagesAtPosition.get(position);
+            if (message==/++/stringcast(value))
+                return true;
+
+            if ( cast(List)value ) {
+                List messages= cast(List)value;
+                if  (messages.contains(message))
+                    return true;
+
+                messages.add(message);
+            } else {
+                ArrayList messages= new ArrayList();
+                messages.add(value);
+                messages.add(message);
+                messagesAtPosition.put(position, messages);
+            }
+        } else
+            messagesAtPosition.put(position, message);
+        return false;
+    }
+
+    private bool includeAnnotation(Annotation annotation, Position position, HashMap messagesAtPosition) {
+        if (!isIncluded(annotation))
+            return false;
+
+        String text= annotation.getText();
+        return (text !is null && !isDuplicateAnnotation(messagesAtPosition, position, text));
+    }
+
+    private List getAnnotationsForLine(ISourceViewer viewer, int line) {
+        IAnnotationModel model= getAnnotationModel(viewer);
+        if (model is null)
+            return null;
+
+        IDocument document= viewer.getDocument();
+        List javaAnnotations= new ArrayList();
+        HashMap messagesAtPosition= new HashMap();
+        Iterator iterator= model.getAnnotationIterator();
+
+        while (iterator.hasNext()) {
+            Annotation annotation= cast(Annotation) iterator.next();
+
+            Position position= model.getPosition(annotation);
+            if (position is null)
+                continue;
+
+            if (!isRulerLine(position, document, line))
+                continue;
+
+            if ( cast(AnnotationBag)annotation ) {
+                AnnotationBag bag= cast(AnnotationBag) annotation;
+                Iterator e= bag.iterator();
+                while (e.hasNext()) {
+                    annotation= cast(Annotation) e.next();
+                    position= model.getPosition(annotation);
+                    if (position !is null && includeAnnotation(annotation, position, messagesAtPosition))
+                        javaAnnotations.add(annotation);
+                }
+                continue;
+            }
+
+            if (includeAnnotation(annotation, position, messagesAtPosition))
+                javaAnnotations.add(annotation);
+        }
+
+        return javaAnnotations;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/DefaultCharacterPairMatcher.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,423 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     Christian Plesner Hansen (plesner@quenta.org) - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.DefaultCharacterPairMatcher;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentExtension3;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITypedRegion;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextUtilities;
+
+/**
+ * A character pair matcher that matches a specified set of character
+ * pairs against each other.  Only characters that occur in the same
+ * partitioning are matched.
+ *
+ * @since 3.3
+ */
+public class DefaultCharacterPairMatcher : ICharacterPairMatcher {
+
+    private int fAnchor= -1;
+    private const CharPairs fPairs;
+    private const String fPartitioning;
+
+    /**
+     * Creates a new character pair matcher that matches the specified
+     * characters within the specified partitioning.  The specified
+     * list of characters must have the form
+     * <blockquote>{ <i>start</i>, <i>end</i>, <i>start</i>, <i>end</i>, ..., <i>start</i>, <i>end</i> }</blockquote>
+     * For instance:
+     * <pre>
+     * char[] chars = new char[] {'(', ')', '{', '}', '[', ']'};
+     * new SimpleCharacterPairMatcher(chars, ...);
+     * </pre>
+     * 
+     * @param chars a list of characters
+     * @param partitioning the partitioning to match within
+     */
+    public this(char[] chars, String partitioning) {
+        Assert.isLegal(chars.length % 2 is 0);
+        Assert.isNotNull(partitioning);
+        fPairs= new CharPairs(chars);
+        fPartitioning= partitioning;
+    }
+    
+    /**
+     * Creates a new character pair matcher that matches characters
+     * within the default partitioning.  The specified list of
+     * characters must have the form
+     * <blockquote>{ <i>start</i>, <i>end</i>, <i>start</i>, <i>end</i>, ..., <i>start</i>, <i>end</i> }</blockquote>
+     * For instance:
+     * <pre>
+     * char[] chars = new char[] {'(', ')', '{', '}', '[', ']'};
+     * new SimpleCharacterPairMatcher(chars);
+     * </pre>
+     * 
+     * @param chars a list of characters
+     */
+    public this(char[] chars) {
+        this(chars, IDocumentExtension3.DEFAULT_PARTITIONING);
+    }
+    
+    /* @see ICharacterPairMatcher#match(IDocument, int) */
+    public IRegion match(IDocument doc, int offset) {
+        if (doc is null || offset < 0 || offset > doc.getLength()) return null;
+        try {
+            return performMatch(doc, offset);
+        } catch (BadLocationException ble) {
+            return null;
+        }
+    }
+        
+    /*
+     * Performs the actual work of matching for #match(IDocument, int).
+     */
+    private IRegion performMatch(IDocument doc, int caretOffset)  {
+        final int charOffset= caretOffset - 1;
+        final char prevChar= doc.getChar(Math.max(charOffset, 0));
+        if (!fPairs.contains(prevChar)) return null;
+        final bool isForward= fPairs.isStartCharacter(prevChar);
+        fAnchor= isForward ? ICharacterPairMatcher.LEFT : ICharacterPairMatcher.RIGHT;
+        final int searchStartPosition= isForward ? caretOffset : caretOffset - 2;
+        final int adjustedOffset= isForward ? charOffset : caretOffset;
+        final String partition= TextUtilities.getContentType(doc, fPartitioning, charOffset, false);
+        final DocumentPartitionAccessor partDoc= new DocumentPartitionAccessor(doc, fPartitioning, partition);
+        int endOffset= findMatchingPeer(partDoc, prevChar, fPairs.getMatching(prevChar),
+                isForward,  isForward ? doc.getLength() : -1,
+                searchStartPosition);
+        if (endOffset is -1) return null;
+        final int adjustedEndOffset= isForward ? endOffset + 1: endOffset;
+        if (adjustedEndOffset is adjustedOffset) return null;
+        return new Region(Math.min(adjustedOffset, adjustedEndOffset),
+                Math.abs(adjustedEndOffset - adjustedOffset));
+    }
+
+    /**
+     * Searches <code>doc</code> for the specified end character, <code>end</code>.
+     * 
+     * @param doc the document to search
+     * @param start the opening matching character
+     * @param end the end character to search for
+     * @param searchForward search forwards or backwards?
+     * @param boundary a boundary at which the search should stop
+     * @param startPos the start offset
+     * @return the index of the end character if it was found, otherwise -1
+     * @throws BadLocationException
+     */
+    private int findMatchingPeer(DocumentPartitionAccessor doc, char start, char end, bool searchForward, int boundary, int startPos)  {
+        int pos= startPos;
+        while (pos !is boundary) {
+            final char c= doc.getChar(pos);
+            if (doc.isMatch(pos, end)) {
+                return pos;
+            } else if (c is start && doc.inPartition(pos)) {
+                pos= findMatchingPeer(doc, start, end, searchForward, boundary,
+                        doc.getNextPosition(pos, searchForward));
+                if (pos is -1) return -1;
+            }
+            pos= doc.getNextPosition(pos, searchForward);
+        }
+        return -1;
+    }
+
+    /* @see ICharacterPairMatcher#getAnchor() */
+    public int getAnchor() {
+        return fAnchor;
+    }
+    
+    /* @see ICharacterPairMatcher#dispose() */
+    public void dispose() { }
+
+    /* @see ICharacterPairMatcher#clear() */
+    public void clear() {
+        fAnchor= -1;
+    }
+
+    /**
+     * Utility class that wraps a document and gives access to
+     * partitioning information.  A document is tied to a particular
+     * partition and, when considering whether or not a position is a
+     * valid match, only considers position within its partition.
+     */
+    private static class DocumentPartitionAccessor {
+        
+        private const IDocument fDocument;
+        private const String fPartitioning, fPartition;
+        private ITypedRegion fCachedPartition;
+        
+        /**
+         * Creates a new partitioned document for the specified document.
+         * 
+         * @param doc the document to wrap
+         * @param partitioning the partitioning used
+         * @param partition the partition managed by this document
+         */
+        public this(IDocument doc, String partitioning,
+                String partition) {
+            fDocument= doc;
+            fPartitioning= partitioning;
+            fPartition= partition;
+        }
+    
+        /**
+         * Returns the character at the specified position in this document.
+         * 
+         * @param pos an offset within this document
+         * @return the character at the offset
+         * @throws BadLocationException
+         */
+        public char getChar(int pos)  {
+            return fDocument.getChar(pos);
+        }
+        
+        /**
+         * Returns true if the character at the specified position is a
+         * valid match for the specified end character.  To be a valid
+         * match, it must be in the appropriate partition and equal to the
+         * end character.
+         * 
+         * @param pos an offset within this document
+         * @param end the end character to match against
+         * @return true exactly if the position represents a valid match
+         * @throws BadLocationException
+         */
+        public bool isMatch(int pos, char end)  {
+            return getChar(pos) is end && inPartition(pos);
+        }
+        
+        /**
+         * Returns true if the specified offset is within the partition
+         * managed by this document.
+         * 
+         * @param pos an offset within this document
+         * @return true if the offset is within this document's partition
+         */
+        public bool inPartition(int pos) {
+            final ITypedRegion partition= getPartition(pos);
+            return partition !is null && partition.getType().equals(fPartition);
+        }
+        
+        /**
+         * Returns the next position to query in the search.  The position
+         * is not guaranteed to be in this document's partition.
+         * 
+         * @param pos an offset within the document
+         * @param searchForward the direction of the search
+         * @return the next position to query
+         */
+        public int getNextPosition(int pos, bool searchForward) {
+            final ITypedRegion partition= getPartition(pos);
+            if (partition is null) return simpleIncrement(pos, searchForward);
+            if (fPartition.equals(partition.getType()))
+                return simpleIncrement(pos, searchForward);
+            if (searchForward) {
+                int end= partition.getOffset() + partition.getLength();
+                if (pos < end)
+                    return end;
+            } else {
+                int offset= partition.getOffset();
+                if (pos > offset)
+                    return offset - 1;
+            }
+            return simpleIncrement(pos, searchForward);
+        }
+    
+        private int simpleIncrement(int pos, bool searchForward) {
+            return pos + (searchForward ? 1 : -1);
+        }
+        
+        /**
+         * Returns partition information about the region containing the
+         * specified position.
+         * 
+         * @param pos a position within this document.
+         * @return positioning information about the region containing the
+         *   position
+         */
+        private ITypedRegion getPartition(int pos) {
+            if (fCachedPartition is null || !contains(fCachedPartition, pos)) {
+                Assert.isTrue(pos >= 0 && pos <= fDocument.getLength());
+                try {
+                    fCachedPartition= TextUtilities.getPartition(fDocument, fPartitioning, pos, false);
+                } catch (BadLocationException e) {
+                    fCachedPartition= null;
+                }
+            }
+            return fCachedPartition;
+        }
+        
+        private static bool contains(IRegion region, int pos) {
+            int offset= region.getOffset();
+            return offset <= pos && pos < offset + region.getLength();
+        }
+        
+    }
+
+    /**
+     * Utility class that encapsulates access to matching character pairs.
+     */
+    private static class CharPairs {
+
+        private const char[] fPairs;
+
+        public this(char[] pairs) {
+            fPairs= pairs;
+        }
+
+        /**
+         * Returns true if the specified character pair occurs in one
+         * of the character pairs.
+         * 
+         * @param c a character
+         * @return true exactly if the character occurs in one of the pairs
+         */
+        public bool contains(char c) {
+            return getAllCharacters().contains(new Character(c));
+        }
+
+        private Set/*<Character>*/ fCharsCache= null;
+        /**
+         * @return A set containing all characters occurring in character pairs.
+         */
+        private Set/*<Character>*/ getAllCharacters() {
+            if (fCharsCache is null) {
+                Set/*<Character>*/ set= new HashSet/*<Character>*/();
+                for (int i= 0; i < fPairs.length; i++)
+                    set.add(new Character(fPairs[i]));
+                fCharsCache= set;
+            }
+            return fCharsCache;
+        }
+
+        /**
+         * Returns true if the specified character opens a character pair
+         * when scanning in the specified direction.
+         *
+         * @param c a character
+         * @param searchForward the direction of the search
+         * @return whether or not the character opens a character pair
+         */
+        public bool isOpeningCharacter(char c, bool searchForward) {
+            for (int i= 0; i < fPairs.length; i += 2) {
+                if (searchForward && getStartChar(i) is c) return true;
+                else if (!searchForward && getEndChar(i) is c) return true;
+            }
+            return false;
+        }
+
+        /**
+         * Returns true of the specified character is a start character.
+         * 
+         * @param c a character
+         * @return true exactly if the character is a start character
+         */
+        public bool isStartCharacter(char c) {
+            return this.isOpeningCharacter(c, true);
+        }
+    
+        /**
+         * Returns the matching character for the specified character.
+         * 
+         * @param c a character occurring in a character pair
+         * @return the matching character
+         */
+        public char getMatching(char c) {
+            for (int i= 0; i < fPairs.length; i += 2) {
+                if (getStartChar(i) is c) return getEndChar(i);
+                else if (getEndChar(i) is c) return getStartChar(i);
+            }
+            Assert.isTrue(false);
+            return '\0';
+        }
+    
+        private char getStartChar(int i) {
+            return fPairs[i];
+        }
+    
+        private char getEndChar(int i) {
+            return fPairs[i + 1];
+        }
+    
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IAnnotationAccess.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IAnnotationAccess;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * An annotation access provides access to information that is not available via
+ * the API of {@link dwtx.jface.text.source.Annotation}. With version
+ * 3.0 all this information is now available from the annotation itself.
+ * <p>
+ *
+ * In order to provide backward compatibility for clients of
+ * <code>IAnnotationAccess</code>, extension interfaces are used as a means
+ * of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.source.IAnnotationAccessExtension} since
+ *     version 3.0 replacing all methods in that interface</li>
+ * <li>{@link IAnnotationAccessExtension2} since
+ *     version 3.2 allowing to set a quick assist assistant to an annotation access.</li>
+ * </ul></p>
+ * <p>
+ * Clients usually implement this interface and its extension interfaces.</p>
+ *
+ * @see dwtx.jface.text.source.IAnnotationAccessExtension
+ * @see dwtx.jface.text.source.Annotation
+ * @since 2.1
+ */
+public interface IAnnotationAccess {
+
+    /**
+     * Returns the type of the given annotation.
+     *
+     * @param annotation the annotation
+     * @return the type of the given annotation or <code>null</code> if it has none.
+     * @deprecated use <code>Annotation.getType()</code>
+     */
+    Object getType(Annotation annotation);
+
+    /**
+     * Returns whether the given annotation spans multiple lines.
+     *
+     * @param annotation the annotation
+     * @return <code>true</code> if the annotation spans multiple lines,
+     *  <code>false</code> otherwise
+     *
+     * @deprecated assumed to always return <code>true</code>
+     */
+    bool isMultiLine(Annotation annotation);
+
+    /**
+     * Returns whether the given annotation is temporary rather than persistent.
+     *
+     * @param annotation the annotation
+     * @return <code>true</code> if the annotation is temporary,
+     *  <code>false</code> otherwise
+     * @deprecated use <code>Annotation.isPersistent()</code>
+     */
+    bool isTemporary(Annotation annotation);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IAnnotationAccessExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,168 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IAnnotationAccessExtension;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.graphics.GC;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Canvas;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.source.IAnnotationAccess}.<p>
+ * This interface replaces the methods of <code>IAnnotationAccess</code>.<p>
+ * This interface provides
+ * <ul>
+ * <li> a label for the annotation type of a given annotation</li>
+ * <li> the paint layer of a given annotation</li>
+ * <li> means to paint a given annotation</li>
+ * <li> information about the type hierarchy of the annotation type of a given annotation</li>
+ * <ul>.
+ *
+ * @see dwtx.jface.text.source.IAnnotationAccess
+ * @since 3.0
+ */
+public interface IAnnotationAccessExtension {
+
+    /**
+     * The default annotation layer.
+     */
+    static const int DEFAULT_LAYER= IAnnotationPresentation.DEFAULT_LAYER;
+
+    /**
+     * Returns the label for the given annotation's type.
+     *
+     * @param annotation the annotation
+     * @return the label the given annotation's type or <code>null</code> if no such label exists
+     */
+    String getTypeLabel(Annotation annotation);
+
+    /**
+     * Returns the layer for given annotation. Annotations are considered
+     * being located at layers and are considered being painted starting with
+     * layer 0 upwards. Thus an annotation at layer 5 will be drawn on top of
+     * all co-located annotations at the layers 4 - 0.
+     *
+     * @param annotation the annotation
+     * @return the layer of the given annotation
+     */
+    int getLayer(Annotation annotation);
+
+    /**
+     * Draws a graphical representation of the given annotation within the given bounds.
+     * <p>
+     * <em>Note that this method is not used when drawing annotations on the editor's
+     * text widget. This is handled trough a {@link dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy}.</em>
+     * </p>
+     * @param annotation the given annotation
+     * @param gc the drawing GC
+     * @param canvas the canvas to draw on
+     * @param bounds the bounds inside the canvas to draw on
+     */
+    void paint(Annotation annotation, GC gc, Canvas canvas, Rectangle bounds);
+
+    /**
+     * Returns <code>true</code> if painting <code>annotation</code> will produce something
+     * meaningful, <code>false</code> if not. E.g. if no image is available.
+     * <p>
+     * <em>Note that this method is not used when drawing annotations on the editor's
+     * text widget. This is handled trough a {@link dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy}.</em>
+     * </p>
+     * @param annotation the annotation to check whether it can be painted
+     * @return <code>true</code> if painting <code>annotation</code> will succeed
+     */
+    bool isPaintable(Annotation annotation);
+
+    /**
+     * Returns <code>true</code> if the given annotation is of the given type
+     * or <code>false</code> otherwise.
+     *
+     * @param annotationType the annotation type
+     * @param potentialSupertype the potential super annotation type
+     * @return <code>true</code> if annotation type is a sub-type of the potential annotation super type
+     */
+    bool isSubtype(Object annotationType, Object potentialSupertype);
+
+    /**
+     * Returns the list of super types for the given annotation type. This does not include the type
+     * itself. The index in the array of super types indicates the length of the path in the hierarchy
+     * graph to the given annotation type.
+     *
+     * @param annotationType the annotation type to check
+     * @return the super types for the given annotation type
+     */
+    Object[] getSupertypes(Object annotationType);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IAnnotationAccessExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IAnnotationAccessExtension2;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.quickassist.IQuickAssistAssistant;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.source.IAnnotationAccess}.<p>
+ * This interface allows clients to set a quick assist assistant.
+ *
+ * @see dwtx.jface.text.source.IAnnotationAccess
+ * @since 3.2
+ */
+public interface IAnnotationAccessExtension2 {
+    
+    /**
+     * Provides this annotation access with a quick assist assistant that
+     * is used to decide whether the quick fix image should be shown.
+     * 
+     * @param assistant the quick assist assistant
+     */
+    void setQuickAssistAssistant(IQuickAssistAssistant assistant);
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IAnnotationHover.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IAnnotationHover;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+/**
+ * Provides the information to be displayed in a hover popup window which
+ * appears over the presentation area of annotations.
+ * <p>
+ * In order to provide backward compatibility for clients of
+ * <code>IAnnotationHover</code>, extension interfaces are used as a means of
+ * evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.source.IAnnotationHoverExtension} since
+ *     version 3.0 allowing a text hover to provide a creator for the hover control.
+ *     This allows for sophisticated hovers in a way that information computed by
+ *     the hover can be displayed in the best possible form.</li>
+ * <li>{@link dwtx.jface.text.source.IAnnotationHoverExtension2} since
+ *     version 3.2 allowing a text hover to specify whether it handles mouse-wheel 
+ *     events itself.</li>
+ * </ul></p>
+ * <p>
+ * Clients may implement this interface.</p>
+ *
+ * @see dwtx.jface.text.source.IAnnotationHoverExtension
+ * @see dwtx.jface.text.source.IAnnotationHoverExtension2
+ */
+public interface IAnnotationHover {
+
+    /**
+     * Returns the text which should be presented in the a
+     * hover popup window. This information is requested based on
+     * the specified line number.
+     *
+     * @param sourceViewer the source viewer this hover is registered with
+     * @param lineNumber the line number for which information is requested
+     * @return the requested information or <code>null</code> if no such information exists
+     */
+    String getHoverInfo(ISourceViewer sourceViewer, int lineNumber);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IAnnotationHoverExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,132 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IAnnotationHoverExtension;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.IInformationControlCreator;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.source.IAnnotationHover} for
+ * <ul>
+ * <li>providing its own information control creator</li>
+ * <li>providing the range of lines for which the hover for a given line is valid</li>
+ * <li>providing whether the information control can interact with the mouse cursor</li>
+ * </ul>
+ *
+ * @see dwtx.jface.text.IInformationControlCreator
+ * @see dwtx.jface.text.source.IAnnotationHover
+ * @since 3.0
+ */
+public interface IAnnotationHoverExtension {
+
+    /**
+     * Returns the hover control creator of this annotation hover.
+     *
+     * @return the hover control creator
+     */
+    IInformationControlCreator getHoverControlCreator();
+
+    /**
+     * Returns whether the provided information control can interact with the mouse cursor. I.e. the
+     * hover must implement custom information control management.
+     *
+     * @return <code>true</code> if the mouse cursor can be handled
+     */
+    bool canHandleMouseCursor();
+
+    /**
+     * Returns the object which should be presented in the a
+     * hover popup window. The information is requested based on
+     * the specified line range.
+     *
+     * @param sourceViewer the source viewer this hover is registered with
+     * @param lineRange the line range for which information is requested
+     * @param visibleNumberOfLines the number of visible lines
+     * @return the requested information or <code>null</code> if no such information exists
+     */
+    Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleNumberOfLines);
+
+    /**
+     * Returns the range of lines that include the given line number for which
+     * the same hover information is valid.
+     *
+     * @param viewer the viewer which the hover is queried for
+     * @param lineNumber the line number of the line for which a hover is displayed for
+     * @return the computed line range or <code>null</code> for no range
+     */
+    ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IAnnotationHoverExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IAnnotationHoverExtension2;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.source.IAnnotationHover} for
+ * <ul>
+ * <li>providing whether the information control can interact with the mouse wheel</li>
+ * </ul>
+ *
+ * @see dwtx.jface.text.source.IAnnotationHover
+ * @since 3.2
+ */
+public interface IAnnotationHoverExtension2 {
+    /**
+     * Returns whether the provided information control can interact with the mouse wheel. I.e. the
+     * hover will not be closed when the mouse wheel is moved.
+     *
+     * @return <code>true</code> if the mouse wheel is handled by the hover
+     */
+    bool canHandleMouseWheel();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IAnnotationMap.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IAnnotationMap;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+import dwtx.jface.text.ISynchronizable;
+
+
+/**
+ * An annotation map is a map specialized for the requirements of an annotation
+ * model. The annotation map supports a customizable lock object which is used
+ * to synchronize concurrent operations on the map (see
+ * {@link dwtx.jface.text.ISynchronizable}. The map supports two
+ * iterator methods, one for the values and one for the keys of the map. The
+ * returned iterators are robust, i.e. they work on a copy of the values and
+ * keys set that is made at the point in time the iterator methods are called.
+ * <p>
+ * The returned collections of the methods <code>values</code>,
+ * <code>entrySet</code>, and <code>keySet</code> are not synchronized on
+ * the annotation map's lock object.
+ * <p>
+ *
+ * @see dwtx.jface.text.source.IAnnotationModel
+ * @since 3.0
+ */
+public interface IAnnotationMap : Map, ISynchronizable {
+
+    /**
+     * Returns an iterator for a copy of this annotation map's values.
+     *
+     * @return an iterator for a copy of this map's values
+     */
+    Iterator valuesIterator();
+
+    /**
+     * Returns an iterator for a copy of this map's key set.
+     *
+     * @return an iterator for a copy of this map's key set
+     */
+    Iterator keySetIterator();
+
+    /**
+     * {@inheritDoc}
+     *
+     * The returned set is not synchronized on this annotation map's lock object.
+     */
+    Set entrySet();
+
+    /**
+     * {@inheritDoc}
+     *
+     * The returned set is not synchronized on this annotation map's lock object.
+     */
+    Set keySet();
+
+    /**
+     * {@inheritDoc}
+     *
+     * The returned collection is not synchronized on this annotation map's lock object.
+     */
+    Collection values();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IAnnotationModel.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,214 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IAnnotationModel;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.Position;
+
+
+/**
+ * This interface defines the model for managing annotations attached to a document.
+ * The model maintains a set of annotations for a given document and notifies registered annotation
+ * model listeners about annotation model changes. It also provides methods
+ * for querying the current position of an annotation managed
+ * by this model.
+ * <p>
+ * In order to provide backward compatibility for clients of <code>IAnnotationModel</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interfaces
+ * exist:
+ * <ul>
+ * <li> {@link dwtx.jface.text.source.IAnnotationModelExtension} since version 3.0 introducing the concept
+ *      of model piggybacking annotation models, modification time stamps, and enhanced manipulation methods.
+ * </li>
+ * <li> {@link dwtx.jface.text.source.IAnnotationModelExtension2} since version 3.4 allows to retrieve
+ *      annotations within a given region.
+ * </li>
+ * </ul>
+ * </p>
+ *
+ * Clients may implement this interface or use the default implementation provided
+ * by <code>AnnotationModel</code>.
+ *
+ * @see dwtx.jface.text.source.IAnnotationModelExtension
+ * @see dwtx.jface.text.source.IAnnotationModelExtension2
+ * @see dwtx.jface.text.source.Annotation
+ * @see dwtx.jface.text.source.IAnnotationModelListener
+ */
+public interface IAnnotationModel {
+
+    /**
+     * Registers the annotation model listener with this annotation model.
+     * After registration listener is informed about each change of this model.
+     * If the listener is already registered nothing happens.
+     *
+     * @param listener the listener to be registered, may not be <code>null</code>
+     */
+    void addAnnotationModelListener(IAnnotationModelListener listener);
+
+    /**
+     * Removes the listener from the model's list of annotation model listeners.
+     * If the listener is not registered with the model nothing happens.
+     *
+     * @param listener the listener to be removed, may not be <code>null</code>
+     */
+    void removeAnnotationModelListener(IAnnotationModelListener listener);
+
+    /**
+     * Connects the annotation model to a document. The annotations managed
+     * by this model must subsequently update according to the changes applied
+     * to the document. Once an annotation model is connected to a document,
+     * all further <code>connect</code> calls must mention the document the
+     * model is already connected to. An annotation model primarily uses
+     * <code>connect</code> and <code>disconnect</code> for reference counting
+     * the document. Reference counting frees the clients from keeping tracker
+     * whether a model has already been connected to a document.
+     *
+     * @param document the document the model gets connected to,
+     *      may not be <code>null</code>
+     *
+     * @see #disconnect(IDocument)
+     */
+    void connect(IDocument document);
+
+    /**
+     * Disconnects this model from a document. After that, document changes no longer matter.
+     * An annotation model may only be disconnected from a document to which it has been
+     * connected before. If the model reference counts the connections to a document,
+     * the connection to the document may only be terminated if the reference count does
+     * down to 0.
+     *
+     * @param document the document the model gets disconnected from,
+     *      may not be <code>null</code>
+     *
+     * @see #connect(IDocument) for further specification details
+     */
+    void disconnect(IDocument document);
+
+    /**
+     * Adds a annotation to this annotation model. The annotation is associated with
+     * with the given position which describes the range covered by the annotation.
+     * All registered annotation model listeners are informed about the change.
+     * If the model is connected to a document, the position is automatically
+     * updated on document changes. If the annotation is already managed by
+     * this annotation model or is not a valid position in the connected document
+     * nothing happens.
+     * <p>
+     * <strong>Performance hint:</strong> Use {@link IAnnotationModelExtension#replaceAnnotations(Annotation[], java.util.Map)}
+     * if several annotations are added and/or removed.
+     * </p>
+     *
+     * @param annotation the annotation to add, may not be <code>null</code>
+     * @param position the position describing the range covered by this annotation,
+     *      may not be <code>null</code>
+     */
+    void addAnnotation(Annotation annotation, Position position);
+
+    /**
+     * Removes the given annotation from the model. I.e. the annotation is no
+     * longer managed by this model. The position associated with the annotation
+     * is no longer updated on document changes. If the annotation is not
+     * managed by this model, nothing happens.
+     * <p>
+     * <strong>Performance hint:</strong> Use {@link IAnnotationModelExtension#replaceAnnotations(Annotation[], java.util.Map)}
+     * if several annotations are removed and/or added.
+     * </p>
+     *
+     * @param annotation the annotation to be removed from this model,
+     *      may not be <code>null</code>
+     */
+    void removeAnnotation(Annotation annotation);
+
+    /**
+     * Returns all annotations managed by this model.
+     *
+     * @return all annotations managed by this model (element type: {@link Annotation})
+     */
+    Iterator getAnnotationIterator();
+
+    /**
+     * Returns the position associated with the given annotation.
+     *
+     * @param annotation the annotation whose position should be returned
+     * @return the position of the given annotation or <code>null</code> if no
+     *      associated annotation exists
+     */
+    Position getPosition(Annotation annotation);
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IAnnotationModelExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IAnnotationModelExtension;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+import dwtx.jface.text.Position;
+
+
+/**
+ * Extends {@link dwtx.jface.text.source.IAnnotationModel}with the
+ * ability piggyback other annotation models. It also introduces the concept of
+ * modification time stamps and adds methods for richer manipulation methods.
+ *
+ * @since 3.0
+ */
+public interface IAnnotationModelExtension {
+
+    /**
+     * Attaches <code>attachment</code> to the receiver. Connects
+     * <code>attachment</code> to the currently connected document. If
+     * <code>attachment</code> is already attached (even) under a different
+     * key), it is not attached again.
+     *
+     * @param key the key through which the attachment is identified.
+     * @param attachment the attached <code>IAnnotationModel</code>
+     */
+    void addAnnotationModel(Object key, IAnnotationModel attachment);
+
+    /**
+     * Returns the attached <code>IAnnotationModel</code> for <code>key</code>,
+     * or <code>null</code> if none is attached for <code>key</code>.
+     *
+     * @param key the key through which the attachment is identified.
+     * @return an <code>IAnnotationModel</code> attached under
+     *         <code>key</code>, or <code>null</code>
+     */
+    IAnnotationModel getAnnotationModel(Object key);
+
+    /**
+     * Removes and returns the attached <code>IAnnotationModel</code> for
+     * <code>key</code>.
+     *
+     * @param key the key through which the attachment is identified.
+     * @return an <code>IAnnotationModel</code> attached under
+     *         <code>key</code>, or <code>null</code>
+     */
+    IAnnotationModel removeAnnotationModel(Object key);
+
+    /**
+     * Adds and removes annotations to/from this annotation model in a single
+     * step. The annotations to remove are given in an array. The annotations to
+     * add are provided in a map associating the annotations with the positions
+     * at which they should be added. All registered annotation model listeners
+     * are informed about the change. If the model is connected to a document,
+     * the positions are automatically updated on document changes. Annotations
+     * that are already managed by this annotation model or are not associated
+     * with a valid position in the connected document have no effect.
+     *
+     * @param annotationsToRemove the annotations to be removed, may be
+     *            <code>null</code>
+     * @param annotationsToAdd the annotations which will be added, may be
+     *            <code>null</code> each map entry has an
+     *            <code>Annotation</code> as key and a <code>Position</code>
+     *            as value
+     * @throws ClassCastException if one of the map key or values has a wrong
+     *             type
+     */
+    void replaceAnnotations(Annotation[] annotationsToRemove, Map annotationsToAdd) ;
+
+    /**
+     * Modifies the position associated with the given annotation to equal the
+     * given position. If the annotation is not yet managed by this annotation
+     * model, the annotation is added. If the given position is
+     * <code>null</code> the annotation is removed from the model. All
+     * annotation model change listeners will be informed about the change.
+     *
+     * @param annotation the annotation whose associated position should be
+     *            modified
+     * @param position the position to whose values the associated position
+     *            should be changed
+     */
+    void modifyAnnotationPosition(Annotation annotation, Position position);
+
+    /**
+     * Removes all annotations from this annotation model.
+     */
+    void removeAllAnnotations();
+
+    /**
+     * Returns the modification stamp of this annotation model.
+     *
+     * @return the modification stamp of this annotation model
+     */
+    Object getModificationStamp();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IAnnotationModelExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IAnnotationModelExtension2;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+/**
+ * Extends {@link dwtx.jface.text.source.IAnnotationModel} with the
+ * ability to retrieve a set of annotations within a given region.
+ *
+ * @since 3.4
+ */
+public interface IAnnotationModelExtension2 {
+
+    /**
+     * Returns an iterator over all annotations managed by this model that are
+     * inside the given region.
+     * 
+     * @param offset the start position of the region, must be >= 0
+     * @param length the length of the region, must be >= 0
+     * @param canStartBefore if <code>true</code> then annotations are included
+     *            which start before the region if they end at or after the region's start
+     * @param canEndAfter if <code>true</code> then annotations are included
+     *            which end after the region if they start at or before the region's end
+     * @return all annotations inside the region managed by this model (element type: {@link Annotation})
+     */
+    Iterator getAnnotationIterator(int offset, int length, bool canStartBefore, bool canEndAfter);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IAnnotationModelListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IAnnotationModelListener;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Interface for objects interested in getting informed about annotation model
+ * changes. Changes are the addition or removal of annotations managed by the
+ * model. Clients may implement this interface.
+ *
+ * In order to provided backward compatibility for clients of
+ * <code>IAnnotationModelListener</code>, extension interfaces are used to
+ * provide a means of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.source.IAnnotationModelListenerExtension}
+ *     since version 2.0 replacing the change notification mechanisms.</li>
+ * </ul>
+ *
+ * @see dwtx.jface.text.source.IAnnotationModel
+ */
+public interface IAnnotationModelListener {
+
+    /**
+     * Called if a model change occurred on the given model.<p>
+     * Replaced by {@link IAnnotationModelListenerExtension#modelChanged(AnnotationModelEvent)}.
+     *
+     * @param model the changed annotation model
+     */
+    void modelChanged(IAnnotationModel model);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IAnnotationModelListenerExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,97 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IAnnotationModelListenerExtension;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Extension interface for {@link IAnnotationModelListener}. Introduces a
+ * notification mechanism that notifies the user by means of <code>AnnotationModelEvent</code>s.
+ * Thus, more detailed information can be sent to the listener. This mechanism replaces the original notification
+ * mechanism of <code>IAnnotationModelListener</code>.
+ *
+ * @since 2.0
+ */
+public interface IAnnotationModelListenerExtension {
+
+    /**
+     * Called if a model change occurred on the given model.
+     *
+     * @param event the event to be sent out
+     */
+    void modelChanged(AnnotationModelEvent event);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IAnnotationPresentation.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IAnnotationPresentation;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.graphics.GC;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Canvas;
+
+/**
+ * Interface for annotations that can take care of their own visible representation.
+ *
+ * @since 3.0
+ */
+public interface IAnnotationPresentation {
+
+    /**
+     * The default annotation layer.
+     */
+    static const int DEFAULT_LAYER= 0;
+
+
+    /**
+     * Returns the annotations drawing layer.
+     *
+     * @return the annotations drawing layer
+     */
+    int getLayer();
+
+    /**
+     * Implement this method to draw a graphical representation
+     * of this annotation within the given bounds.
+     * <p>
+     * <em>Note that this method is not used when drawing annotations on the editor's
+     * text widget. This is handled trough a {@link dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy}.</em>
+     * </p>
+     * @param gc the drawing GC
+     * @param canvas the canvas to draw on
+     * @param bounds the bounds inside the canvas to draw on
+     */
+    void paint(GC gc, Canvas canvas, Rectangle bounds);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IChangeRulerColumn.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IChangeRulerColumn;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.graphics.Color;
+
+/**
+ * An <code>IChangeRulerColumn</code> can display quick diff information.
+ *
+ * @since 3.0
+ */
+public interface IChangeRulerColumn : IVerticalRulerColumn, IVerticalRulerInfoExtension {
+
+    /** The ID under which the quick diff model is registered with a document's annotation model. */
+    public static const String QUICK_DIFF_MODEL_ID= "diff"; //$NON-NLS-1$
+
+    /**
+     * Sets the hover of this ruler column.
+     *
+     * @param hover the hover that will produce hover information text for this ruler column
+     */
+    public abstract void setHover(IAnnotationHover hover);
+
+    /**
+     * Sets the background color for normal lines. The color has to be disposed of by the caller when
+     * the receiver is no longer used.
+     *
+     * @param backgroundColor the new color to be used as standard line background
+     */
+    public abstract void setBackground(Color backgroundColor);
+
+    /**
+     * Sets the background color for added lines. The color has to be disposed of by the caller when
+     * the receiver is no longer used.
+     *
+     * @param addedColor the new color to be used for the added lines background
+     */
+    public abstract void setAddedColor(Color addedColor);
+
+    /**
+     * Sets the background color for changed lines. The color has to be disposed of by the caller when
+     * the receiver is no longer used.
+     *
+     * @param changedColor the new color to be used for the changed lines background
+     */
+    public abstract void setChangedColor(Color changedColor);
+
+    /**
+     * Sets the color for the deleted lines indicator. The color has to be disposed of by the caller when
+     * the receiver is no longer used.
+     *
+     * @param deletedColor the new color to be used for the deleted lines indicator.
+     */
+    public abstract void setDeletedColor(Color deletedColor);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ICharacterPairMatcher.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.ICharacterPairMatcher;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+
+/**
+ * A character pair matcher finds to a character at a certain document offset
+ * the matching peer character. It is the matchers responsibility to define the
+ * concepts of "matching" and "peer". The matching process starts at a given
+ * offset. Starting of this offset, the matcher chooses a character close to
+ * this offset. The anchor defines whether the chosen character is left or right
+ * of the initial offset. The matcher then searches for the matching peer
+ * character of the chosen character and if it finds one, delivers the minimal
+ * region of the document that contains both characters.
+ *
+ * @since 2.1
+ */
+public interface ICharacterPairMatcher {
+
+    /**
+     * Indicates the anchor value "right".
+     */
+    static const int RIGHT= 0;
+    /**
+     * Indicates the anchor value "left".
+     */
+    static const int LEFT= 1;
+
+
+    /**
+     * Disposes this pair matcher.
+     */
+    void dispose();
+
+    /**
+     * Clears this pair matcher. I.e. the matcher throws away all state it might
+     * remember and prepares itself for a new call of the <code>match</code>
+     * method.
+     */
+    void clear();
+
+    /**
+     * Starting at the given offset, the matcher chooses a character close to this offset.
+     * The matcher then searches for the matching peer character of the chosen character
+     * and if it finds one, returns the minimal region of the document that contains both characters.
+     * It returns <code>null</code> if there is no peer character.
+     *
+     * @param iDocument the document to work on
+     * @param i the start offset
+     * @return the minimal region containing the peer characters
+     */
+    IRegion match(IDocument iDocument, int i);
+
+    /**
+     * Returns the anchor for the region of the matching peer characters. The anchor
+     * says whether the character that has been chosen to search for its peer character
+     * has been left or right of the initial offset.
+     *
+     * @return <code>RIGHT</code> or <code>LEFT</code>
+     */
+    int getAnchor();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ILineDiffInfo.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,140 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.ILineDiffInfo;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Describes the change state of one line, which consists of the state of the line itself, which
+ * can be <code>UNCHANGED</code>, <code>CHANGED</code> or <code>ADDED</code>, and the number of
+ * deleted lines before and after this line.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public interface ILineDiffInfo {
+
+    /** Denotes an unchanged line. */
+    static const int UNCHANGED= 0;
+
+    /** Denotes an added line. */
+    static const int ADDED= 1;
+
+    /** Denotes a changed line. */
+    static const int CHANGED= 2;
+
+    /**
+     * Returns the number of deleted lines after this line.
+     *
+     * @return the number of lines after this line.
+     */
+    int getRemovedLinesBelow();
+
+    /**
+     * Returns the number of deleted lines before this line.
+     *
+     * @return the number of lines before this line.
+     */
+    int getRemovedLinesAbove();
+
+    /**
+     * Returns the type of this line, one out of <code>UNCHANGED</code>, <code>CHANGED</code> or
+     * <code>ADDED</code>.
+     *
+     * @return the type of this line.
+     */
+    int getChangeType();
+
+    /**
+     * Returns whether this line has any changes (to itself, or any deletions before or after it).
+     *
+     * @return <code>true</code>, if the line's state (as returned by <code>getType</code>) is
+     * either <code>CHANGED</code> or <code>ADDED</code> or either of <code>getRemovedLinesBelow</code>
+     * and <code>getRemovedLinesAbove</code> would return a number &gt; 0
+     */
+    bool hasChanges();
+
+    /**
+     * Returns the original text of this changed region
+     *
+     * @return the original text of this changed region, including any deleted lines. The returned
+     * value and its elements may not be <code>null/code>, it may however be of zero length
+     */
+    String[] getOriginalText();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ILineDiffer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,155 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.ILineDiffer;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.BadLocationException;
+
+
+/**
+ * Protocol that allows direct access to line information. Usually, implementations will also
+ * implement <code>IAnnotationModel</code>, which only allows <code>Iterator</code> based access
+ * to annotations.
+ * <p>
+ * <code>ILineDiffer</code> also allows to revert any lines to their original
+ * contents as defined by the quick diff reference used by the receiver.
+ * </p>
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ * <p>
+ * In order to provide backward compatibility for clients of <code>ILineDiffer</code>, extension
+ * interfaces are used to provide a means of evolution. The following extension interface
+ * exists:
+ * <ul>
+ * <li> {@link ILineDifferExtension} (since version 3.1): introducing the concept
+ *      suspending and resuming an <code>ILineDiffer</code>.</li>
+ * <li> {@link ILineDifferExtension2} (since version 3.3): allowing to query the suspension state
+ * of an <code>ILineDiffer</code>.</li>
+ * </ul>
+ * </p>
+ *
+ * @since 3.0
+ */
+public interface ILineDiffer {
+
+    /**
+     * Determines the line state for line <code>line</code> in the targeted document.
+     *
+     * @param line the line to get diff information for
+     * @return the line information object for <code>line</code> or <code>null</code> if none
+     */
+    ILineDiffInfo getLineInfo(int line);
+
+    /**
+     * Reverts a single changed line to its original state, not touching any lines that
+     * are deleted at its borders.
+     *
+     * @param line the line number of the line to be restored.
+     * @throws BadLocationException if <code>line</code> is out of bounds.
+     */
+    void revertLine(int line) ;
+
+    /**
+     * Reverts a block of modified / added lines to their original state, including any deleted
+     * lines inside the block or at its borders. A block is considered to be a range of modified
+     * (e.g. changed, or added) lines.
+     *
+     * @param line any line in the block to be reverted.
+     * @throws BadLocationException if <code>line</code> is out of bounds.
+     */
+    void revertBlock(int line) ;
+
+    /**
+     * Reverts a range of lines to their original state, including any deleted
+     * lines inside the block or at its borders.
+     *
+     * @param line any line in the block to be reverted.
+     * @param nLines the number of lines to be reverted, must be &gt; 0.
+     * @throws BadLocationException if <code>line</code> is out of bounds.
+     */
+    void revertSelection(int line, int nLines) ;
+
+    /**
+     * Restores the deleted lines after <code>line</code>.
+     *
+     * @param line the deleted lines following this line number are restored.
+     * @return the number of restored lines.
+     * @throws BadLocationException if <code>line</code> is out of bounds.
+     */
+    int restoreAfterLine(int line) ;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ILineDifferExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,100 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.ILineDifferExtension;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link ILineDiffer}.
+ * <p>
+ * Introduces the concept of suspending a differ. A <code>ILineDiffer</code> may
+ * be suspended into a dormant state, and resumed to normal operation.
+ * </p>
+ *
+ * @since 3.1
+ */
+public interface ILineDifferExtension {
+
+    /**
+     * Suspends the receiver. All differences are cleared.
+     */
+    void suspend();
+
+    /**
+     * Resumes the receiver. Must only be called after suspend.
+     */
+    void resume();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ILineDifferExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.ILineDifferExtension2;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link ILineDiffer}.
+ * <p>
+ * Allows to query the suspension state.
+ * </p>
+ *
+ * @since 3.3
+ */
+public interface ILineDifferExtension2 {
+    /**
+     * Returns <code>true</code> if the receiver is suspended, <code>false</code> otherwise.
+     * 
+     * @return <code>true</code> if the receiver is suspended, <code>false</code> otherwise
+     */
+    bool isSuspended();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ILineRange.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.ILineRange;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Describes a range of lines.
+ * <p>
+ * Note that the number of lines is 1-based, e.g. <code>getStartLine() + getNumberOfLines()</code>
+ * computes the first line <em>after</em> the range, and a range with
+ * <code>getNumberOfLines() is 0</code> is empty.
+ * </p>
+ * 
+ * @since 3.0
+ */
+public interface ILineRange {
+
+    /**
+     * Returns the start line of this line range or <code>-1</code>.
+     *
+     * @return the start line of this line range or <code>-1</code> if this line range is invalid.
+     */
+    int getStartLine();
+
+    /**
+     * Returns the number of lines of this line range or <code>-1</code>.
+     *
+     * @return the number of lines in this line range or <code>-1</code> if this line range is invalid.
+     */
+    int getNumberOfLines();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IOverviewRuler.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IOverviewRuler;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.graphics.Color;
+import dwt.widgets.Control;
+
+/**
+ * This interface defines a visual component which may serve
+ * text viewers as an overview annotation presentation area.  This means,
+ * presentation of annotations is independent from the actual view port of
+ * the text viewer. The annotations of the viewer's whole document are
+ * visible in the overview ruler.
+ * <p>
+ * This interfaces embodies three contracts:
+ * <ul>
+ * <li> The overview ruler retrieves the annotations it presents from an annotation model.
+ * <li> The ruler is a visual component which must be integrated in a hierarchy of DWT controls.
+ * <li> The ruler provides interested clients with mapping and
+ *      interaction information. This covers the mapping between
+ *      coordinates of the ruler's control and line numbers based
+ *      on the connected text viewer's document (<code>IVerticalRulerInfo</code>).
+ * </ul></p>
+ * <p>
+ * Clients may implement this interface or use the default implementation provided
+ * by <code>OverviewlRuler</code>.</p>
+ *
+ * @see dwtx.jface.text.ITextViewer
+ * @since 2.1
+ */
+public interface IOverviewRuler : IVerticalRuler {
+
+    /**
+     * Returns whether there is an annotation an the given vertical coordinate. This
+     * method takes the compression factor of the overview ruler into account.
+     *
+     * @param y the y-coordinate
+     * @return <code>true</code> if there is an annotation, <code>false</code> otherwise
+     */
+    bool hasAnnotation(int y);
+
+    /**
+     * Returns the height of the visual presentation of an annotation in this
+     * overview ruler. Assumes that all annotations are represented using the
+     * same height.
+     *
+     * @return int the visual height of an annotation
+     */
+    int getAnnotationHeight();
+
+    /**
+     * Sets the color for the given annotation type in this overview ruler.
+     *
+     * @param annotationType the annotation type
+     * @param color the color
+     */
+    void setAnnotationTypeColor(Object annotationType, Color color);
+
+    /**
+     * Sets the drawing layer for the given annotation type in this overview ruler.
+     *
+     * @param annotationType the annotation type
+     * @param layer the drawing layer
+     */
+    void setAnnotationTypeLayer(Object annotationType, int layer);
+
+    /**
+     * Adds the given annotation type to this overview ruler. Starting with this
+     * call, annotations of the given type are shown in the overview ruler.
+     *
+     * @param annotationType the annotation type
+     */
+    void addAnnotationType(Object annotationType);
+
+    /**
+     * Removes the given annotation type from this overview ruler. Annotations
+     * of the given type are no longer shown in the overview ruler.
+     *
+     * @param annotationType the annotation type
+     */
+    void removeAnnotationType(Object annotationType);
+
+    /**
+     * Adds the given annotation type to the header of this ruler. Starting with
+     * this call, the presence of annotations is tracked and the header is drawn
+     * in the configured color.
+     *
+     * @param annotationType the annotation type to be tracked
+     */
+    void addHeaderAnnotationType(Object annotationType);
+
+    /**
+     * Removes the given annotation type from the header of this ruler. The
+     * presence of annotations of the given type is no longer tracked and the
+     * header is drawn in the default color, depending on the other configured
+     * configured annotation types.
+     *
+     * @param annotationType the annotation type to be removed
+     */
+    void removeHeaderAnnotationType(Object annotationType);
+
+    /**
+     * Returns this rulers header control. This is the little area between the
+     * top of the text widget and the top of this overview ruler.
+     *
+     * @return the header control of this overview ruler.
+     */
+    Control getHeaderControl();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ISharedTextColors.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,108 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.ISharedTextColors;
+
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.graphics.Color;
+import dwt.graphics.RGB;
+
+
+/**
+ * Manages DWT color objects. Until the <code>dispose</code> method is called,
+ * the same color object is returned for equal <code>RGB</code> values.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ *
+ * @since 2.1
+ */
+public interface ISharedTextColors {
+
+    /**
+     * Returns the color object for the value represented by the given
+     * <code>RGB</code> object.
+     *
+     * @param rgb the RBG color specification
+     * @return the color object for the given RGB value
+     */
+    Color getColor(RGB rgb);
+
+    /**
+     * Tells this object to dispose all its managed colors.
+     */
+    void dispose();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ISourceViewer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,264 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.ISourceViewer;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextOperationTarget;
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * In addition to the text viewer functionality a source viewer supports:
+ * <ul>
+ * <li>visual annotations based on an annotation model
+ * <li>visual range indication
+ * <li>management of text viewer add-ons
+ * <li>explicit configuration
+ * </ul>
+ * It is assumed that range indication and visual annotations are shown inside
+ * the same presentation area. There are no assumptions about whether this area
+ * is different from the viewer's text widget.
+ * <p>
+ * As the visibility of visual annotations can dynamically be changed, it is
+ * assumed that the annotation presentation area can dynamically be hidden if it
+ * is different from the text widget.
+ * <p>
+ * In order to provide backward compatibility for clients of
+ * <code>ISourceViewer</code>, extension interfaces are used as a means of
+ * evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.source.ISourceViewerExtension} since version 2.1
+ * introducing the concept of an annotation overview.</li>
+ * <li>{@link dwtx.jface.text.source.ISourceViewerExtension2} since version 3.0
+ * allowing source viewers to roll back a previously performed configuration and
+ * allows access to the viewer's visual annotation model.</li>
+ * <li>{@link dwtx.jface.text.source.ISourceViewerExtension3} since version 3.2
+ * introducing the concept of a quick assist assistant and providing access
+ * to the quick assist invocation context as well as the current annotation hover.</li>
+ * <li>{@link dwtx.jface.text.source.ISourceViewerExtension4} since version 3.4
+ * introducing API to access a minimal set of content assistant APIs.</li>
+ * </ul></p>
+ * <p>
+ * Clients may implement this interface and its extension interfaces or use the
+ * default implementation provided by
+ * {@link dwtx.jface.text.source.SourceViewer}.</p>
+ *
+ * @see dwtx.jface.text.source.ISourceViewerExtension
+ * @see dwtx.jface.text.source.ISourceViewerExtension2
+ * @see dwtx.jface.text.source.ISourceViewerExtension3
+ * @see dwtx.jface.text.source.ISourceViewerExtension4
+ */
+public interface ISourceViewer : ITextViewer {
+
+    /**
+     * Text operation code for requesting content assist to show completion
+     * proposals for the current insert position.
+     */
+    static const int CONTENTASSIST_PROPOSALS= ITextOperationTarget.STRIP_PREFIX + 1;
+
+    /**
+     * Text operation code for requesting content assist to show
+     * the content information for the current insert position.
+     */
+    static const int CONTENTASSIST_CONTEXT_INFORMATION=  ITextOperationTarget.STRIP_PREFIX + 2;
+
+    /**
+     * Text operation code for formatting the selected text or complete document
+     * of this viewer if the selection is empty.
+     */
+    static const int FORMAT= ITextOperationTarget.STRIP_PREFIX + 3;
+
+    /**
+     * Text operation code for requesting information at the current insertion position.
+     * @since 2.0
+     */
+    static const int INFORMATION = ITextOperationTarget.STRIP_PREFIX + 4;
+
+    /*
+     * XXX: Cannot continue numbering due to operation codes used in ProjectionViewer
+     */
+
+    /**
+     * Text operation code for requesting quick assist. This will normally
+     * show quick assist and quick fix proposals for the current position.
+     * @since 3.2
+     */
+    static const int QUICK_ASSIST= ITextOperationTarget.STRIP_PREFIX + 10;
+
+    /**
+     * Configures the source viewer using the given configuration. Prior to 3.0 this
+     * method can only be called once. Since 3.0 this method can be called again
+     * after a call to {@link ISourceViewerExtension2#unconfigure()}.
+     *
+     * @param configuration the source viewer configuration to be used
+     */
+    void configure(SourceViewerConfiguration configuration);
+
+    /**
+     * Sets the annotation hover of this source viewer. The annotation hover
+     * provides the information to be displayed in a hover popup window
+     * if requested over the annotation presentation area. The annotation
+     * hover is assumed to be line oriented.
+     *
+     * @param annotationHover the hover to be used, <code>null</code> is a valid argument
+     */
+    void setAnnotationHover(IAnnotationHover annotationHover);
+
+    /**
+     * Sets the given document as this viewer's text model and the
+     * given annotation model as the model for this viewer's visual
+     * annotations. The presentation is accordingly updated. An appropriate
+     * <code>TextEvent</code> is issued. This text event does not carry
+     * a related document event.
+     *
+     * @param document the viewer's new input document
+     * @param annotationModel the model for the viewer's visual annotations
+     *
+     * @see ITextViewer#setDocument(IDocument)
+     */
+    void setDocument(IDocument document, IAnnotationModel annotationModel);
+
+    /**
+     * Sets the given document as this viewer's text model and the
+     * given annotation model as the model for this viewer's visual
+     * annotations. The presentation is accordingly updated whereby
+     * only the specified region is exposed. An appropriate
+     * <code>TextEvent</code> is issued. The text event does not carry a
+     * related document event. This method is a convenience method for
+     * <code>setDocument(document, annotationModel);setVisibleRegion(offset, length)</code>.
+     *
+     * @param document the new input document
+     * @param annotationModel the model of the viewer's visual annotations
+     * @param modelRangeOffset the offset of the model range
+     * @param modelRangeLength the length of the model range
+     *
+     * @see ITextViewer#setDocument(IDocument, int, int)
+     */
+    void setDocument(IDocument document, IAnnotationModel annotationModel, int modelRangeOffset, int modelRangeLength);
+
+    /**
+     * Returns this viewer's annotation model. Use
+     * {@link ISourceViewerExtension2#getVisualAnnotationModel()}in order to
+     * get access to the viewer's visual annotation model.
+     *
+     * @return this viewer's annotation model
+     */
+    IAnnotationModel getAnnotationModel();
+
+    /**
+     * Sets the annotation used by this viewer as range indicator. The
+     * range covered by this annotation is referred to as range indication.
+     *
+     * @param rangeIndicator the annotation to be used as this viewer's range indicator
+     */
+    void setRangeIndicator(Annotation rangeIndicator);
+
+    /**
+     * Sets the viewers's range indication to the specified range. Its is indicated
+     * whether the cursor should also be moved to the beginning of the specified range.
+     *
+     * @param offset the offset of the range
+     * @param length the length of the range
+     * @param moveCursor indicates whether the cursor should be moved to the given offset
+     */
+    void setRangeIndication(int offset, int length, bool moveCursor);
+
+    /**
+     * Returns the viewer's range indication.
+     *
+     * @return the viewer's range indication.
+     */
+    IRegion getRangeIndication();
+
+    /**
+     * Removes the viewer's range indication. There is no visible range indication
+     * after this method completed.
+     */
+    void removeRangeIndication();
+
+    /**
+     * Controls the visibility of annotations and in the case of separate
+     * presentation areas of text and annotations, the visibility of the
+     * annotation's presentation area.<p>
+     * By default, annotations and their presentation area are visible.
+     *
+     * @param show indicates the visibility of annotations
+     */
+    void showAnnotations(bool show);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ISourceViewerExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.source.ISourceViewerExtension;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface {@link dwtx.jface.text.source.ISourceViewer}.
+ * <p>
+ * Extends the source viewer with the concept of an annotation overview. The
+ * annotation overview differs from the annotation presentation in that it is
+ * independent from the viewer's view port, i.e. the annotations of the whole
+ * document are visible. There are no assumptions about the area in which the
+ * annotation overview is shown.
+ * <p>
+ * As the visibility of annotation overview can dynamically be changed, it is
+ * assumed that the presentation area can dynamically be hidden if it is
+ * different from the text widget.
+ *
+ * @see dwtx.jface.text.source.ISourceViewer
+ * @since 2.1
+ */
+public interface ISourceViewerExtension {
+
+    /**
+     * Shows/hides an overview representation of the annotations of the whole document of this viewer.
+     *
+     * @param show <code>true</code> if annotation overview should be visible, <code>false</code> otherwise
+     */
+    void showAnnotationsOverview(bool show);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ISourceViewerExtension2.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.source.ISourceViewerExtension2;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.source.ISourceViewer}.<p>
+ * Allows the source viewer to roll back a previous configuration process and allows
+ * clients access to the viewer's visual annotation model.
+ *
+ * @since 3.0
+ */
+public interface ISourceViewerExtension2 {
+
+    /**
+     * Rolls back the configuration process of this source viewer. The source
+     * viewer can be configured again after a call to this method. Unlike
+     * {@link ISourceViewer#configure(SourceViewerConfiguration)} this method
+     * can be called more than once without interleaving calls to
+     * {@link ISourceViewer#configure(SourceViewerConfiguration)}.
+     */
+    void unconfigure();
+
+    /**
+     * Returns the visual annotation model of this viewer.
+     *
+     * @return the visual annotation model of this viewer
+     */
+    IAnnotationModel getVisualAnnotationModel();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ISourceViewerExtension3.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.source.ISourceViewerExtension3;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.quickassist.IQuickAssistAssistant;
+import dwtx.jface.text.quickassist.IQuickAssistInvocationContext;
+
+/**
+ * Extension interface for {@link dwtx.jface.text.source.ISourceViewer}.<p>
+ * It introduces the concept of a quick assist assistant and provides access
+ * to the quick assist invocation context. It also gives access to any currently 
+ * showing annotation hover.</p>
+ *
+ * @see IQuickAssistAssistant
+ * @see IQuickAssistInvocationContext
+ * @since 3.2
+ */
+public interface ISourceViewerExtension3 {
+
+    /**
+     * Returns this viewers quick assist assistant.
+     *
+     * @return the quick assist assistant or <code>null</code> if none is configured
+     * @since 3.2
+     */
+    public IQuickAssistAssistant getQuickAssistAssistant();
+
+    /**
+     * Returns this viewer's quick assist invocation context.
+     *
+     * @return the quick assist invocation context or <code>null</code> if none is available
+     */
+    IQuickAssistInvocationContext getQuickAssistInvocationContext();
+
+    /**
+     * Returns the currently displayed annotation hover if any, <code>null</code> otherwise.
+     *
+     * @return the currently displayed annotation hover or <code>null</code>
+     */
+    IAnnotationHover getCurrentAnnotationHover();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ISourceViewerExtension4.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.ISourceViewerExtension4;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.contentassist.IContentAssistant;
+
+
+/**
+ * Extension interface for {@link dwtx.jface.text.source.ISourceViewer}.
+ * <p>
+ * It introduces API to access a minimal set of content assistant APIs.</li>
+ * </p>
+ * 
+ * @see IContentAssistant
+ * @since 3.4
+ */
+public interface ISourceViewerExtension4 {
+
+    /**
+     * Returns a facade for this viewer's content assistant.
+     * 
+     * @return a content assistant facade or <code>null</code> if none is
+     *         configured
+     */
+    public ContentAssistantFacade getContentAssistantFacade();
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IVerticalRuler.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IVerticalRuler;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwtx.jface.text.ITextViewer;
+
+
+/**
+ * This interface defines a visual component which may serve text viewers as an
+ * annotation presentation area. Implementers of this interface have to define
+ * the presentation modus. This can either depend on the connected viewer's view
+ * port or not. If the modus is view port dependent the ruler only shows those
+ * annotations that are attached to document regions that are visible in the
+ * view port. If independent, the presented annotations can also be attached to
+ * invisible document regions.
+ *
+ * This interfaces comprises three contracts:
+ * <ul>
+ * <li>The vertical ruler retrieves the annotations it presents from an
+ *     annotation model.
+ * <li>The ruler is a visual component which must be integrated in a hierarchy
+ *     of DWT controls.
+ * <li>The ruler provides interested clients with mapping and interaction
+ *     information. This covers the mapping between coordinates of the ruler's
+ *     control and line numbers based on the connected text viewer's document (see
+ *     {@link dwtx.jface.text.source.IVerticalRulerInfo}).
+ * </ul>
+ * <p>
+ * In order to provide backward compatibility for clients of
+ * <code>IVerticalRuler</code>, extension interfaces are used as a means of
+ * evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.source.IVerticalRulerExtension} since
+ *     version 2.0 introducing setters for font and mouse button activity location.</li>
+ * </ul></p>
+ * <p>
+ * Clients may implement this interface or use the default implementation
+ * provided by {@link dwtx.jface.text.source.CompositeRuler} and
+ * {@link dwtx.jface.text.source.VerticalRuler}.</p>
+ *
+ * @see dwtx.jface.text.source.IVerticalRulerExtension
+ * @see dwtx.jface.text.ITextViewer
+ */
+public interface IVerticalRuler : IVerticalRulerInfo {
+
+    /**
+     * Associates an annotation model with this ruler.
+     * A value <code>null</code> is acceptable and clears the ruler.
+     *
+     * @param model the new annotation model, may be <code>null</code>
+     */
+    void setModel(IAnnotationModel model);
+
+    /**
+     * Returns the current annotation model of this ruler or <code>null</code>
+     * if the ruler has no model.
+     *
+     * @return this ruler's annotation model or <code>null</code> if there is no model
+     */
+    IAnnotationModel getModel();
+
+    /**
+     * Forces the vertical ruler to synchronize itself with its
+     * annotation model and its viewer's view port.
+     */
+    void update();
+
+    /**
+     * Creates the ruler's DWT control.
+     *
+     * @param parent the parent control of the ruler's control
+     * @param textViewer the text viewer to which this ruler belongs
+     * @return the ruler's DWT control
+     */
+    Control createControl(Composite parent, ITextViewer textViewer);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IVerticalRulerColumn.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,141 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IVerticalRulerColumn;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwt.graphics.Font;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+
+
+/**
+ * A vertical ruler column is an element that can be added to a composite
+ * vertical ruler ({@link dwtx.jface.text.source.CompositeRuler}). A
+ * composite vertical ruler is a vertical ruler with  dynamically changing
+ * appearance and behavior depending on its actual arrangement of ruler columns.
+ * A vertical ruler column supports a subset of the contract of a vertical
+ * ruler.
+ *
+ * @see dwtx.jface.text.source.CompositeRuler
+ * @since 2.0
+ */
+public interface IVerticalRulerColumn {
+
+    /**
+     * Associates an annotation model with this ruler column.
+     * A value <code>null</code> is acceptable and clears the ruler.
+     *
+     * @param model the new annotation model, may be <code>null</code>
+     */
+    void setModel(IAnnotationModel model);
+
+    /**
+     * Redraws this column.
+     */
+    void redraw();
+
+    /**
+     * Creates the column's DWT control.
+     *
+     * @param parentRuler the parent ruler of this column
+     * @param parentControl the control of the parent ruler
+     * @return the column's DWT control
+     */
+    Control createControl(CompositeRuler parentRuler, Composite parentControl);
+
+    /**
+     * Returns the column's DWT control.
+     *
+     * @return the column's DWT control
+     */
+    Control getControl();
+
+    /**
+     * Returns the width of this column's control.
+     *
+     * @return the width of this column's control
+     */
+    int getWidth();
+
+    /**
+     * Sets the font of this ruler column.
+     *
+     * @param font the new font of the ruler column
+     */
+    void setFont(Font font);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IVerticalRulerExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,109 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IVerticalRulerExtension;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwt.graphics.Font;
+
+
+/**
+ * Extension interface for {@link IVerticalRuler}.
+ * <p>
+ * Allows to set the font of the vertical ruler and to set the location of the
+ * last mouse button activity.
+ *
+ * @since 2.0
+ */
+public interface IVerticalRulerExtension {
+
+    /**
+     * Sets the font of this vertical ruler.
+     *
+     * @param font the new font of the vertical ruler
+     */
+    void setFont(Font font);
+
+    /**
+     * Sets the location of the last mouse button activity. This method is used for
+     * example by external mouse listeners.
+     *
+     * @param x the x-coordinate
+     * @param y the y-coordinate
+     */
+    void setLocationOfLastMouseButtonActivity(int x, int y);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IVerticalRulerInfo.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.source.IVerticalRulerInfo;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+import dwt.widgets.Control;
+
+
+/**
+ * A vertical ruler is a visual component which may serve text viewers as an
+ * annotation presentation area. The vertical ruler info provides interested
+ * clients with the mapping and interaction aspect of the vertical ruler. This
+ * covers the mapping between coordinates of the ruler's control and line
+ * numbers based on the connected text viewer's document.
+ *
+ * In order to provide backward compatibility for clients of
+ * <code>IVerticalRulerInfo</code>, extension interfaces are used as a means
+ * of evolution. The following extension interfaces exist:
+ * <ul>
+ * <li>{@link dwtx.jface.text.source.IVerticalRulerInfoExtension} since
+ * version 3.0 allowing custom annotation hovers and specific annotation models.
+ * </li>
+ * </ul>
+ *
+ * @see dwtx.jface.text.source.IVerticalRulerInfoExtension
+ * @since 2.0
+ */
+public interface IVerticalRulerInfo {
+
+    /**
+     * Returns the ruler's DWT control.
+     *
+     * @return the ruler's DWT control
+     */
+    Control getControl();
+
+    /**
+     * Returns the line number of the last mouse button activity.
+     * Based on the input document of the connected text viewer.
+     *
+     * @return the line number of the last mouse button activity or <code>-1</code> if 
+     *          the last mouse activity does not correspond to a valid document line
+     */
+    int getLineOfLastMouseButtonActivity();
+
+    /**
+     * Translates a y-coordinate of the ruler's DWT control into
+     * the according line number of the document of the connected text viewer.
+     *
+     * @param y_coordinate a y-coordinate of the ruler's DWT control
+     * @return the line number of that coordinate or <code>-1</code> if that
+     *          coordinate does not correspond to a valid document line
+     */
+    int toDocumentLineNumber(int y_coordinate);
+
+    /**
+     * Returns the width of this ruler's control.
+     *
+     * @return the width of this ruler's control
+     */
+    int getWidth();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IVerticalRulerInfoExtension.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IVerticalRulerInfoExtension;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Extension interface for
+ * {@link dwtx.jface.text.source.IVerticalRulerInfo}.
+ * <p>
+ * Introduces the ability to define a custom hover to be used when hovering over
+ * the vertical ruler described by this info instance, and to specify the
+ * annotation model used by it.
+ * <p>
+ * It also allows client to register as listeners on the represented vertical
+ * ruler and sends out notifications similar to selection events such as that a
+ * particular annotation presented in the vertical ruler has been selected.
+ *
+ * @see dwtx.jface.text.source.IVerticalRuler
+ * @see dwtx.jface.text.source.IAnnotationModel
+ * @since 3.0
+ */
+public interface IVerticalRulerInfoExtension {
+    /**
+     * Returns the hover for this vertical ruler (column).
+     *
+     * @return the hover for this column
+     */
+    IAnnotationHover getHover();
+
+    /**
+     * Returns the model currently used by the receiver.
+     *
+     * @return the model of the receiver, or <code>null</code> if no model is
+     *         installed.
+     */
+    IAnnotationModel getModel();
+
+    /**
+     * Registers a vertical ruler listener to be informed if an annotation gets
+     * selected on the vertical ruler.
+     *
+     * @param listener the listener to be informed
+     */
+    void addVerticalRulerListener(IVerticalRulerListener listener);
+
+    /**
+     * Removes a previously registered listener. If <code>listener</code> is not registered
+     * with the receiver, calling this method has no effect.
+     *
+     * @param listener the listener to be removed
+     */
+    void removeVerticalRulerListener(IVerticalRulerListener listener);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/IVerticalRulerListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,116 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.IVerticalRulerListener;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.widgets.Menu;
+
+
+/**
+ * Interface for listening to annotation related events happening on a vertical ruler.
+ * <p>
+ * This interface may be implemented by clients.
+ * </p>
+ *
+ * @since 3.0
+ */
+public interface IVerticalRulerListener {
+
+    /**
+     * Called when an annotation is selected in the vertical ruler.
+     *
+     * @param event the annotation event that occurred
+     */
+    void annotationSelected(VerticalRulerEvent event);
+
+    /**
+     * Called when a default selection occurs on an
+     * annotation in the vertical ruler.
+     *
+     * @param event the annotation event that occurred
+     */
+    void annotationDefaultSelected(VerticalRulerEvent event);
+
+    /**
+     * Called when the context menu is opened on an annotation in the
+     * vertical ruler.
+     *
+     * @param event the annotation event that occurred
+     * @param menu the menu that is about to be shown
+     */
+    void annotationContextMenuAboutToShow(VerticalRulerEvent event, Menu menu);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/ImageUtilities.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.ImageUtilities;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.DWT;
+import dwt.graphics.FontMetrics;
+import dwt.graphics.GC;
+import dwt.graphics.Image;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Canvas;
+
+/**
+ * Provides methods for drawing images onto a canvas.
+ * <p>
+ * This class is neither intended to be instantiated nor subclassed.
+ * </p>
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ImageUtilities {
+
+    /**
+     * Draws an image aligned inside the given rectangle on the given canvas.
+     *
+     * @param image the image to be drawn
+     * @param gc the drawing GC
+     * @param canvas the canvas on which to draw
+     * @param r the clipping rectangle
+     * @param halign the horizontal alignment of the image to be drawn
+     * @param valign the vertical alignment of the image to be drawn
+     */
+    public static void drawImage(Image image, GC gc, Canvas canvas, Rectangle r, int halign, int valign) {
+        if (image !is null) {
+
+            Rectangle bounds= image.getBounds();
+
+            int x= 0;
+            switch(halign) {
+            case DWT.LEFT:
+                break;
+            case DWT.CENTER:
+                x= (r.width - bounds.width) / 2;
+                break;
+            case DWT.RIGHT:
+                x= r.width - bounds.width;
+                break;
+            }
+
+            int y= 0;
+            switch (valign) {
+            case DWT.TOP: {
+                FontMetrics fontMetrics= gc.getFontMetrics();
+                y= (fontMetrics.getHeight() - bounds.height)/2;
+                break;
+            }
+            case DWT.CENTER:
+                y= (r.height - bounds.height) / 2;
+                break;
+            case DWT.BOTTOM: {
+                FontMetrics fontMetrics= gc.getFontMetrics();
+                y= r.height - (fontMetrics.getHeight() + bounds.height)/2;
+                break;
+            }
+            }
+
+            gc.drawImage(image, r.x+x, r.y+y);
+        }
+    }
+
+    /**
+     * Draws an image aligned inside the given rectangle on the given canvas.
+     *
+     * @param image the image to be drawn
+     * @param gc the drawing GC
+     * @param canvas the canvas on which to draw
+     * @param r the clipping rectangle
+     * @param align the alignment of the image to be drawn
+     */
+    public static void drawImage(Image image, GC gc, Canvas canvas, Rectangle r, int align_) {
+        drawImage(image, gc, canvas, r, align_, DWT.CENTER);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/JFaceTextMessages.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,139 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.source.JFaceTextMessages;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+import dwt.dwthelper.utils;
+
+import dwt.dwthelper.ResourceBundle;
+import dwtx.dwtxhelper.MessageFormat;
+
+/**
+ * Accessor for the <code>JFaceTextMessages.properties</code> file in
+ * package <code>dwtx.jface.text</code>.
+ * @since 2.0
+ */
+class JFaceTextMessages {
+
+    /** The resource bundle name. */
+//     private static const String RESOURCE_BUNDLE= "dwtx.jface.text.JFaceTextMessages";//$NON-NLS-1$
+
+    /** The resource bundle. */
+    private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+    static this() {
+        fgResourceBundle = ResourceBundle.getBundle(
+            getImportData!("dwtx.jface.text.JFaceTextMessages.properties"));
+    }
+
+    /**
+     * Prohibits the creation of accessor objects.
+     */
+    private this() {
+    }
+
+    /**
+     * Returns the string found in the resource bundle under the given key or a place holder string.
+     *
+     * @param key the look up key
+     * @return the value found under the given key
+     */
+    public static String getString(String key) {
+        try {
+            return fgResourceBundle.getString(key);
+        } catch (MissingResourceException e) {
+            return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Gets a string from the resource bundle and formats it with the argument
+     *
+     * @param key   the string used to get the bundle value, must not be null
+     * @param args arguments used when formatting the string
+     * @return the formatted string
+     * @since 3.0
+     */
+    public static String getFormattedString(String key, Object[] args...) {
+        String format= null;
+        try {
+            format= fgResourceBundle.getString(key);
+        } catch (MissingResourceException e) {
+            return "!" ~ key ~ "!";//$NON-NLS-2$ //$NON-NLS-1$
+        }
+        return MessageFormat.format(format, args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/LineChangeHover.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,397 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.LineChangeHover;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+import dwt.graphics.Point;
+import dwt.widgets.Shell;
+import dwtx.jface.action.ToolBarManager;
+import dwtx.jface.text.DefaultInformationControl;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.information.IInformationProviderExtension2;
+
+
+/**
+ * A hover for line oriented diffs. It determines the text to show as hover for a certain line in the
+ * document.
+ *
+ * @since 3.0
+ */
+public class LineChangeHover : IAnnotationHover, IAnnotationHoverExtension, IInformationProviderExtension2 {
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationHover#getHoverInfo(dwtx.jface.text.source.ISourceViewer, int)
+     */
+    public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+        return null;
+    }
+
+    /**
+     * Formats the source w/ syntax coloring etc. This implementation replaces tabs with spaces.
+     * May be overridden by subclasses.
+     *
+     * @param content the hover content
+     * @return <code>content</code> reformatted
+     */
+    protected String formatSource(String content) {
+        if (content !is null) {
+            StringBuffer sb= new StringBuffer(content);
+            final String tabReplacement= getTabReplacement();
+            for (int pos= 0; pos < sb.length(); pos++) {
+                if (sb.slice()[pos] is '\t'){
+                    sb.select( pos, pos + 1);
+                    sb.replace(tabReplacement);
+                }
+            }
+            return sb.toString();
+        }
+        return content;
+    }
+
+    /**
+     * Returns a replacement for the tab character. The default implementation
+     * returns a tabulator character, but subclasses may override to specify a
+     * number of spaces.
+     *
+     * @return a whitespace String that will be substituted for the tabulator
+     *         character
+     */
+    protected String getTabReplacement() {
+        return "\t"; //$NON-NLS-1$
+    }
+
+    /**
+     * Computes the content of the hover for the document contained in <code>viewer</code> on
+     * line <code>line</code>.
+     *
+     * @param viewer the connected viewer
+     * @param first the first line in <code>viewer</code>'s document to consider
+     * @param last the last line in <code>viewer</code>'s document to consider
+     * @param maxLines the max number of lines
+     * @return The hover content corresponding to the parameters
+     * @see #getHoverInfo(ISourceViewer, int)
+     * @see #getHoverInfo(ISourceViewer, ILineRange, int)
+     */
+    private String computeContent(ISourceViewer viewer, int first, int last, int maxLines) {
+        ILineDiffer differ= getDiffer(viewer);
+        if (differ is null)
+            return null;
+
+        final List lines= new LinkedList();
+        for (int l= first; l <= last; l++) {
+            ILineDiffInfo info= differ.getLineInfo(l);
+            if (info !is null)
+                lines.add(cast(Object)info);
+        }
+
+        return decorateText(lines, maxLines);
+    }
+
+    /**
+     * Takes a list of <code>ILineDiffInfo</code>s and computes a hover of at most <code>maxLines</code>.
+     * Added lines are prefixed with a <code>'+'</code>, changed lines with <code>'>'</code> and
+     * deleted lines with <code>'-'</code>.
+     * <p>Deleted and added lines can even each other out, so that a number of deleted lines get
+     * displayed where - in the current document - the added lines are.
+     *
+     * @param diffInfos a <code>List</code> of <code>ILineDiffInfo</code>
+     * @param maxLines the maximum number of lines. Note that adding up all annotations might give
+     * more than that due to deleted lines.
+     * @return a <code>String</code> suitable for hover display
+     */
+    protected String decorateText(List diffInfos, int maxLines) {
+        /* maxLines controls the size of the hover (not more than what fits into the display are of
+         * the viewer).
+         * added controls how many lines are added - added lines are
+         */
+        String text= ""; //$NON-NLS-1$
+        int added= 0;
+        for (Iterator it= diffInfos.iterator(); it.hasNext();) {
+            ILineDiffInfo info= cast(ILineDiffInfo)it.next();
+            String[] original= info.getOriginalText();
+            int type= info.getChangeType();
+            int i= 0;
+            if (type is ILineDiffInfo.ADDED)
+                added++;
+            else if (type is ILineDiffInfo.CHANGED) {
+                text ~= "> " ~ (original.length > 0 ? original[i++] : ""); //$NON-NLS-1$ //$NON-NLS-2$
+                maxLines--;
+            } else if (type is ILineDiffInfo.UNCHANGED) {
+                maxLines++;
+            }
+            if (maxLines is 0)
+                return trimTrailing(text);
+            for (; i < original.length; i++) {
+                text ~= "- " ~ original[i]; //$NON-NLS-1$
+                added--;
+                if (--maxLines is 0)
+                    return trimTrailing(text);
+            }
+        }
+        text= text.trim();
+        if (text.length() is 0 && added-- > 0 && maxLines-- > 0)
+            text ~= "+ "; //$NON-NLS-1$
+        while (added-- > 0 && maxLines-- > 0)
+            text ~= "\n+ "; //$NON-NLS-1$
+        return text;
+    }
+
+    /**
+     * Trims trailing spaces
+     *
+     * @param text a <code>String</code>
+     * @return a copy of <code>text</code> with trailing spaces removed
+     */
+    private String trimTrailing(String text) {
+        int pos= text.length() - 1;
+        while (pos >= 0 && Character.isWhitespace(text.charAt(pos))) {
+            pos--;
+        }
+        return text.substring(0, pos + 1);
+    }
+
+    /**
+     * Extracts the line differ - if any - from the viewer's document's annotation model.
+     * @param viewer the viewer
+     * @return a line differ for the document displayed in viewer, or <code>null</code>.
+     */
+    private ILineDiffer getDiffer(ISourceViewer viewer) {
+        IAnnotationModel model= viewer.getAnnotationModel();
+
+        if (model is null)
+            return null;
+
+        if ( cast(IAnnotationModelExtension)model ) {
+            IAnnotationModel diffModel= (cast(IAnnotationModelExtension)model).getAnnotationModel(cast(Object)IChangeRulerColumn.QUICK_DIFF_MODEL_ID);
+            if (diffModel !is null)
+                model= diffModel;
+        }
+        if ( cast(ILineDiffer)model ) {
+            if (cast(ILineDifferExtension2)model && (cast(ILineDifferExtension2)model).isSuspended())
+                return null;
+            return cast(ILineDiffer)model;
+        }
+        return null;
+    }
+
+    /**
+     * Computes the block of lines which form a contiguous block of changes covering <code>line</code>.
+     *
+     * @param viewer the source viewer showing
+     * @param line the line which a hover is displayed for
+     * @param min the first line in <code>viewer</code>'s document to consider
+     * @param max the last line in <code>viewer</code>'s document to consider
+     * @return the selection in the document displayed in <code>viewer</code> containing <code>line</code>
+     * that is covered by the hover information returned by the receiver.
+     */
+    protected Point computeLineRange(ISourceViewer viewer, int line, int min, int max) {
+        /* Algorithm:
+         * All lines that have changes to themselves (added, changed) are taken that form a
+         * contiguous block of lines that includes <code>line</code>.
+         *
+         * If <code>line</code> is itself unchanged, if there is a deleted line either above or
+         * below, or both, the lines +/- 1 from <code>line</code> are included in the search as well,
+         * without applying this last rule to them, though. (I.e., if <code>line</code> is unchanged,
+         * but has a deleted line above, this one is taken in. If the line above has changes, the block
+         * is extended from there. If the line has no changes itself, the search stops).
+         *
+         * The block never extends the visible line range of the viewer.
+         */
+
+        ILineDiffer differ= getDiffer(viewer);
+        if (differ is null)
+            return new Point(-1, -1);
+
+        // backward search
+
+        int l= line;
+        ILineDiffInfo info= differ.getLineInfo(l);
+        // search backwards until a line has no changes to itself
+        while (l >= min && info !is null && (info.getChangeType() is ILineDiffInfo.CHANGED || info.getChangeType() is ILineDiffInfo.ADDED)) {
+            info= differ.getLineInfo(--l);
+        }
+
+        int first= Math.min(l + 1, line);
+
+        // forward search
+
+        l= line;
+        info= differ.getLineInfo(l);
+        // search forward until a line has no changes to itself
+        while (l <= max && info !is null && (info.getChangeType() is ILineDiffInfo.CHANGED || info.getChangeType() is ILineDiffInfo.ADDED)) {
+            info= differ.getLineInfo(++l);
+        }
+
+        int last= Math.max(l - 1, line);
+
+        return new Point(first, last);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverInfo(dwtx.jface.text.source.ISourceViewer, dwtx.jface.text.source.ILineRange, int)
+     */
+    public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleLines) {
+        int first= adaptFirstLine(sourceViewer, lineRange.getStartLine());
+        int last= adaptLastLine(sourceViewer, lineRange.getStartLine() + lineRange.getNumberOfLines() - 1);
+        String content= computeContent(sourceViewer, first, last, visibleLines);
+        return stringcast(formatSource(content));
+    }
+
+    /**
+     * Adapts the start line to the implementation of <code>ILineDiffInfo</code>.
+     *
+     * @param viewer the source viewer
+     * @param startLine the line to adapt
+     * @return <code>startLine - 1</code> if that line exists and is an
+     *         unchanged line followed by deletions, <code>startLine</code>
+     *         otherwise
+     */
+    private int adaptFirstLine(ISourceViewer viewer, int startLine) {
+        ILineDiffer differ= getDiffer(viewer);
+        if (differ !is null && startLine > 0) {
+            int l= startLine - 1;
+            ILineDiffInfo info= differ.getLineInfo(l);
+            if (info !is null && info.getChangeType() is ILineDiffInfo.UNCHANGED && info.getRemovedLinesBelow() > 0)
+                return l;
+        }
+        return startLine;
+    }
+
+    /**
+     * Adapts the last line to the implementation of <code>ILineDiffInfo</code>.
+     *
+     * @param viewer the source viewer
+     * @param lastLine the line to adapt
+     * @return <code>lastLine - 1</code> if that line exists and is an
+     *         unchanged line followed by deletions, <code>startLine</code>
+     *         otherwise
+     */
+    private int adaptLastLine(ISourceViewer viewer, int lastLine) {
+        ILineDiffer differ= getDiffer(viewer);
+        if (differ !is null && lastLine > 0) {
+            ILineDiffInfo info= differ.getLineInfo(lastLine);
+            if (info !is null && info.getChangeType() is ILineDiffInfo.UNCHANGED)
+                return lastLine - 1;
+        }
+        return lastLine;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverLineRange(dwtx.jface.text.source.ISourceViewer, int)
+     */
+    public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) {
+        IDocument document= viewer.getDocument();
+        if (document !is null) {
+            Point range= computeLineRange(viewer, lineNumber, 0, Math.max(0, document.getNumberOfLines() - 1));
+            if (range.x !is -1 && range.y !is -1)
+                return new LineRange(range.x, range.y - range.x + 1);
+        }
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationHoverExtension#canHandleMouseCursor()
+     */
+    public bool canHandleMouseCursor() {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverControlCreator()
+     */
+    public IInformationControlCreator getHoverControlCreator() {
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator()
+     * @since 3.2
+     */
+    public IInformationControlCreator getInformationPresenterControlCreator() {
+        return new class()  IInformationControlCreator {
+            public IInformationControl createInformationControl(Shell parent) {
+                return new DefaultInformationControl(parent, cast(ToolBarManager)null, null);
+            }
+        };
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/LineNumberChangeRulerColumn.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,456 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.LineNumberChangeRulerColumn;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+
+import dwt.graphics.Color;
+import dwt.graphics.GC;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.internal.text.revisions.RevisionPainter;
+import dwtx.jface.internal.text.source.DiffPainter;
+import dwtx.jface.text.revisions.IRevisionListener;
+import dwtx.jface.text.revisions.IRevisionRulerColumn;
+import dwtx.jface.text.revisions.IRevisionRulerColumnExtension;
+import dwtx.jface.text.revisions.RevisionInformation;
+import dwtx.jface.viewers.ISelectionProvider;
+
+/**
+ * A vertical ruler column displaying line numbers and serving as a UI for quick diff.
+ * Clients usually instantiate and configure object of this class.
+ *
+ * @since 3.0
+ */
+public final class LineNumberChangeRulerColumn : LineNumberRulerColumn , IVerticalRulerInfo, IVerticalRulerInfoExtension, IChangeRulerColumn, IRevisionRulerColumn, IRevisionRulerColumnExtension {
+
+    public Control getControl() {
+        return super.getControl();
+    }
+
+    /** The ruler's annotation model. */
+    private IAnnotationModel fAnnotationModel;
+    /** <code>true</code> if changes should be displayed using character indications instead of background colors. */
+    private bool fCharacterDisplay;
+    /**
+     * The revision painter strategy.
+     *
+     * @since 3.2
+     */
+    private const RevisionPainter fRevisionPainter;
+    /**
+     * The diff information painter strategy.
+     *
+     * @since 3.2
+     */
+    private const DiffPainter fDiffPainter;
+    /**
+     * Whether to show number or to behave like a change ruler column.
+     * @since 3.3
+     */
+    private bool fShowNumbers= true;
+
+    /**
+     * Creates a new instance.
+     *
+     * @param sharedColors the shared colors provider to use
+     */
+    public this(ISharedTextColors sharedColors) {
+        Assert.isNotNull(cast(Object)sharedColors);
+        fRevisionPainter= new RevisionPainter(this, sharedColors);
+        fDiffPainter= new DiffPainter(this, sharedColors);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.LineNumberRulerColumn#createControl(dwtx.jface.text.source.CompositeRuler, dwt.widgets.Composite)
+     */
+    public Control createControl(CompositeRuler parentRuler, Composite parentControl) {
+        Control control= super.createControl(parentRuler, parentControl);
+        fRevisionPainter.setParentRuler(parentRuler);
+        fDiffPainter.setParentRuler(parentRuler);
+        return control;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfo#getLineOfLastMouseButtonActivity()
+     */
+    public int getLineOfLastMouseButtonActivity() {
+        return getParentRuler().getLineOfLastMouseButtonActivity();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfo#toDocumentLineNumber(int)
+     */
+    public int toDocumentLineNumber(int y_coordinate) {
+        return getParentRuler().toDocumentLineNumber(y_coordinate);
+    }
+
+    /*
+     * @see IVerticalRulerColumn#setModel(IAnnotationModel)
+     */
+    public void setModel(IAnnotationModel model) {
+        setAnnotationModel(model);
+        fRevisionPainter.setModel(model);
+        fDiffPainter.setModel(model);
+        updateNumberOfDigits();
+        computeIndentations();
+        layout(true);
+        postRedraw();
+    }
+
+    private void setAnnotationModel(IAnnotationModel model) {
+        if (fAnnotationModel !is model)
+            fAnnotationModel= model;
+    }
+
+
+    /**
+     * Sets the display mode of the ruler. If character mode is set to <code>true</code>, diff
+     * information will be displayed textually on the line number ruler.
+     *
+     * @param characterMode <code>true</code> if diff information is to be displayed textually.
+     */
+    public void setDisplayMode(bool characterMode) {
+        if (characterMode !is fCharacterDisplay) {
+            fCharacterDisplay= characterMode;
+            updateNumberOfDigits();
+            computeIndentations();
+            layout(true);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getModel()
+     */
+    public IAnnotationModel getModel() {
+        return fAnnotationModel;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.LineNumberRulerColumn#createDisplayString(int)
+     */
+    protected String createDisplayString(int line) {
+        StringBuffer buffer= new StringBuffer();
+        if (fShowNumbers)
+            buffer.append(super.createDisplayString(line));
+        if (fCharacterDisplay && getModel() !is null)
+            buffer.append(fDiffPainter.getDisplayCharacter(line));
+        return buffer.toString();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.LineNumberRulerColumn#computeNumberOfDigits()
+     */
+    protected int computeNumberOfDigits() {
+        int digits;
+        if (fCharacterDisplay && getModel() !is null) {
+            if (fShowNumbers)
+                digits= super.computeNumberOfDigits() + 1;
+            else
+                digits= 1;
+        } else {
+            if (fShowNumbers)
+                digits= super.computeNumberOfDigits();
+            else
+                digits= 0;
+        }
+        if (fRevisionPainter.hasInformation())
+            digits+= fRevisionPainter.getRequiredWidth();
+        return digits;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#addVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener)
+     */
+    public void addVerticalRulerListener(IVerticalRulerListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#removeVerticalRulerListener(dwtx.jface.text.source.IVerticalRulerListener)
+     */
+    public void removeVerticalRulerListener(IVerticalRulerListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.LineNumberRulerColumn#doPaint(dwt.graphics.GC)
+     */
+    void doPaint(GC gc, ILineRange visibleLines) {
+        Color foreground= gc.getForeground();
+        if (visibleLines !is null) {
+            if (fRevisionPainter.hasInformation())
+                fRevisionPainter.paint(gc, visibleLines);
+            else if (fDiffPainter.hasInformation()) // don't paint quick diff colors if revisions are painted
+                fDiffPainter.paint(gc, visibleLines);
+        }
+        gc.setForeground(foreground);
+        if (fShowNumbers || fCharacterDisplay)
+            super.doPaint(gc, visibleLines);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfoExtension#getHover()
+     */
+    public IAnnotationHover getHover() {
+        int activeLine= getParentRuler().getLineOfLastMouseButtonActivity();
+        if (fRevisionPainter.hasHover(activeLine))
+            return fRevisionPainter.getHover();
+        if (fDiffPainter.hasHover(activeLine))
+            return fDiffPainter.getHover();
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IChangeRulerColumn#setHover(dwtx.jface.text.source.IAnnotationHover)
+     */
+    public void setHover(IAnnotationHover hover) {
+        fRevisionPainter.setHover(hover);
+        fDiffPainter.setHover(hover);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IChangeRulerColumn#setBackground(dwt.graphics.Color)
+     */
+    public void setBackground(Color background) {
+        super.setBackground(background);
+        fRevisionPainter.setBackground(background);
+        fDiffPainter.setBackground(background);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IChangeRulerColumn#setAddedColor(dwt.graphics.Color)
+     */
+    public void setAddedColor(Color addedColor) {
+        fDiffPainter.setAddedColor(addedColor);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IChangeRulerColumn#setChangedColor(dwt.graphics.Color)
+     */
+    public void setChangedColor(Color changedColor) {
+        fDiffPainter.setChangedColor(changedColor);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IChangeRulerColumn#setDeletedColor(dwt.graphics.Color)
+     */
+    public void setDeletedColor(Color deletedColor) {
+        fDiffPainter.setDeletedColor(deletedColor);
+    }
+
+    /*
+     * @see dwtx.jface.text.revisions.IRevisionRulerColumn#setRevisionInformation(dwtx.jface.text.revisions.RevisionInformation)
+     */
+    public void setRevisionInformation(RevisionInformation info) {
+        fRevisionPainter.setRevisionInformation(info);
+        updateNumberOfDigits();
+        computeIndentations();
+        layout(true);
+        postRedraw();
+    }
+
+    /*
+     * @see dwtx.jface.text.revisions.IRevisionRulerColumnExtension#getRevisionSelectionProvider()
+     * @since 3.2
+     */
+    public ISelectionProvider getRevisionSelectionProvider() {
+        return fRevisionPainter.getRevisionSelectionProvider();
+    }
+
+    /*
+     * @see dwtx.jface.text.revisions.IRevisionRulerColumnExtension#setRenderingMode(dwtx.jface.text.revisions.IRevisionRulerColumnExtension.RenderingMode)
+     * @since 3.3
+     */
+    public void setRevisionRenderingMode(RenderingMode renderingMode) {
+        fRevisionPainter.setRenderingMode(renderingMode);
+    }
+
+    /**
+     * Sets the line number display mode.
+     *
+     * @param showNumbers <code>true</code> to show numbers, <code>false</code> to only show
+     *        diff / revision info.
+     * @since 3.3
+     */
+    public void showLineNumbers(bool showNumbers) {
+        if (fShowNumbers !is showNumbers) {
+            fShowNumbers= showNumbers;
+            updateNumberOfDigits();
+            computeIndentations();
+            layout(true);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.LineNumberRulerColumn#getWidth()
+     * @since 3.3
+     */
+    public int getWidth() {
+        int width= super.getWidth();
+        return width > 0 ? width : 8; // minimal width to display quick diff / revisions if no textual info is shown
+    }
+
+    /**
+     * Returns <code>true</code> if the ruler is showing line numbers, <code>false</code>
+     * otherwise
+     *
+     * @return <code>true</code> if line numbers are shown, <code>false</code> otherwise
+     * @since 3.3
+     */
+    public bool isShowingLineNumbers() {
+        return fShowNumbers;
+    }
+
+    /**
+     * Returns <code>true</code> if the ruler is showing revision information, <code>false</code>
+     * otherwise
+     *
+     * @return <code>true</code> if revision information is shown, <code>false</code> otherwise
+     * @since 3.3
+     */
+    public bool isShowingRevisionInformation() {
+        return fRevisionPainter.hasInformation();
+    }
+
+    /**
+     * Returns <code>true</code> if the ruler is showing change information, <code>false</code>
+     * otherwise
+     *
+     * @return <code>true</code> if change information is shown, <code>false</code> otherwise
+     * @since 3.3
+     */
+    public bool isShowingChangeInformation() {
+        return fDiffPainter.hasInformation();
+    }
+
+    /*
+     * @see dwtx.jface.text.revisions.IRevisionRulerColumnExtension#showRevisionAuthor(bool)
+     * @since 3.3
+     */
+    public void showRevisionAuthor(bool show) {
+        fRevisionPainter.showRevisionAuthor(show);
+        updateNumberOfDigits();
+        computeIndentations();
+        layout(true);
+        postRedraw();
+    }
+
+    /*
+     * @see dwtx.jface.text.revisions.IRevisionRulerColumnExtension#showRevisionId(bool)
+     * @since 3.3
+     */
+    public void showRevisionId(bool show) {
+        fRevisionPainter.showRevisionId(show);
+        updateNumberOfDigits();
+        computeIndentations();
+        layout(true);
+        postRedraw();
+    }
+
+    /*
+     * @see dwtx.jface.text.revisions.IRevisionRulerColumnExtension#addRevisionListener(dwtx.jface.text.revisions.IRevisionListener)
+     * @since 3.3
+     */
+    public void addRevisionListener(IRevisionListener listener) {
+        fRevisionPainter.addRevisionListener(listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.revisions.IRevisionRulerColumnExtension#removeRevisionListener(dwtx.jface.text.revisions.IRevisionListener)
+     * @since 3.3
+     */
+    public void removeRevisionListener(IRevisionListener listener) {
+        fRevisionPainter.removeRevisionListener(listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.LineNumberRulerColumn#handleDispose()
+     * @since 3.3
+     */
+    protected void handleDispose() {
+        fRevisionPainter.setParentRuler(null);
+        fRevisionPainter.setModel(null);
+        fDiffPainter.setParentRuler(null);
+        fDiffPainter.setModel(null);
+        super.handleDispose();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/LineNumberRulerColumn.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,974 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Nikolay Botev <bono8106@hotmail.com> - [rulers] Shift clicking in line number column doesn't select range - https://bugs.eclipse.org/bugs/show_bug.cgi?id=32166
+ *     Nikolay Botev <bono8106@hotmail.com> - [rulers] Clicking in line number ruler should not trigger annotation ruler - https://bugs.eclipse.org/bugs/show_bug.cgi?id=40889
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.LineNumberRulerColumn;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.events.MouseMoveListener;
+import dwt.events.PaintEvent;
+import dwt.events.PaintListener;
+import dwt.graphics.Color;
+import dwt.graphics.Font;
+import dwt.graphics.FontMetrics;
+import dwt.graphics.GC;
+import dwt.graphics.Image;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Canvas;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.TypedListener;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextListener;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.IViewportListener;
+import dwtx.jface.text.JFaceTextUtil;
+import dwtx.jface.text.TextEvent;
+
+
+/**
+ * A vertical ruler column displaying line numbers.
+ * Clients usually instantiate and configure object of this class.
+ *
+ * @since 2.0
+ */
+public class LineNumberRulerColumn : IVerticalRulerColumn {
+
+    /**
+     * Internal listener class.
+     */
+    class InternalListener : IViewportListener, ITextListener {
+
+        /**
+         * @since 3.1
+         */
+        private bool fCachedRedrawState= true;
+
+        /*
+         * @see IViewportListener#viewportChanged(int)
+         */
+        public void viewportChanged(int verticalPosition) {
+            if (fCachedRedrawState && verticalPosition !is fScrollPos)
+                redraw();
+        }
+
+        /*
+         * @see ITextListener#textChanged(TextEvent)
+         */
+        public void textChanged(TextEvent event) {
+
+            fCachedRedrawState= event.getViewerRedrawState();
+            if (!fCachedRedrawState)
+                return;
+
+            if (updateNumberOfDigits()) {
+                computeIndentations();
+                layout(event.getViewerRedrawState());
+                return;
+            }
+
+            bool viewerCompletelyShown= isViewerCompletelyShown();
+            if (viewerCompletelyShown || fSensitiveToTextChanges || event.getDocumentEvent() is null)
+                postRedraw();
+            fSensitiveToTextChanges= viewerCompletelyShown;
+        }
+    }
+
+    /**
+     * Handles all the mouse interaction in this line number ruler column.
+     */
+    class MouseHandler : MouseListener, MouseMoveListener {
+
+        /** The cached view port size. */
+        private int fCachedViewportSize;
+        /** The area of the line at which line selection started. */
+        private int fStartLineOffset;
+        /** The number of the line at which line selection started. */
+        private int fStartLineNumber;
+        /** The auto scroll direction. */
+        private int fAutoScrollDirection;
+        /* @since 3.2 */
+        private bool fIsListeningForMove= false;
+
+        /*
+         * @see dwt.events.MouseListener#mouseUp(dwt.events.MouseEvent)
+         */
+        public void mouseUp(MouseEvent event) {
+            // see bug 45700
+            if (event.button is 1) {
+                stopSelecting();
+                stopAutoScroll();
+            }
+        }
+
+        /*
+         * @see dwt.events.MouseListener#mouseDown(dwt.events.MouseEvent)
+         */
+        public void mouseDown(MouseEvent event) {
+            fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+            // see bug 45700
+            if (event.button is 1) {
+                startSelecting((event.stateMask & DWT.SHIFT) !is 0);
+            }
+        }
+
+        /*
+         * @see dwt.events.MouseListener#mouseDoubleClick(dwt.events.MouseEvent)
+         */
+        public void mouseDoubleClick(MouseEvent event) {
+            fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+            stopSelecting();
+            stopAutoScroll();
+        }
+
+        /*
+         * @see dwt.events.MouseMoveListener#mouseMove(dwt.events.MouseEvent)
+         */
+        public void mouseMove(MouseEvent event) {
+            if (fIsListeningForMove && !autoScroll(event)) {
+                int newLine= fParentRuler.toDocumentLineNumber(event.y);
+                expandSelection(newLine);
+            }
+            fParentRuler.setLocationOfLastMouseButtonActivity(event.x, event.y);
+        }
+
+        /**
+         * Called when line drag selection started. Adds mouse move and track
+         * listeners to this column's control.
+         *
+         * @param expandExistingSelection if <code>true</code> the existing selection will be expanded,
+         *          otherwise a new selection is started
+         */
+        private void startSelecting(bool expandExistingSelection) {
+            try {
+
+                // select line
+                IDocument document= fCachedTextViewer.getDocument();
+                int lineNumber= fParentRuler.getLineOfLastMouseButtonActivity();
+                if (expandExistingSelection && cast(ITextViewerExtension5)fCachedTextViewer
+                        && fCachedTextViewer.getTextWidget() !is null) {
+                    ITextViewerExtension5 extension5= (cast(ITextViewerExtension5)fCachedTextViewer);
+                    // Find model curosr position
+                    int widgetCaret= fCachedTextViewer.getTextWidget().getCaretOffset();
+                    int modelCaret= extension5.widgetOffset2ModelOffset(widgetCaret);
+                    // Find model selection range
+                    Point selection= fCachedTextViewer.getSelectedRange();
+                    // Start from tail of selection range (opposite of cursor position)
+                    int startOffset= modelCaret is selection.x ? selection.x + selection.y : selection.x;
+
+                    fStartLineNumber= document.getLineOfOffset(startOffset);
+                    fStartLineOffset= startOffset;
+
+                    expandSelection(lineNumber);
+                } else {
+                    fStartLineNumber= lineNumber;
+                    fStartLineOffset= document.getLineInformation(fStartLineNumber).getOffset();
+                    fCachedTextViewer.setSelectedRange(fStartLineOffset, 0);
+                }
+                fCachedViewportSize= getVisibleLinesInViewport();
+
+                // prepare for drag selection
+                fIsListeningForMove= true;
+
+            } catch (BadLocationException x) {
+            }
+        }
+
+        /**
+         * Called when line drag selection stopped. Removes all previously
+         * installed listeners from this column's control.
+         */
+        private void stopSelecting() {
+            // drag selection stopped
+            fIsListeningForMove= false;
+        }
+
+        /**
+         * Expands the line selection from the remembered start line to the
+         * given line.
+         *
+         * @param lineNumber the line to which to expand the selection
+         */
+        private void expandSelection(int lineNumber) {
+            try {
+
+                IDocument document= fCachedTextViewer.getDocument();
+                IRegion lineInfo= document.getLineInformation(lineNumber);
+
+                Display display= fCachedTextWidget.getDisplay();
+                Point absolutePosition= display.getCursorLocation();
+                Point relativePosition= fCachedTextWidget.toControl(absolutePosition);
+
+                int offset;
+
+                if (relativePosition.x < 0)
+                    offset= lineInfo.getOffset();
+                else {
+                    try {
+                        int widgetOffset= fCachedTextWidget.getOffsetAtLocation(relativePosition);
+                        Point p= fCachedTextWidget.getLocationAtOffset(widgetOffset);
+                        if (p.x > relativePosition.x)
+                            widgetOffset--;
+
+                        // Convert to model offset
+                        if ( cast(ITextViewerExtension5)fCachedTextViewer ) {
+                            ITextViewerExtension5 extension= cast(ITextViewerExtension5)fCachedTextViewer;
+                            offset= extension.widgetOffset2ModelOffset(widgetOffset);
+                        } else
+                            offset= widgetOffset + fCachedTextViewer.getVisibleRegion().getOffset();
+
+                    } catch (IllegalArgumentException ex) {
+                        int lineEndOffset= lineInfo.getOffset() + lineInfo.getLength();
+
+                        // Convert to widget offset
+                        int lineEndWidgetOffset;
+                        if ( cast(ITextViewerExtension5)fCachedTextViewer ) {
+                            ITextViewerExtension5 extension= cast(ITextViewerExtension5)fCachedTextViewer;
+                            lineEndWidgetOffset= extension.modelOffset2WidgetOffset(lineEndOffset);
+                        } else
+                            lineEndWidgetOffset= lineEndOffset - fCachedTextViewer.getVisibleRegion().getOffset();
+
+                        Point p= fCachedTextWidget.getLocationAtOffset(lineEndWidgetOffset);
+                        if (p.x < relativePosition.x)
+                            offset= lineEndOffset;
+                        else
+                            offset= lineInfo.getOffset();
+                    }
+                }
+
+                int start= Math.min(fStartLineOffset, offset);
+                int end= Math.max(fStartLineOffset, offset);
+
+                if (lineNumber < fStartLineNumber)
+                    fCachedTextViewer.setSelectedRange(end, start - end);
+                else
+                    fCachedTextViewer.setSelectedRange(start, end - start);
+
+            } catch (BadLocationException x) {
+            }
+        }
+
+        /**
+         * Called when auto scrolling stopped. Clears the auto scroll direction.
+         */
+        private void stopAutoScroll() {
+            fAutoScrollDirection= DWT.NULL;
+        }
+
+        /**
+         * Called on drag selection.
+         *
+         * @param event the mouse event caught by the mouse move listener
+         * @return <code>true</code> if scrolling happened, <code>false</code> otherwise
+         */
+        private bool autoScroll(MouseEvent event) {
+            Rectangle area= fCanvas.getClientArea();
+
+            if (event.y > area.height) {
+                autoScroll(DWT.DOWN);
+                return true;
+            }
+
+            if (event.y < 0) {
+                autoScroll(DWT.UP);
+                return true;
+            }
+
+            stopAutoScroll();
+            return false;
+        }
+
+        /**
+         * Scrolls the viewer into the given direction.
+         *
+         * @param direction the scroll direction
+         */
+        private void autoScroll(int direction) {
+
+            if (fAutoScrollDirection is direction)
+                return;
+
+            final int TIMER_INTERVAL= 5;
+            final Display display= fCanvas.getDisplay();
+            Runnable timer= null;
+            switch (direction) {
+                case DWT.UP:
+                    timer= new class()  Runnable {
+                        public void run() {
+                            if (fAutoScrollDirection is DWT.UP) {
+                                int top= getInclusiveTopIndex();
+                                if (top > 0) {
+                                    fCachedTextViewer.setTopIndex(top -1);
+                                    expandSelection(top -1);
+                                    display.timerExec(TIMER_INTERVAL, this);
+                                }
+                            }
+                        }
+                    };
+                    break;
+                case  DWT.DOWN:
+                    timer= new class()  Runnable {
+                        public void run() {
+                            if (fAutoScrollDirection is DWT.DOWN) {
+                                int top= getInclusiveTopIndex();
+                                fCachedTextViewer.setTopIndex(top +1);
+                                expandSelection(top +1 + fCachedViewportSize);
+                                display.timerExec(TIMER_INTERVAL, this);
+                            }
+                        }
+                    };
+                    break;
+            }
+
+            if (timer !is null) {
+                fAutoScrollDirection= direction;
+                display.timerExec(TIMER_INTERVAL, timer);
+            }
+        }
+
+        /**
+         * Returns the viewer's first visible line, even if only partially visible.
+         *
+         * @return the viewer's first visible line
+         */
+        private int getInclusiveTopIndex() {
+            if (fCachedTextWidget !is null && !fCachedTextWidget.isDisposed()) {
+                return JFaceTextUtil.getPartialTopIndex(fCachedTextViewer);
+            }
+            return -1;
+        }
+    }
+
+    /** This column's parent ruler */
+    private CompositeRuler fParentRuler;
+    /** Cached text viewer */
+    private ITextViewer fCachedTextViewer;
+    /** Cached text widget */
+    private StyledText fCachedTextWidget;
+    /** The columns canvas */
+    private Canvas fCanvas;
+    /** Cache for the actual scroll position in pixels */
+    private int fScrollPos;
+    /** The drawable for double buffering */
+    private Image fBuffer;
+    /** The internal listener */
+    private InternalListener fInternalListener;
+    /** The font of this column */
+    private Font fFont;
+    /** The indentation cache */
+    private int[] fIndentation;
+    /** Indicates whether this column reacts on text change events */
+    private bool fSensitiveToTextChanges= false;
+    /** The foreground color */
+    private Color fForeground;
+    /** The background color */
+    private Color fBackground;
+    /** Cached number of displayed digits */
+    private int fCachedNumberOfDigits= -1;
+    /** Flag indicating whether a relayout is required */
+    private bool fRelayoutRequired= false;
+    /**
+     * Redraw runnable lock
+     * @since 3.0
+     */
+    private Object fRunnableLock;
+    /**
+     * Redraw runnable state
+     * @since 3.0
+     */
+    private bool fIsRunnablePosted= false;
+    /**
+     * Redraw runnable
+     * @since 3.0
+     */
+    private Runnable fRunnable;
+    private void fRunnable_init() {
+        fRunnable = new class() Runnable {
+            public void run() {
+                synchronized (fRunnableLock) {
+                    fIsRunnablePosted= false;
+                }
+                redraw();
+            }
+        };
+    }
+    /* @since 3.2 */
+    private MouseHandler fMouseHandler;
+
+
+    /**
+     * Constructs a new vertical ruler column.
+     */
+    public this() {
+        fInternalListener= new InternalListener();
+        fRunnableLock= new Object();
+        fRunnable_init();
+    }
+
+    /**
+     * Sets the foreground color of this column.
+     *
+     * @param foreground the foreground color
+     */
+    public void setForeground(Color foreground) {
+        fForeground= foreground;
+    }
+
+    /**
+     * Returns the foreground color being used to print the line numbers.
+     *
+     * @return the configured foreground color
+     * @since 3.0
+     */
+    protected Color getForeground() {
+        return fForeground;
+    }
+
+    /**
+     * Sets the background color of this column.
+     *
+     * @param background the background color
+     */
+    public void setBackground(Color background) {
+        fBackground= background;
+        if (fCanvas !is null && !fCanvas.isDisposed())
+            fCanvas.setBackground(getBackground(fCanvas.getDisplay()));
+    }
+
+    /**
+     * Returns the System background color for list widgets.
+     *
+     * @param display the display
+     * @return the System background color for list widgets
+     */
+    protected Color getBackground(Display display) {
+        if (fBackground is null)
+            return display.getSystemColor(DWT.COLOR_LIST_BACKGROUND);
+        return fBackground;
+    }
+
+    /*
+     * @see IVerticalRulerColumn#getControl()
+     */
+    public Control getControl() {
+        return fCanvas;
+    }
+
+    /*
+     * @see IVerticalRuleColumnr#getWidth
+     */
+    public int getWidth() {
+        return fIndentation[0];
+    }
+
+    /**
+     * Computes the number of digits to be displayed. Returns
+     * <code>true</code> if the number of digits changed compared
+     * to the previous call of this method. If the method is called
+     * for the first time, the return value is also <code>true</code>.
+     *
+     * @return whether the number of digits has been changed
+     * @since 3.0
+     */
+    protected bool updateNumberOfDigits() {
+        if (fCachedTextViewer is null)
+            return false;
+
+        int digits= computeNumberOfDigits();
+
+        if (fCachedNumberOfDigits !is digits) {
+            fCachedNumberOfDigits= digits;
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Does the real computation of the number of digits. Subclasses may override this method if
+     * they need extra space on the line number ruler.
+     *
+     * @return the number of digits to be displayed on the line number ruler.
+     */
+    protected int computeNumberOfDigits() {
+        IDocument document= fCachedTextViewer.getDocument();
+        int lines= document is null ? 0 : document.getNumberOfLines();
+
+        int digits= 2;
+        while (lines > Math.pow(cast(real)10.0, cast(uint)digits) -1) {
+            ++digits;
+        }
+        return digits;
+    }
+
+    /**
+     * Layouts the enclosing viewer to adapt the layout to changes of the
+     * size of the individual components.
+     *
+     * @param redraw <code>true</code> if this column can be redrawn
+     */
+    protected void layout(bool redraw) {
+        if (!redraw) {
+            fRelayoutRequired= true;
+            return;
+        }
+
+        fRelayoutRequired= false;
+        if ( cast(ITextViewerExtension)fCachedTextViewer ) {
+            ITextViewerExtension extension= cast(ITextViewerExtension) fCachedTextViewer;
+            Control control= extension.getControl();
+            if ( cast(Composite)control  && !control.isDisposed()) {
+                Composite composite= cast(Composite) control;
+                composite.layout(true);
+            }
+        }
+    }
+
+    /**
+     * Computes the indentations for the given font and stores them in
+     * <code>fIndentation</code>.
+     */
+    protected void computeIndentations() {
+        if (fCanvas is null || fCanvas.isDisposed())
+            return;
+
+        GC gc= new GC(fCanvas);
+        try {
+
+            gc.setFont(fCanvas.getFont());
+
+            fIndentation= new int[fCachedNumberOfDigits + 1];
+
+            char[] nines= new char[fCachedNumberOfDigits];
+            Arrays.fill(nines, '9');
+            String nineString= new_String(nines);
+            Point p= gc.stringExtent(nineString);
+            fIndentation[0]= p.x;
+
+            for (int i= 1; i <= fCachedNumberOfDigits; i++) {
+                p= gc.stringExtent(nineString.substring(0, i));
+                fIndentation[i]= fIndentation[0] - p.x;
+            }
+
+        } finally {
+            gc.dispose();
+        }
+    }
+
+    /*
+     * @see IVerticalRulerColumn#createControl(CompositeRuler, Composite)
+     */
+    public Control createControl(CompositeRuler parentRuler, Composite parentControl) {
+
+        fParentRuler= parentRuler;
+        fCachedTextViewer= parentRuler.getTextViewer();
+        fCachedTextWidget= fCachedTextViewer.getTextWidget();
+
+        fCanvas= new class(parentControl, DWT.NO_FOCUS )  Canvas {
+            this(Composite c, int s ){
+                super(c,s);
+            }
+            /*
+             * @see dwt.widgets.Control#addMouseListener(dwt.events.MouseListener)
+             * @since 3.4
+             */
+            public void addMouseListener(MouseListener listener) {
+                // see bug 40889, bug 230073 and AnnotationRulerColumn#isPropagatingMouseListener()
+                if (listener is fMouseHandler)
+                    super.addMouseListener(listener);
+                else {
+                    TypedListener typedListener= null;
+                    if (listener !is null)
+                        typedListener= new TypedListener(listener);
+                    addListener(DWT.MouseDoubleClick, typedListener);
+                }
+            }
+        };
+        fCanvas.setBackground(getBackground(fCanvas.getDisplay()));
+        fCanvas.setForeground(fForeground);
+
+        fCanvas.addPaintListener(new class()  PaintListener {
+            public void paintControl(PaintEvent event) {
+                if (fCachedTextViewer !is null)
+                    doubleBufferPaint(event.gc);
+            }
+        });
+
+        fCanvas.addDisposeListener(new class()  DisposeListener {
+            public void widgetDisposed(DisposeEvent e) {
+                handleDispose();
+                fCachedTextViewer= null;
+                fCachedTextWidget= null;
+            }
+        });
+
+        fMouseHandler= new MouseHandler();
+        fCanvas.addMouseListener(fMouseHandler);
+        fCanvas.addMouseMoveListener(fMouseHandler);
+
+        if (fCachedTextViewer !is null) {
+
+            fCachedTextViewer.addViewportListener(fInternalListener);
+            fCachedTextViewer.addTextListener(fInternalListener);
+
+            if (fFont is null) {
+                if (fCachedTextWidget !is null && !fCachedTextWidget.isDisposed())
+                    fFont= fCachedTextWidget.getFont();
+            }
+        }
+
+        if (fFont !is null)
+            fCanvas.setFont(fFont);
+
+        updateNumberOfDigits();
+        computeIndentations();
+        return fCanvas;
+    }
+
+    /**
+     * Disposes the column's resources.
+     */
+    protected void handleDispose() {
+
+        if (fCachedTextViewer !is null) {
+            fCachedTextViewer.removeViewportListener(fInternalListener);
+            fCachedTextViewer.removeTextListener(fInternalListener);
+        }
+
+        if (fBuffer !is null) {
+            fBuffer.dispose();
+            fBuffer= null;
+        }
+    }
+
+    /**
+     * Double buffer drawing.
+     *
+     * @param dest the GC to draw into
+     */
+    private void doubleBufferPaint(GC dest) {
+
+        Point size= fCanvas.getSize();
+
+        if (size.x <= 0 || size.y <= 0)
+            return;
+
+        if (fBuffer !is null) {
+            Rectangle r= fBuffer.getBounds();
+            if (r.width !is size.x || r.height !is size.y) {
+                fBuffer.dispose();
+                fBuffer= null;
+            }
+        }
+        if (fBuffer is null)
+            fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
+
+        GC gc= new GC(fBuffer);
+        gc.setFont(fCanvas.getFont());
+        if (fForeground !is null)
+            gc.setForeground(fForeground);
+
+        try {
+            gc.setBackground(getBackground(fCanvas.getDisplay()));
+            gc.fillRectangle(0, 0, size.x, size.y);
+
+            ILineRange visibleLines= JFaceTextUtil.getVisibleModelLines(fCachedTextViewer);
+            if (visibleLines is null)
+                return;
+            fScrollPos= fCachedTextWidget.getTopPixel();
+            doPaint(gc, visibleLines);
+        } finally {
+            gc.dispose();
+        }
+
+        dest.drawImage(fBuffer, 0, 0);
+    }
+
+    /**
+     * Returns the view port height in lines.
+     *
+     * @return the view port height in lines
+     * @deprecated as of 3.2 the number of lines in the viewport cannot be computed because
+     *             StyledText supports variable line heights
+     */
+    protected int getVisibleLinesInViewport() {
+        return getVisibleLinesInViewport(fCachedTextWidget);
+    }
+
+
+    /**
+     * Returns <code>true</code> if the viewport displays the entire viewer contents, i.e. the
+     * viewer is not vertically scrollable.
+     *
+     * @return <code>true</code> if the viewport displays the entire contents, <code>false</code> otherwise
+     * @since 3.2
+     */
+    protected final bool isViewerCompletelyShown() {
+        return JFaceTextUtil.isShowingEntireContents(fCachedTextWidget);
+    }
+
+    /**
+     * Draws the ruler column.
+     *
+     * @param gc the GC to draw into
+     * @param visibleLines the visible model lines
+     * @since 3.2
+     */
+    void doPaint(GC gc, ILineRange visibleLines) {
+        Display display= fCachedTextWidget.getDisplay();
+
+        // draw diff info
+        int y= -JFaceTextUtil.getHiddenTopLinePixels(fCachedTextWidget);
+
+        int lastLine= end(visibleLines);
+        for (int line= visibleLines.getStartLine(); line < lastLine; line++) {
+            int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, line);
+            if (widgetLine is -1)
+                continue;
+
+            int lineHeight= fCachedTextWidget.getLineHeight(fCachedTextWidget.getOffsetAtLine(widgetLine));
+            paintLine(line, y, lineHeight, gc, display);
+            y += lineHeight;
+        }
+    }
+
+    /* @since 3.2 */
+    private static int end(ILineRange range) {
+        return range.getStartLine() + range.getNumberOfLines();
+    }
+
+    /**
+     * Computes the string to be printed for <code>line</code>. The default implementation returns
+     * <code>Integer.toString(line + 1)</code>.
+     *
+     * @param line the line number for which the line number string is generated
+     * @return the string to be printed on the line number bar for <code>line</code>
+     * @since 3.0
+     */
+    protected String createDisplayString(int line) {
+        return Integer.toString(line + 1);
+    }
+
+    /**
+     * Returns the difference between the baseline of the widget and the
+     * baseline as specified by the font for <code>gc</code>. When drawing
+     * line numbers, the returned bias should be added to obtain text lined up
+     * on the correct base line of the text widget.
+     *
+     * @param gc the <code>GC</code> to get the font metrics from
+     * @param widgetLine the widget line
+     * @return the baseline bias to use when drawing text that is lined up with
+     *         <code>fCachedTextWidget</code>
+     * @since 3.2
+     */
+    private int getBaselineBias(GC gc, int widgetLine) {
+        /*
+         * https://bugs.eclipse.org/bugs/show_bug.cgi?id=62951
+         * widget line height may be more than the font height used for the
+         * line numbers, since font styles (bold, italics...) can have larger
+         * font metrics than the simple font used for the numbers.
+         */
+        int offset= fCachedTextWidget.getOffsetAtLine(widgetLine);
+        int widgetBaseline= fCachedTextWidget.getBaseline(offset);
+
+        FontMetrics fm= gc.getFontMetrics();
+        int fontBaseline= fm.getAscent() + fm.getLeading();
+        int baselineBias= widgetBaseline - fontBaseline;
+        return Math.max(0, baselineBias);
+    }
+
+    /**
+     * Paints the line. After this method is called the line numbers are painted on top
+     * of the result of this method.
+     *
+     * @param line the line of the document which the ruler is painted for
+     * @param y the y-coordinate of the box being painted for <code>line</code>, relative to <code>gc</code>
+     * @param lineheight the height of one line (and therefore of the box being painted)
+     * @param gc the drawing context the client may choose to draw on.
+     * @param display the display the drawing occurs on
+     * @since 3.0
+     */
+    protected void paintLine(int line, int y, int lineheight, GC gc, Display display) {
+        int widgetLine= JFaceTextUtil.modelLineToWidgetLine(fCachedTextViewer, line);
+
+        String s= createDisplayString(line);
+        int indentation= fIndentation[s.length];
+        int baselineBias= getBaselineBias(gc, widgetLine);
+        gc.drawString(s, indentation, y + baselineBias, true);
+    }
+
+    /**
+     * Triggers a redraw in the display thread.
+     *
+     * @since 3.0
+     */
+    protected final void postRedraw() {
+        if (fCanvas !is null && !fCanvas.isDisposed()) {
+            Display d= fCanvas.getDisplay();
+            if (d !is null) {
+                synchronized (fRunnableLock) {
+                    if (fIsRunnablePosted)
+                        return;
+                    fIsRunnablePosted= true;
+                }
+                d.asyncExec(fRunnable);
+            }
+        }
+    }
+
+    /*
+     * @see IVerticalRulerColumn#redraw()
+     */
+    public void redraw() {
+
+        if (fRelayoutRequired) {
+            layout(true);
+            return;
+        }
+
+        if (fCachedTextViewer !is null && fCanvas !is null && !fCanvas.isDisposed()) {
+            GC gc= new GC(fCanvas);
+            doubleBufferPaint(gc);
+            gc.dispose();
+        }
+    }
+
+    /*
+     * @see IVerticalRulerColumn#setModel(IAnnotationModel)
+     */
+    public void setModel(IAnnotationModel model) {
+    }
+
+    /*
+     * @see IVerticalRulerColumn#setFont(Font)
+     */
+    public void setFont(Font font) {
+        fFont= font;
+        if (fCanvas !is null && !fCanvas.isDisposed()) {
+            fCanvas.setFont(fFont);
+            updateNumberOfDigits();
+            computeIndentations();
+        }
+    }
+
+    /**
+     * Returns the parent (composite) ruler of this ruler column.
+     *
+     * @return the parent ruler
+     * @since 3.0
+     */
+    protected CompositeRuler getParentRuler() {
+        return fParentRuler;
+    }
+
+
+    /**
+     * Returns the number of lines in the view port.
+     *
+     * @param textWidget
+     * @return the number of lines visible in the view port <code>-1</code> if there's no client area
+     * @deprecated this method should not be used - it relies on the widget using a uniform line height
+     */
+    static int getVisibleLinesInViewport(StyledText textWidget) {
+        if (textWidget !is null) {
+            Rectangle clArea= textWidget.getClientArea();
+            if (!clArea.isEmpty()) {
+                int firstPixel= 0;
+                int lastPixel= clArea.height - 1; // XXX what about margins? don't take trims as they include scrollbars
+                int first= JFaceTextUtil.getLineIndex(textWidget, firstPixel);
+                int last= JFaceTextUtil.getLineIndex(textWidget, lastPixel);
+                return last - first;
+            }
+        }
+        return -1;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/LineRange.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.LineRange;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Default implementation of {@link ILineRange}.
+ *
+ * @since 3.0
+ */
+public final class LineRange : ILineRange {
+
+    private int fStartLine;
+    private int fNumberOfLines;
+
+    /**
+     * Creates a new line range with the given specification.
+     *
+     * @param startLine the start line
+     * @param numberOfLines the number of lines
+     */
+    public this(int startLine, int numberOfLines) {
+        fStartLine= startLine;
+        fNumberOfLines= numberOfLines;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ILineRange#getStartLine()
+     */
+    public int getStartLine() {
+        return fStartLine;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ILineRange#getNumberOfLines()
+     */
+    public int getNumberOfLines() {
+        return fNumberOfLines;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/MatchingCharacterPainter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,341 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.MatchingCharacterPainter;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+import dwt.custom.StyledText;
+import dwt.events.PaintEvent;
+import dwt.events.PaintListener;
+import dwt.graphics.Color;
+import dwt.graphics.GC;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IPaintPositionManager;
+import dwtx.jface.text.IPainter;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+
+/**
+ * Highlights the peer character matching the character near the caret position.
+ * This painter can be configured with an
+ * {@link dwtx.jface.text.source.ICharacterPairMatcher}.
+ * <p>
+ * Clients instantiate and configure object of this class.</p>
+ *
+ * @since 2.1
+ */
+public final class MatchingCharacterPainter : IPainter, PaintListener {
+
+    /** Indicates whether this painter is active */
+    private bool fIsActive= false;
+    /** The source viewer this painter is associated with */
+    private ISourceViewer fSourceViewer;
+    /** The viewer's widget */
+    private StyledText fTextWidget;
+    /** The color in which to highlight the peer character */
+    private Color fColor;
+    /** The paint position manager */
+    private IPaintPositionManager fPaintPositionManager;
+    /** The strategy for finding matching characters */
+    private ICharacterPairMatcher fMatcher;
+    /** The position tracking the matching characters */
+    private Position fPairPosition;
+    /** The anchor indicating whether the character is left or right of the caret */
+    private int fAnchor;
+
+
+    /**
+     * Creates a new MatchingCharacterPainter for the given source viewer using
+     * the given character pair matcher. The character matcher is not adopted by
+     * this painter. Thus,  it is not disposed. However, this painter requires
+     * exclusive access to the given pair matcher.
+     *
+     * @param sourceViewer
+     * @param matcher
+     */
+    public this(ISourceViewer sourceViewer, ICharacterPairMatcher matcher) {
+        fPairPosition= new Position(0, 0);
+        fSourceViewer= sourceViewer;
+        fMatcher= matcher;
+        fTextWidget= sourceViewer.getTextWidget();
+    }
+
+    /**
+     * Sets the color in which to highlight the match character.
+     *
+     * @param color the color
+     */
+    public void setColor(Color color) {
+        fColor= color;
+    }
+
+    /*
+     * @see dwtx.jface.text.IPainter#dispose()
+     */
+    public void dispose() {
+        if (fMatcher !is null) {
+            fMatcher.clear();
+            fMatcher= null;
+        }
+
+        fColor= null;
+        fTextWidget= null;
+    }
+
+    /*
+     * @see dwtx.jface.text.IPainter#deactivate(bool)
+     */
+    public void deactivate(bool redraw) {
+        if (fIsActive) {
+            fIsActive= false;
+            fTextWidget.removePaintListener(this);
+            if (fPaintPositionManager !is null)
+                fPaintPositionManager.unmanagePosition(fPairPosition);
+            if (redraw)
+                handleDrawRequest(null);
+        }
+    }
+
+    /*
+     * @see dwt.events.PaintListener#paintControl(dwt.events.PaintEvent)
+     */
+    public void paintControl(PaintEvent event) {
+        if (fTextWidget !is null)
+            handleDrawRequest(event.gc);
+    }
+
+    /**
+     * Handles a redraw request.
+     *
+     * @param gc the GC to draw into.
+     */
+    private void handleDrawRequest(GC gc) {
+
+        if (fPairPosition.isDeleted)
+            return;
+
+        int offset= fPairPosition.getOffset();
+        int length= fPairPosition.getLength();
+        if (length < 1)
+            return;
+
+        if ( cast(ITextViewerExtension5)fSourceViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) fSourceViewer;
+            IRegion widgetRange= extension.modelRange2WidgetRange(new Region(offset, length));
+            if (widgetRange is null)
+                return;
+
+            try {
+                // don't draw if the pair position is really hidden and widgetRange just
+                // marks the coverage around it.
+                IDocument doc= fSourceViewer.getDocument();
+                int startLine= doc.getLineOfOffset(offset);
+                int endLine= doc.getLineOfOffset(offset + length);
+                if (extension.modelLine2WidgetLine(startLine) is -1 || extension.modelLine2WidgetLine(endLine) is -1)
+                    return;
+            } catch (BadLocationException e) {
+                return;
+            }
+
+            offset= widgetRange.getOffset();
+            length= widgetRange.getLength();
+
+        } else {
+            IRegion region= fSourceViewer.getVisibleRegion();
+            if (region.getOffset() > offset || region.getOffset() + region.getLength() < offset + length)
+                return;
+            offset -= region.getOffset();
+        }
+
+        if (ICharacterPairMatcher.RIGHT is fAnchor)
+            draw(gc, offset, 1);
+        else
+            draw(gc, offset + length -1, 1);
+    }
+
+    /**
+     * Highlights the given widget region.
+     *
+     * @param gc the GC to draw into
+     * @param offset the offset of the widget region
+     * @param length the length of the widget region
+     */
+    private void draw(GC gc, int offset, int length) {
+        if (gc !is null) {
+
+            gc.setForeground(fColor);
+
+            Rectangle bounds;
+            if (length > 0)
+                bounds= fTextWidget.getTextBounds(offset, offset + length - 1);
+            else {
+                Point loc= fTextWidget.getLocationAtOffset(offset);
+                bounds= new Rectangle(loc.x, loc.y, 1, fTextWidget.getLineHeight(offset));
+            }
+
+            // draw box around line segment
+            gc.drawRectangle(bounds.x, bounds.y, bounds.width - 1, bounds.height - 1);
+
+            // draw box around character area
+//          int widgetBaseline= fTextWidget.getBaseline();
+//          FontMetrics fm= gc.getFontMetrics();
+//          int fontBaseline= fm.getAscent() + fm.getLeading();
+//          int fontBias= widgetBaseline - fontBaseline;
+
+//          gc.drawRectangle(left.x, left.y + fontBias, right.x - left.x - 1, fm.getHeight() - 1);
+
+        } else {
+            fTextWidget.redrawRange(offset, length, true);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IPainter#paint(int)
+     */
+    public void paint(int reason) {
+
+        IDocument document= fSourceViewer.getDocument();
+        if (document is null) {
+            deactivate(false);
+            return;
+        }
+
+        Point selection= fSourceViewer.getSelectedRange();
+        if (selection.y > 0) {
+            deactivate(true);
+            return;
+        }
+
+        IRegion pair= fMatcher.match(document, selection.x);
+        if (pair is null) {
+            deactivate(true);
+            return;
+        }
+
+        if (fIsActive) {
+
+            if (IPainter.CONFIGURATION is reason) {
+
+                // redraw current highlighting
+                handleDrawRequest(null);
+
+            } else if (pair.getOffset() !is fPairPosition.getOffset() ||
+                    pair.getLength() !is fPairPosition.getLength() ||
+                    fMatcher.getAnchor() !is fAnchor) {
+
+                // otherwise only do something if position is different
+
+                // remove old highlighting
+                handleDrawRequest(null);
+                // update position
+                fPairPosition.isDeleted_= false;
+                fPairPosition.offset= pair.getOffset();
+                fPairPosition.length= pair.getLength();
+                fAnchor= fMatcher.getAnchor();
+                // apply new highlighting
+                handleDrawRequest(null);
+
+            }
+        } else {
+
+            fIsActive= true;
+
+            fPairPosition.isDeleted_= false;
+            fPairPosition.offset= pair.getOffset();
+            fPairPosition.length= pair.getLength();
+            fAnchor= fMatcher.getAnchor();
+
+            fTextWidget.addPaintListener(this);
+            fPaintPositionManager.managePosition(fPairPosition);
+            handleDrawRequest(null);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IPainter#setPositionManager(dwtx.jface.text.IPaintPositionManager)
+     */
+    public void setPositionManager(IPaintPositionManager manager) {
+        fPaintPositionManager= manager;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/OverviewRuler.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1442 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.OverviewRuler;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.MouseAdapter;
+import dwt.events.MouseEvent;
+import dwt.events.MouseMoveListener;
+import dwt.events.MouseTrackAdapter;
+import dwt.events.PaintEvent;
+import dwt.events.PaintListener;
+import dwt.graphics.Color;
+import dwt.graphics.Cursor;
+import dwt.graphics.GC;
+import dwt.graphics.Image;
+import dwt.graphics.Point;
+import dwt.graphics.RGB;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Canvas;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextListener;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.JFaceTextUtil;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextEvent;
+import dwtx.jface.text.source.projection.AnnotationBag;
+
+
+/**
+ * Ruler presented next to a source viewer showing all annotations of the
+ * viewer's annotation model in a compact format. The ruler has the same height
+ * as the source viewer.
+ * <p>
+ * Clients usually instantiate and configure objects of this class.</p>
+ *
+ * @since 2.1
+ */
+public class OverviewRuler : IOverviewRuler {
+
+    /**
+     * Internal listener class.
+     */
+    class InternalListener : ITextListener, IAnnotationModelListener, IAnnotationModelListenerExtension {
+
+        /*
+         * @see ITextListener#textChanged
+         */
+        public void textChanged(TextEvent e) {
+            if (fTextViewer !is null && e.getDocumentEvent() is null && e.getViewerRedrawState()) {
+                // handle only changes of visible document
+                redraw();
+            }
+        }
+
+        /*
+         * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
+         */
+        public void modelChanged(IAnnotationModel model) {
+            update();
+        }
+
+        /*
+         * @see dwtx.jface.text.source.IAnnotationModelListenerExtension#modelChanged(dwtx.jface.text.source.AnnotationModelEvent)
+         * @since 3.3
+         */
+        public void modelChanged(AnnotationModelEvent event) {
+            if (!event.isValid())
+                return;
+
+            if (event.isWorldChange()) {
+                update();
+                return;
+            }
+
+            Annotation[] annotations= event.getAddedAnnotations();
+            int length= annotations.length;
+            for (int i= 0; i < length; i++) {
+                if (!skip(annotations[i].getType())) {
+                    update();
+                    return;
+                }
+            }
+
+            annotations= event.getRemovedAnnotations();
+            length= annotations.length;
+            for (int i= 0; i < length; i++) {
+                if (!skip(annotations[i].getType())) {
+                    update();
+                    return;
+                }
+            }
+
+            annotations= event.getChangedAnnotations();
+            length= annotations.length;
+            for (int i= 0; i < length; i++) {
+                if (!skip(annotations[i].getType())) {
+                    update();
+                    return;
+                }
+            }
+
+        }
+    }
+
+    /**
+     * Enumerates the annotations of a specified type and characteristics
+     * of the associated annotation model.
+     */
+    class FilterIterator : Iterator {
+
+        final static int TEMPORARY= 1 << 1;
+        final static int PERSISTENT= 1 << 2;
+        final static int IGNORE_BAGS= 1 << 3;
+
+        private Iterator fIterator;
+        private Object fType;
+        private Annotation fNext;
+        private int fStyle;
+
+        /**
+         * Creates a new filter iterator with the given specification.
+         *
+         * @param annotationType the annotation type
+         * @param style the style
+         */
+        public this(Object annotationType, int style) {
+            fType= annotationType;
+            fStyle= style;
+            if (fModel !is null) {
+                fIterator= fModel.getAnnotationIterator();
+                skip();
+            }
+        }
+
+        /**
+         * Creates a new filter iterator with the given specification.
+         *
+         * @param annotationType the annotation type
+         * @param style the style
+         * @param iterator the iterator
+         */
+        public this(Object annotationType, int style, Iterator iterator) {
+            fType= annotationType;
+            fStyle= style;
+            fIterator= iterator;
+            skip();
+        }
+
+        private void skip() {
+
+            bool temp= (fStyle & TEMPORARY) !is 0;
+            bool pers= (fStyle & PERSISTENT) !is 0;
+            bool ignr= (fStyle & IGNORE_BAGS) !is 0;
+
+            while (fIterator.hasNext()) {
+                Annotation next= cast(Annotation) fIterator.next();
+
+                if (next.isMarkedDeleted())
+                    continue;
+
+                if (ignr && ( cast(AnnotationBag)next ))
+                    continue;
+
+                fNext= next;
+                Object annotationType= stringcast(next.getType());
+                if (fType is null || fType.opEquals(annotationType) || !fConfiguredAnnotationTypes.contains(annotationType) && isSubtype(annotationType)) {
+                    if (temp && pers) return;
+                    if (pers && next.isPersistent()) return;
+                    if (temp && !next.isPersistent()) return;
+                }
+            }
+            fNext= null;
+        }
+
+        private bool isSubtype(Object annotationType) {
+            if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) {
+                IAnnotationAccessExtension extension= cast(IAnnotationAccessExtension) fAnnotationAccess;
+                return extension.isSubtype(annotationType, fType);
+            }
+            return cast(bool) fType.opEquals(annotationType);
+        }
+
+        /*
+         * @see Iterator#hasNext()
+         */
+        public bool hasNext() {
+            return fNext !is null;
+        }
+        /*
+         * @see Iterator#next()
+         */
+        public Object next() {
+            try {
+                return fNext;
+            } finally {
+                if (fIterator !is null)
+                    skip();
+            }
+        }
+        /*
+         * @see Iterator#remove()
+         */
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    /**
+     * The painter of the overview ruler's header.
+     */
+    class HeaderPainter : PaintListener {
+
+        private Color fIndicatorColor;
+        private Color fSeparatorColor;
+
+        /**
+         * Creates a new header painter.
+         */
+        public this() {
+            fSeparatorColor= fHeader.getDisplay().getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW);
+        }
+
+        /**
+         * Sets the header color.
+         *
+         * @param color the header color
+         */
+        public void setColor(Color color) {
+            fIndicatorColor= color;
+        }
+
+        private void drawBevelRect(GC gc, int x, int y, int w, int h, Color topLeft, Color bottomRight) {
+            gc.setForeground(topLeft is null ? fSeparatorColor : topLeft);
+            gc.drawLine(x, y, x + w -1, y);
+            gc.drawLine(x, y, x, y + h -1);
+
+            gc.setForeground(bottomRight is null ? fSeparatorColor : bottomRight);
+            gc.drawLine(x + w, y, x + w, y + h);
+            gc.drawLine(x, y + h, x + w, y + h);
+        }
+
+        public void paintControl(PaintEvent e) {
+            if (fIndicatorColor is null)
+                return;
+
+            Point s= fHeader.getSize();
+
+            e.gc.setBackground(fIndicatorColor);
+            Rectangle r= new Rectangle(INSET, (s.y - (2*ANNOTATION_HEIGHT)) / 2, s.x - (2*INSET), 2*ANNOTATION_HEIGHT);
+            e.gc.fillRectangle(r);
+            Display d= fHeader.getDisplay();
+            if (d !is null)
+//              drawBevelRect(e.gc, r.x, r.y, r.width -1, r.height -1, d.getSystemColor(DWT.COLOR_WIDGET_NORMAL_SHADOW), d.getSystemColor(DWT.COLOR_WIDGET_HIGHLIGHT_SHADOW));
+                drawBevelRect(e.gc, r.x, r.y, r.width -1, r.height -1, null, null);
+
+            e.gc.setForeground(fSeparatorColor);
+            e.gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance
+            e.gc.drawLine(0, s.y -1, s.x -1, s.y -1);
+        }
+    }
+
+    private static const int INSET= 2;
+    private static const int ANNOTATION_HEIGHT= 4;
+    private static bool ANNOTATION_HEIGHT_SCALABLE= true;
+
+
+    /** The model of the overview ruler */
+    private IAnnotationModel fModel;
+    /** The view to which this ruler is connected */
+    private ITextViewer fTextViewer;
+    /** The ruler's canvas */
+    private Canvas fCanvas;
+    /** The ruler's header */
+    private Canvas fHeader;
+    /** The buffer for double buffering */
+    private Image fBuffer;
+    /** The internal listener */
+    private InternalListener fInternalListener;
+    /** The width of this vertical ruler */
+    private int fWidth;
+    /** The hit detection cursor */
+    private Cursor fHitDetectionCursor;
+    /** The last cursor */
+    private Cursor fLastCursor;
+    /** The line of the last mouse button activity */
+    private int fLastMouseButtonActivityLine= -1;
+    /** The actual annotation height */
+    private int fAnnotationHeight= -1;
+    /** The annotation access */
+    private IAnnotationAccess fAnnotationAccess;
+    /** The header painter */
+    private HeaderPainter fHeaderPainter;
+    /**
+     * The list of annotation types to be shown in this ruler.
+     * @since 3.0
+     */
+    private Set fConfiguredAnnotationTypes;
+    /**
+     * The list of annotation types to be shown in the header of this ruler.
+     * @since 3.0
+     */
+    private Set fConfiguredHeaderAnnotationTypes;
+    /** The mapping between annotation types and colors */
+    private Map fAnnotationTypes2Colors;
+    /** The color manager */
+    private ISharedTextColors fSharedTextColors;
+    /**
+     * All available annotation types sorted by layer.
+     *
+     * @since 3.0
+     */
+    private List fAnnotationsSortedByLayer;
+    /**
+     * All available layers sorted by layer.
+     * This list may contain duplicates.
+     * @since 3.0
+     */
+    private List fLayersSortedByLayer;
+    /**
+     * Map of allowed annotation types.
+     * An allowed annotation type maps to <code>true</code>, a disallowed
+     * to <code>false</code>.
+     * @since 3.0
+     */
+    private Map fAllowedAnnotationTypes;
+    /**
+     * Map of allowed header annotation types.
+     * An allowed annotation type maps to <code>true</code>, a disallowed
+     * to <code>false</code>.
+     * @since 3.0
+     */
+    private Map fAllowedHeaderAnnotationTypes;
+    /**
+     * The cached annotations.
+     * @since 3.0
+     */
+    private List fCachedAnnotations;
+
+    /**
+     * Redraw runnable lock
+     * @since 3.3
+     */
+    private Object fRunnableLock;
+    /**
+     * Redraw runnable state
+     * @since 3.3
+     */
+    private bool fIsRunnablePosted= false;
+    /**
+     * Redraw runnable
+     * @since 3.3
+     */
+    private Runnable fRunnable;
+    /**
+     * Tells whether temporary annotations are drawn with
+     * a separate color. This color will be computed by
+     * discoloring the original annotation color.
+     *
+     * @since 3.4
+     */
+    private bool fIsTemporaryAnnotationDiscolored;
+
+
+    /**
+     * Constructs a overview ruler of the given width using the given annotation access and the given
+     * color manager.
+     * <p><strong>Note:</strong> As of 3.4, temporary annotations are no longer discolored.
+     * Use {@link #OverviewRuler(IAnnotationAccess, int, ISharedTextColors, bool)} if you
+     * want to keep the old behavior.</p>
+     *
+     * @param annotationAccess the annotation access
+     * @param width the width of the vertical ruler
+     * @param sharedColors the color manager
+     */
+    public this(IAnnotationAccess annotationAccess, int width, ISharedTextColors sharedColors) {
+        this(annotationAccess, width, sharedColors, false);
+    }
+
+    /**
+     * Constructs a overview ruler of the given width using the given annotation
+     * access and the given color manager.
+     *
+     * @param annotationAccess the annotation access
+     * @param width the width of the vertical ruler
+     * @param sharedColors the color manager
+     * @param discolorTemporaryAnnotation <code>true</code> if temporary annotations should be discolored
+     * @since 3.4
+     */
+    public this(IAnnotationAccess annotationAccess, int width, ISharedTextColors sharedColors, bool discolorTemporaryAnnotation) {
+        // DWT instance init
+        fInternalListener= new InternalListener();
+        fConfiguredAnnotationTypes= new HashSet();
+        fConfiguredHeaderAnnotationTypes= new HashSet();
+        fAnnotationTypes2Colors= new HashMap();
+        fAnnotationsSortedByLayer= new ArrayList();
+        fLayersSortedByLayer= new ArrayList();
+        fAllowedAnnotationTypes= new HashMap();
+        fAllowedHeaderAnnotationTypes= new HashMap();
+        fCachedAnnotations= new ArrayList();
+        fRunnableLock= new Object();
+        fRunnable= dgRunnable( {
+            synchronized (fRunnableLock) {
+                fIsRunnablePosted= false;
+            }
+            redraw();
+            updateHeader();
+        });
+
+        fAnnotationAccess= annotationAccess;
+        fWidth= width;
+        fSharedTextColors= sharedColors;
+        fIsTemporaryAnnotationDiscolored= discolorTemporaryAnnotation;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfo#getControl()
+     */
+    public Control getControl() {
+        return fCanvas;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerInfo#getWidth()
+     */
+    public int getWidth() {
+        return fWidth;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRuler#setModel(dwtx.jface.text.source.IAnnotationModel)
+     */
+    public void setModel(IAnnotationModel model) {
+        if (model !is fModel || model !is null) {
+
+            if (fModel !is null)
+                fModel.removeAnnotationModelListener(fInternalListener);
+
+            fModel= model;
+
+            if (fModel !is null)
+                fModel.addAnnotationModelListener(fInternalListener);
+
+            update();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRuler#createControl(dwt.widgets.Composite, dwtx.jface.text.ITextViewer)
+     */
+    public Control createControl(Composite parent, ITextViewer textViewer) {
+
+        fTextViewer= textViewer;
+
+        fHitDetectionCursor= new Cursor(parent.getDisplay(), DWT.CURSOR_HAND);
+
+        fHeader= new Canvas(parent, DWT.NONE);
+
+        if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) {
+            fHeader.addMouseTrackListener(new class()  MouseTrackAdapter {
+                /*
+                 * @see dwt.events.MouseTrackAdapter#mouseHover(dwt.events.MouseEvent)
+                 * @since 3.3
+                 */
+                public void mouseEnter(MouseEvent e) {
+                    updateHeaderToolTipText();
+                }
+            });
+        }
+
+        fCanvas= new Canvas(parent, DWT.NO_BACKGROUND);
+
+        fCanvas.addPaintListener(new class()  PaintListener {
+            public void paintControl(PaintEvent event) {
+                if (fTextViewer !is null)
+                    doubleBufferPaint(event.gc);
+            }
+        });
+
+        fCanvas.addDisposeListener(new class()  DisposeListener {
+            public void widgetDisposed(DisposeEvent event) {
+                handleDispose();
+                fTextViewer= null;
+            }
+        });
+
+        fCanvas.addMouseListener(new class()  MouseAdapter {
+            public void mouseDown(MouseEvent event) {
+                handleMouseDown(event);
+            }
+        });
+
+        fCanvas.addMouseMoveListener(new class()  MouseMoveListener {
+            public void mouseMove(MouseEvent event) {
+                handleMouseMove(event);
+            }
+        });
+
+        if (fTextViewer !is null)
+            fTextViewer.addTextListener(fInternalListener);
+
+        return fCanvas;
+    }
+
+    /**
+     * Disposes the ruler's resources.
+     */
+    private void handleDispose() {
+
+        if (fTextViewer !is null) {
+            fTextViewer.removeTextListener(fInternalListener);
+            fTextViewer= null;
+        }
+
+        if (fModel !is null)
+            fModel.removeAnnotationModelListener(fInternalListener);
+
+        if (fBuffer !is null) {
+            fBuffer.dispose();
+            fBuffer= null;
+        }
+
+        if (fHitDetectionCursor !is null) {
+            fHitDetectionCursor.dispose();
+            fHitDetectionCursor= null;
+        }
+
+        fConfiguredAnnotationTypes.clear();
+        fAllowedAnnotationTypes.clear();
+        fConfiguredHeaderAnnotationTypes.clear();
+        fAllowedHeaderAnnotationTypes.clear();
+        fAnnotationTypes2Colors.clear();
+        fAnnotationsSortedByLayer.clear();
+        fLayersSortedByLayer.clear();
+    }
+
+    /**
+     * Double buffer drawing.
+     *
+     * @param dest the GC to draw into
+     */
+    private void doubleBufferPaint(GC dest) {
+
+        Point size= fCanvas.getSize();
+
+        if (size.x <= 0 || size.y <= 0)
+            return;
+
+        if (fBuffer !is null) {
+            Rectangle r= fBuffer.getBounds();
+            if (r.width !is size.x || r.height !is size.y) {
+                fBuffer.dispose();
+                fBuffer= null;
+            }
+        }
+        if (fBuffer is null)
+            fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
+
+        GC gc= new GC(fBuffer);
+        try {
+            gc.setBackground(fCanvas.getBackground());
+            gc.fillRectangle(0, 0, size.x, size.y);
+
+            cacheAnnotations();
+
+            if ( cast(ITextViewerExtension5)fTextViewer )
+                doPaint1(gc);
+            else
+                doPaint(gc);
+
+        } finally {
+            gc.dispose();
+        }
+
+        dest.drawImage(fBuffer, 0, 0);
+    }
+
+    /**
+     * Draws this overview ruler.
+     *
+     * @param gc the GC to draw into
+     */
+    private void doPaint(GC gc) {
+
+        Rectangle r= new Rectangle(0, 0, 0, 0);
+        int yy, hh= ANNOTATION_HEIGHT;
+
+        IDocument document= fTextViewer.getDocument();
+        IRegion visible= fTextViewer.getVisibleRegion();
+
+        StyledText textWidget= fTextViewer.getTextWidget();
+        int maxLines= textWidget.getLineCount();
+
+        Point size= fCanvas.getSize();
+        int writable= JFaceTextUtil.computeLineHeight(textWidget, 0, maxLines, maxLines);
+
+        if (size.y > writable)
+            size.y= Math.max(writable - fHeader.getSize().y, 0);
+
+        for (Iterator iterator= fAnnotationsSortedByLayer.iterator(); iterator.hasNext();) {
+            Object annotationType= iterator.next();
+
+            if (skip(annotationType))
+                continue;
+
+            int[] style= [ FilterIterator.PERSISTENT, FilterIterator.TEMPORARY ];
+            for (int t=0; t < style.length; t++) {
+
+                Iterator e= new FilterIterator(annotationType, style[t], fCachedAnnotations.iterator());
+                Color fill= getFillColor(annotationType, style[t] is FilterIterator.TEMPORARY);
+                Color stroke= getStrokeColor(annotationType, style[t] is FilterIterator.TEMPORARY);
+
+                for (int i= 0; e.hasNext(); i++) {
+
+                    Annotation a= cast(Annotation) e.next();
+                    Position p= fModel.getPosition(a);
+
+                    if (p is null || !p.overlapsWith(visible.getOffset(), visible.getLength()))
+                        continue;
+
+                    int annotationOffset= Math.max(p.getOffset(), visible.getOffset());
+                    int annotationEnd= Math.min(p.getOffset() + p.getLength(), visible.getOffset() + visible.getLength());
+                    int annotationLength= annotationEnd - annotationOffset;
+
+                    try {
+                        if (ANNOTATION_HEIGHT_SCALABLE) {
+                            int numbersOfLines= document.getNumberOfLines(annotationOffset, annotationLength);
+                            // don't count empty trailing lines
+                            IRegion lastLine= document.getLineInformationOfOffset(annotationOffset + annotationLength);
+                            if (lastLine.getOffset() is annotationOffset + annotationLength) {
+                                numbersOfLines -= 2;
+                                hh= (numbersOfLines * size.y) / maxLines + ANNOTATION_HEIGHT;
+                                if (hh < ANNOTATION_HEIGHT)
+                                    hh= ANNOTATION_HEIGHT;
+                            } else
+                                hh= ANNOTATION_HEIGHT;
+                        }
+                        fAnnotationHeight= hh;
+
+                        int startLine= textWidget.getLineAtOffset(annotationOffset - visible.getOffset());
+                        yy= Math.min((startLine * size.y) / maxLines, size.y - hh);
+
+                        if (fill !is null) {
+                            gc.setBackground(fill);
+                            gc.fillRectangle(INSET, yy, size.x-(2*INSET), hh);
+                        }
+
+                        if (stroke !is null) {
+                            gc.setForeground(stroke);
+                            r.x= INSET;
+                            r.y= yy;
+                            r.width= size.x - (2 * INSET);
+                            r.height= hh;
+                            gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance
+                            gc.drawRectangle(r);
+                        }
+                    } catch (BadLocationException x) {
+                    }
+                }
+            }
+        }
+    }
+
+    private void cacheAnnotations() {
+        fCachedAnnotations.clear();
+        if (fModel !is null) {
+            Iterator iter= fModel.getAnnotationIterator();
+            while (iter.hasNext()) {
+                Annotation annotation= cast(Annotation) iter.next();
+
+                if (annotation.isMarkedDeleted())
+                    continue;
+
+                if (skip(annotation.getType()))
+                    continue;
+
+                fCachedAnnotations.add(annotation);
+            }
+        }
+    }
+
+    /**
+     * Draws this overview ruler. Uses <code>ITextViewerExtension5</code> for
+     * its implementation. Will replace <code>doPaint(GC)</code>.
+     *
+     * @param gc the GC to draw into
+     */
+    private void doPaint1(GC gc) {
+
+        Rectangle r= new Rectangle(0, 0, 0, 0);
+        int yy, hh= ANNOTATION_HEIGHT;
+
+        ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer;
+        IDocument document= fTextViewer.getDocument();
+        StyledText textWidget= fTextViewer.getTextWidget();
+
+        int maxLines= textWidget.getLineCount();
+        Point size= fCanvas.getSize();
+        int writable= JFaceTextUtil.computeLineHeight(textWidget, 0, maxLines, maxLines);
+        if (size.y > writable)
+            size.y= Math.max(writable - fHeader.getSize().y, 0);
+
+        for (Iterator iterator= fAnnotationsSortedByLayer.iterator(); iterator.hasNext();) {
+            Object annotationType= iterator.next();
+
+            if (skip(annotationType))
+                continue;
+
+            int[] style= [ FilterIterator.PERSISTENT, FilterIterator.TEMPORARY ];
+            for (int t=0; t < style.length; t++) {
+
+                Iterator e= new FilterIterator(annotationType, style[t], fCachedAnnotations.iterator());
+                Color fill= getFillColor(annotationType, style[t] is FilterIterator.TEMPORARY);
+                Color stroke= getStrokeColor(annotationType, style[t] is FilterIterator.TEMPORARY);
+
+                for (int i= 0; e.hasNext(); i++) {
+
+                    Annotation a= cast(Annotation) e.next();
+                    Position p= fModel.getPosition(a);
+
+                    if (p is null)
+                        continue;
+
+                    IRegion widgetRegion= extension.modelRange2WidgetRange(new Region(p.getOffset(), p.getLength()));
+                    if (widgetRegion is null)
+                        continue;
+
+                    try {
+                        if (ANNOTATION_HEIGHT_SCALABLE) {
+                            int numbersOfLines= document.getNumberOfLines(p.getOffset(), p.getLength());
+                            // don't count empty trailing lines
+                            IRegion lastLine= document.getLineInformationOfOffset(p.getOffset() + p.getLength());
+                            if (lastLine.getOffset() is p.getOffset() + p.getLength()) {
+                                numbersOfLines -= 2;
+                                hh= (numbersOfLines * size.y) / maxLines + ANNOTATION_HEIGHT;
+                                if (hh < ANNOTATION_HEIGHT)
+                                    hh= ANNOTATION_HEIGHT;
+                            } else
+                                hh= ANNOTATION_HEIGHT;
+                        }
+                        fAnnotationHeight= hh;
+
+                        int startLine= textWidget.getLineAtOffset(widgetRegion.getOffset());
+                        yy= Math.min((startLine * size.y) / maxLines, size.y - hh);
+
+                        if (fill !is null) {
+                            gc.setBackground(fill);
+                            gc.fillRectangle(INSET, yy, size.x-(2*INSET), hh);
+                        }
+
+                        if (stroke !is null) {
+                            gc.setForeground(stroke);
+                            r.x= INSET;
+                            r.y= yy;
+                            r.width= size.x - (2 * INSET);
+                            r.height= hh;
+                            gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance
+                            gc.drawRectangle(r);
+                        }
+                    } catch (BadLocationException x) {
+                    }
+                }
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRuler#update()
+     */
+     public void update() {
+        if (fCanvas !is null && !fCanvas.isDisposed()) {
+            Display d= fCanvas.getDisplay();
+            if (d !is null) {
+                synchronized (fRunnableLock) {
+                    if (fIsRunnablePosted)
+                        return;
+                    fIsRunnablePosted= true;
+                }
+                d.asyncExec(fRunnable);
+            }
+        }
+    }
+
+    /**
+     * Redraws the overview ruler.
+     */
+    private void redraw() {
+        if (fTextViewer is null || fModel is null)
+            return;
+
+        if (fCanvas !is null && !fCanvas.isDisposed()) {
+            GC gc= new GC(fCanvas);
+            doubleBufferPaint(gc);
+            gc.dispose();
+        }
+    }
+
+    /**
+     * Translates a given y-coordinate of this ruler into the corresponding
+     * document lines. The number of lines depends on the concrete scaling
+     * given as the ration between the height of this ruler and the length
+     * of the document.
+     *
+     * @param y_coordinate the y-coordinate
+     * @return the corresponding document lines
+     */
+    private int[] toLineNumbers(int y_coordinate) {
+
+        StyledText textWidget=  fTextViewer.getTextWidget();
+        int maxLines= textWidget.getContent().getLineCount();
+
+        int rulerLength= fCanvas.getSize().y;
+        int writable= JFaceTextUtil.computeLineHeight(textWidget, 0, maxLines, maxLines);
+
+        if (rulerLength > writable)
+            rulerLength= Math.max(writable - fHeader.getSize().y, 0);
+
+        if (y_coordinate >= writable || y_coordinate >= rulerLength)
+            return [-1, -1];
+
+        int[] lines= new int[2];
+
+        int pixel0= Math.max(y_coordinate - 1, 0);
+        int pixel1= Math.min(rulerLength, y_coordinate + 1);
+        rulerLength= Math.max(rulerLength, 1);
+
+        lines[0]= (pixel0 * maxLines) / rulerLength;
+        lines[1]= (pixel1 * maxLines) / rulerLength;
+
+        if ( cast(ITextViewerExtension5)fTextViewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer;
+            lines[0]= extension.widgetLine2ModelLine(lines[0]);
+            lines[1]= extension.widgetLine2ModelLine(lines[1]);
+        } else {
+            try {
+                IRegion visible= fTextViewer.getVisibleRegion();
+                int lineNumber= fTextViewer.getDocument().getLineOfOffset(visible.getOffset());
+                lines[0] += lineNumber;
+                lines[1] += lineNumber;
+            } catch (BadLocationException x) {
+            }
+        }
+
+        return lines;
+    }
+
+    /**
+     * Returns the position of the first annotation found in the given line range.
+     *
+     * @param lineNumbers the line range
+     * @return the position of the first found annotation
+     */
+    private Position getAnnotationPosition(int[] lineNumbers) {
+        if (lineNumbers[0] is -1)
+            return null;
+
+        Position found= null;
+
+        try {
+            IDocument d= fTextViewer.getDocument();
+            IRegion line= d.getLineInformation(lineNumbers[0]);
+
+            int start= line.getOffset();
+
+            line= d.getLineInformation(lineNumbers[lineNumbers.length - 1]);
+            int end= line.getOffset() + line.getLength();
+
+            for (int i= fAnnotationsSortedByLayer.size() -1; i >= 0; i--) {
+
+                Object annotationType= fAnnotationsSortedByLayer.get(i);
+
+                Iterator e= new FilterIterator(annotationType, FilterIterator.PERSISTENT | FilterIterator.TEMPORARY);
+                while (e.hasNext() && found is null) {
+                    Annotation a= cast(Annotation) e.next();
+                    if (a.isMarkedDeleted())
+                        continue;
+
+                    if (skip(a.getType()))
+                        continue;
+
+                    Position p= fModel.getPosition(a);
+                    if (p is null)
+                        continue;
+
+                    int posOffset= p.getOffset();
+                    int posEnd= posOffset + p.getLength();
+                    IRegion region= d.getLineInformationOfOffset(posEnd);
+                    // trailing empty lines don't count
+                    if (posEnd > posOffset && region.getOffset() is posEnd) {
+                        posEnd--;
+                        region= d.getLineInformationOfOffset(posEnd);
+                    }
+
+                    if (posOffset <= end && posEnd >= start)
+                            found= p;
+                }
+            }
+        } catch (BadLocationException x) {
+        }
+
+        return found;
+    }
+
+    /**
+     * Returns the line which  corresponds best to one of
+     * the underlying annotations at the given y-coordinate.
+     *
+     * @param lineNumbers the line numbers
+     * @return the best matching line or <code>-1</code> if no such line can be found
+     */
+    private int findBestMatchingLineNumber(int[] lineNumbers) {
+        if (lineNumbers is null || lineNumbers.length < 1)
+            return -1;
+
+        try {
+            Position pos= getAnnotationPosition(lineNumbers);
+            if (pos is null)
+                return -1;
+            return fTextViewer.getDocument().getLineOfOffset(pos.getOffset());
+        } catch (BadLocationException ex) {
+            return -1;
+        }
+    }
+
+    /**
+     * Handles mouse clicks.
+     *
+     * @param event the mouse button down event
+     */
+    private void handleMouseDown(MouseEvent event) {
+        if (fTextViewer !is null) {
+            int[] lines= toLineNumbers(event.y);
+            Position p= getAnnotationPosition(lines);
+            if (p is null && event.button is 1) {
+                try {
+                    p= new Position(fTextViewer.getDocument().getLineInformation(lines[0]).getOffset(), 0);
+                } catch (BadLocationException e) {
+                    // do nothing
+                }
+            }
+            if (p !is null) {
+                fTextViewer.revealRange(p.getOffset(), p.getLength());
+                fTextViewer.setSelectedRange(p.getOffset(), p.getLength());
+            }
+            fTextViewer.getTextWidget().setFocus();
+        }
+        fLastMouseButtonActivityLine= toDocumentLineNumber(event.y);
+    }
+
+    /**
+     * Handles mouse moves.
+     *
+     * @param event the mouse move event
+     */
+    private void handleMouseMove(MouseEvent event) {
+        if (fTextViewer !is null) {
+            int[] lines= toLineNumbers(event.y);
+            Position p= getAnnotationPosition(lines);
+            Cursor cursor= (p !is null ? fHitDetectionCursor : null);
+            if (cursor !is fLastCursor) {
+                fCanvas.setCursor(cursor);
+                fLastCursor= cursor;
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IOverviewRuler#addAnnotationType(java.lang.Object)
+     */
+    public void addAnnotationType(Object annotationType) {
+        fConfiguredAnnotationTypes.add(annotationType);
+        fAllowedAnnotationTypes.clear();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IOverviewRuler#removeAnnotationType(java.lang.Object)
+     */
+    public void removeAnnotationType(Object annotationType) {
+        fConfiguredAnnotationTypes.remove(annotationType);
+        fAllowedAnnotationTypes.clear();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IOverviewRuler#setAnnotationTypeLayer(java.lang.Object, int)
+     */
+    public void setAnnotationTypeLayer(Object annotationType, int layer) {
+        int j= fAnnotationsSortedByLayer.indexOf(annotationType);
+        if (j !is -1) {
+            fAnnotationsSortedByLayer.remove(j);
+            fLayersSortedByLayer.remove(j);
+        }
+
+        if (layer >= 0) {
+            int i= 0;
+            int size= fLayersSortedByLayer.size();
+            while (i < size && layer >= (cast(Integer)fLayersSortedByLayer.get(i)).intValue())
+                i++;
+            Integer layerObj= new Integer(layer);
+            fLayersSortedByLayer.add(i, layerObj);
+            fAnnotationsSortedByLayer.add(i, annotationType);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IOverviewRuler#setAnnotationTypeColor(java.lang.Object, dwt.graphics.Color)
+     */
+    public void setAnnotationTypeColor(Object annotationType, Color color) {
+        if (color !is null)
+            fAnnotationTypes2Colors.put(annotationType, color);
+        else
+            fAnnotationTypes2Colors.remove(annotationType);
+    }
+
+    /**
+     * Returns whether the given annotation type should be skipped by the drawing routine.
+     *
+     * @param annotationType the annotation type
+     * @return <code>true</code> if annotation of the given type should be skipped
+     */
+    private bool skip(Object annotationType) {
+        return !contains(annotationType, fAllowedAnnotationTypes, fConfiguredAnnotationTypes);
+    }
+    private bool skip(String annotationType) {
+        return !contains(stringcast(annotationType), fAllowedAnnotationTypes, fConfiguredAnnotationTypes);
+    }
+
+    /**
+     * Returns whether the given annotation type should be skipped by the drawing routine of the header.
+     *
+     * @param annotationType the annotation type
+     * @return <code>true</code> if annotation of the given type should be skipped
+     * @since 3.0
+     */
+    private bool skipInHeader(Object annotationType) {
+        return !contains(annotationType, fAllowedHeaderAnnotationTypes, fConfiguredHeaderAnnotationTypes);
+    }
+
+    /**
+     * Returns whether the given annotation type is mapped to <code>true</code>
+     * in the given <code>allowed</code> map or covered by the <code>configured</code>
+     * set.
+     *
+     * @param annotationType the annotation type
+     * @param allowed the map with allowed annotation types mapped to booleans
+     * @param configured the set with configured annotation types
+     * @return <code>true</code> if annotation is contained, <code>false</code>
+     *         otherwise
+     * @since 3.0
+     */
+    private bool contains(Object annotationType, Map allowed, Set configured) {
+        Boolean cached= cast(Boolean) allowed.get(annotationType);
+        if (cached !is null)
+            return cached.booleanValue();
+
+        bool covered= isCovered(annotationType, configured);
+        allowed.put(annotationType, covered ? Boolean.TRUE : Boolean.FALSE);
+        return covered;
+    }
+
+    /**
+     * Computes whether the annotations of the given type are covered by the given <code>configured</code>
+     * set. This is the case if either the type of the annotation or any of its
+     * super types is contained in the <code>configured</code> set.
+     *
+     * @param annotationType the annotation type
+     * @param configured the set with configured annotation types
+     * @return <code>true</code> if annotation is covered, <code>false</code>
+     *         otherwise
+     * @since 3.0
+     */
+    private bool isCovered(Object annotationType, Set configured) {
+        if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) {
+            IAnnotationAccessExtension extension= cast(IAnnotationAccessExtension) fAnnotationAccess;
+            Iterator e= configured.iterator();
+            while (e.hasNext()) {
+                if (extension.isSubtype(annotationType,e.next()))
+                    return true;
+            }
+            return false;
+        }
+        return configured.contains(annotationType);
+    }
+
+    /**
+     * Returns a specification of a color that lies between the given
+     * foreground and background color using the given scale factor.
+     *
+     * @param fg the foreground color
+     * @param bg the background color
+     * @param scale the scale factor
+     * @return the interpolated color
+     */
+    private static RGB interpolate(RGB fg, RGB bg, double scale) {
+        return new RGB(
+            cast(int) ((1.0-scale) * fg.red + scale * bg.red),
+            cast(int) ((1.0-scale) * fg.green + scale * bg.green),
+            cast(int) ((1.0-scale) * fg.blue + scale * bg.blue)
+        );
+    }
+
+    /**
+     * Returns the grey value in which the given color would be drawn in grey-scale.
+     *
+     * @param rgb the color
+     * @return the grey-scale value
+     */
+    private static double greyLevel(RGB rgb) {
+        if (rgb.red is rgb.green && rgb.green is rgb.blue)
+            return rgb.red;
+        return  (0.299 * rgb.red + 0.587 * rgb.green + 0.114 * rgb.blue + 0.5);
+    }
+
+    /**
+     * Returns whether the given color is dark or light depending on the colors grey-scale level.
+     *
+     * @param rgb the color
+     * @return <code>true</code> if the color is dark, <code>false</code> if it is light
+     */
+    private static bool isDark(RGB rgb) {
+        return greyLevel(rgb) > 128;
+    }
+
+    /**
+     * Returns a color based on the color configured for the given annotation type and the given scale factor.
+     *
+     * @param annotationType the annotation type
+     * @param scale the scale factor
+     * @return the computed color
+     */
+    private Color getColor(Object annotationType, double scale) {
+        Color base= findColor(annotationType);
+        if (base is null)
+            return null;
+
+        RGB baseRGB= base.getRGB();
+        RGB background= fCanvas.getBackground().getRGB();
+
+        bool darkBase= isDark(baseRGB);
+        bool darkBackground= isDark(background);
+        if (darkBase && darkBackground)
+            background= new RGB(255, 255, 255);
+        else if (!darkBase && !darkBackground)
+            background= new RGB(0, 0, 0);
+
+        return fSharedTextColors.getColor(interpolate(baseRGB, background, scale));
+    }
+
+    /**
+     * Returns the color for the given annotation type
+     *
+     * @param annotationType the annotation type
+     * @return the color
+     * @since 3.0
+     */
+    private Color findColor(Object annotationType) {
+        Color color= cast(Color) fAnnotationTypes2Colors.get(annotationType);
+        if (color !is null)
+            return color;
+
+        if ( cast(IAnnotationAccessExtension)fAnnotationAccess ) {
+            IAnnotationAccessExtension extension= cast(IAnnotationAccessExtension) fAnnotationAccess;
+            Object[] superTypes= extension.getSupertypes(annotationType);
+            if (superTypes !is null) {
+                for (int i= 0; i < superTypes.length; i++) {
+                    color= cast(Color) fAnnotationTypes2Colors.get(superTypes[i]);
+                    if (color !is null)
+                        return color;
+                }
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the stroke color for the given annotation type and characteristics.
+     *
+     * @param annotationType the annotation type
+     * @param temporary <code>true</code> if for temporary annotations
+     * @return the stroke color
+     */
+    private Color getStrokeColor(Object annotationType, bool temporary) {
+        return getColor(annotationType, temporary && fIsTemporaryAnnotationDiscolored ? 0.5 : 0.2);
+    }
+
+    /**
+     * Returns the fill color for the given annotation type and characteristics.
+     *
+     * @param annotationType the annotation type
+     * @param temporary <code>true</code> if for temporary annotations
+     * @return the fill color
+     */
+    private Color getFillColor(Object annotationType, bool temporary) {
+        return getColor(annotationType, temporary && fIsTemporaryAnnotationDiscolored ? 0.9 : 0.75);
+    }
+
+    /*
+     * @see IVerticalRulerInfo#getLineOfLastMouseButtonActivity()
+     */
+    public int getLineOfLastMouseButtonActivity() {
+        if (fLastMouseButtonActivityLine >= fTextViewer.getDocument().getNumberOfLines())
+            fLastMouseButtonActivityLine= -1;
+        return fLastMouseButtonActivityLine;
+    }
+
+    /*
+     * @see IVerticalRulerInfo#toDocumentLineNumber(int)
+     */
+    public int toDocumentLineNumber(int y_coordinate) {
+
+        if (fTextViewer is null || y_coordinate is -1)
+            return -1;
+
+        int[] lineNumbers= toLineNumbers(y_coordinate);
+        int bestLine= findBestMatchingLineNumber(lineNumbers);
+        if (bestLine is -1 && lineNumbers.length > 0)
+            return lineNumbers[0];
+        return  bestLine;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRuler#getModel()
+     */
+    public IAnnotationModel getModel() {
+        return fModel;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IOverviewRuler#getAnnotationHeight()
+     */
+    public int getAnnotationHeight() {
+        return fAnnotationHeight;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IOverviewRuler#hasAnnotation(int)
+     */
+    public bool hasAnnotation(int y) {
+        return findBestMatchingLineNumber(toLineNumbers(y)) !is -1;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IOverviewRuler#getHeaderControl()
+     */
+    public Control getHeaderControl() {
+        return fHeader;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IOverviewRuler#addHeaderAnnotationType(java.lang.Object)
+     */
+    public void addHeaderAnnotationType(Object annotationType) {
+        fConfiguredHeaderAnnotationTypes.add(annotationType);
+        fAllowedHeaderAnnotationTypes.clear();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IOverviewRuler#removeHeaderAnnotationType(java.lang.Object)
+     */
+    public void removeHeaderAnnotationType(Object annotationType) {
+        fConfiguredHeaderAnnotationTypes.remove(annotationType);
+        fAllowedHeaderAnnotationTypes.clear();
+    }
+
+    /**
+     * Updates the header of this ruler.
+     */
+    private void updateHeader() {
+        if (fHeader is null || fHeader.isDisposed())
+            return;
+
+        fHeader.setToolTipText(null);
+
+        Object colorType= null;
+        outer: for (int i= fAnnotationsSortedByLayer.size() -1; i >= 0; i--) {
+            Object annotationType= fAnnotationsSortedByLayer.get(i);
+            if (skipInHeader(annotationType) || skip(annotationType))
+                continue;
+
+            Iterator e= new FilterIterator(annotationType, FilterIterator.PERSISTENT | FilterIterator.TEMPORARY | FilterIterator.IGNORE_BAGS, fCachedAnnotations.iterator());
+            while (e.hasNext()) {
+                if (e.next() !is null) {
+                    colorType= annotationType;
+                    break outer;
+                }
+            }
+        }
+
+        Color color= null;
+        if (colorType !is null)
+            color= findColor(colorType);
+
+        if (color is null) {
+            if (fHeaderPainter !is null)
+                fHeaderPainter.setColor(null);
+        }   else {
+            if (fHeaderPainter is null) {
+                fHeaderPainter= new HeaderPainter();
+                fHeader.addPaintListener(fHeaderPainter);
+            }
+            fHeaderPainter.setColor(color);
+        }
+
+        fHeader.redraw();
+
+    }
+
+    /**
+     * Updates the header tool tip text of this ruler.
+     */
+    private void updateHeaderToolTipText() {
+        if (fHeader is null || fHeader.isDisposed())
+            return;
+
+        if (fHeader.getToolTipText() !is null)
+            return;
+
+        String overview= ""; //$NON-NLS-1$
+
+        for (int i= fAnnotationsSortedByLayer.size() -1; i >= 0; i--) {
+
+            Object annotationType= fAnnotationsSortedByLayer.get(i);
+
+            if (skipInHeader(annotationType) || skip(annotationType))
+                continue;
+
+            int count= 0;
+            String annotationTypeLabel= null;
+
+            Iterator e= new FilterIterator(annotationType, FilterIterator.PERSISTENT | FilterIterator.TEMPORARY | FilterIterator.IGNORE_BAGS, fCachedAnnotations.iterator());
+            while (e.hasNext()) {
+                Annotation annotation= cast(Annotation)e.next();
+                if (annotation !is null) {
+                    if (annotationTypeLabel is null)
+                        annotationTypeLabel= (cast(IAnnotationAccessExtension)fAnnotationAccess).getTypeLabel(annotation);
+                    count++;
+                }
+            }
+
+            if (annotationTypeLabel !is null) {
+                if (overview.length() > 0)
+                    overview ~= "\n"; //$NON-NLS-1$
+                overview ~= JFaceTextMessages.getFormattedString("OverviewRulerHeader.toolTipTextEntry", stringcast(annotationTypeLabel), new Integer(count) ); //$NON-NLS-1$
+            }
+        }
+
+        if (overview.length() > 0)
+            fHeader.setToolTipText(overview);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/OverviewRulerHoverManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,157 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.OverviewRulerHoverManager;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+import dwt.custom.StyledText;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.ScrollBar;
+import dwtx.jface.text.IInformationControlCreator;
+
+/**
+ * This manager controls the layout, content, and visibility of an information
+ * control in reaction to mouse hover events issued by the overview ruler of a
+ * source viewer.
+ *
+ * @since 2.1
+ */
+class OverviewRulerHoverManager : AnnotationBarHoverManager {
+
+    /**
+     * Creates an overview hover manager with the given parameters. In addition,
+     * the hovers anchor is RIGHT and the margin is 5 points to the right.
+     *
+     * @param ruler the overview ruler this manager connects to
+     * @param sourceViewer the source viewer this manager connects to
+     * @param annotationHover the annotation hover providing the information to be displayed
+     * @param creator the information control creator
+     */
+    public this(IOverviewRuler ruler, ISourceViewer sourceViewer, IAnnotationHover annotationHover, IInformationControlCreator creator) {
+        super(ruler, sourceViewer, annotationHover, creator);
+        setAnchor(ANCHOR_LEFT);
+        StyledText textWidget= sourceViewer.getTextWidget();
+        if (textWidget !is null) {
+            ScrollBar verticalBar= textWidget.getVerticalBar();
+            if (verticalBar !is null)
+                setMargins(verticalBar.getSize().x, 5);
+        }
+    }
+
+    /*
+     * @see AbstractHoverInformationControlManager#computeInformation()
+     */
+    protected void computeInformation() {
+        Point location= getHoverEventLocation();
+        int line= getVerticalRulerInfo().toDocumentLineNumber(location.y);
+        IAnnotationHover hover= getAnnotationHover();
+        
+        IInformationControlCreator controlCreator= null;
+        if ( cast(IAnnotationHoverExtension)hover )
+            controlCreator= (cast(IAnnotationHoverExtension)hover).getHoverControlCreator();
+        setCustomInformationControlCreator(controlCreator);
+        
+        setInformation(hover.getHoverInfo(getSourceViewer(), line), computeArea(location.y));
+    }
+
+    /**
+     * Determines graphical area covered for which the hover is valid.
+     *
+     * @param y y-coordinate in the vertical ruler
+     * @return the graphical extend where the hover is valid
+     */
+    private Rectangle computeArea(int y) {
+        // This is OK (see constructor)
+        IOverviewRuler overviewRuler= cast(IOverviewRuler) getVerticalRulerInfo();
+
+        int hover_height= overviewRuler.getAnnotationHeight();
+        int hover_width= getVerticalRulerInfo().getControl().getSize().x;
+
+        // Calculate y-coordinate for hover
+        int hover_y= y;
+        bool hasAnnotation= true;
+        while (hasAnnotation && hover_y > y - hover_height) {
+            hover_y--;
+            hasAnnotation= overviewRuler.hasAnnotation(hover_y);
+        }
+        hover_y++;
+
+        return new Rectangle(0, hover_y, hover_width, hover_height);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/SourceViewer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1161 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.SourceViewer;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwt.DWT;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Canvas;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Layout;
+import dwtx.jface.internal.text.NonDeletingPositionUpdater;
+import dwtx.jface.internal.text.StickyHoverManager;
+import dwtx.jface.text.AbstractHoverInformationControlManager;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DocumentRewriteSession;
+import dwtx.jface.text.DocumentRewriteSessionType;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentExtension4;
+import dwtx.jface.text.IPositionUpdater;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.IRewriteTarget;
+import dwtx.jface.text.ISlaveDocumentManager;
+import dwtx.jface.text.ISlaveDocumentManagerExtension;
+import dwtx.jface.text.ITextViewerExtension2;
+import dwtx.jface.text.ITextViewerExtension8;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextViewer;
+import dwtx.jface.text.contentassist.IContentAssistant;
+import dwtx.jface.text.contentassist.IContentAssistantExtension4;
+import dwtx.jface.text.formatter.FormattingContext;
+import dwtx.jface.text.formatter.FormattingContextProperties;
+import dwtx.jface.text.formatter.IContentFormatter;
+import dwtx.jface.text.formatter.IContentFormatterExtension;
+import dwtx.jface.text.formatter.IFormattingContext;
+import dwtx.jface.text.hyperlink.IHyperlinkDetector;
+import dwtx.jface.text.information.IInformationPresenter;
+import dwtx.jface.text.presentation.IPresentationReconciler;
+import dwtx.jface.text.projection.ChildDocument;
+import dwtx.jface.text.quickassist.IQuickAssistAssistant;
+import dwtx.jface.text.quickassist.IQuickAssistInvocationContext;
+import dwtx.jface.text.reconciler.IReconciler;
+
+/**
+ * DWT based implementation of
+ * {@link dwtx.jface.text.source.ISourceViewer} and its extension
+ * interfaces. The same rules apply as for
+ * {@link dwtx.jface.text.TextViewer}. A source viewer uses an
+ * <code>IVerticalRuler</code> as its annotation presentation area. The
+ * vertical ruler is a small strip shown left of the viewer's text widget. A
+ * source viewer uses an <code>IOverviewRuler</code> as its presentation area
+ * for the annotation overview. The overview ruler is a small strip shown right
+ * of the viewer's text widget.
+ * <p>
+ * Clients are supposed to instantiate a source viewer and subsequently to
+ * communicate with it exclusively using the <code>ISourceViewer</code> and
+ * its extension interfaces.</p>
+ * <p>
+ * Clients may subclass this class but should expect some breakage by future releases.</p>
+ */
+public class SourceViewer : TextViewer , ISourceViewer, ISourceViewerExtension, ISourceViewerExtension2, ISourceViewerExtension3, ISourceViewerExtension4 {
+
+
+    /**
+     * Layout of a source viewer. Vertical ruler, text widget, and overview ruler are shown side by side.
+     */
+    protected class RulerLayout : Layout {
+
+        /** The gap between the text viewer and the vertical ruler. */
+        protected int fGap;
+
+        /**
+         * Creates a new ruler layout with the given gap between text viewer and vertical ruler.
+         *
+         * @param gap the gap between text viewer and vertical ruler
+         */
+        public this(int gap) {
+            fGap= gap;
+        }
+
+        /*
+         * @see Layout#computeSize(Composite, int, int, bool)
+         */
+        protected Point computeSize(Composite composite, int wHint, int hHint, bool flushCache) {
+            Control[] children= composite.getChildren();
+            Point s= children[children.length - 1].computeSize(DWT.DEFAULT, DWT.DEFAULT, flushCache);
+            if (fVerticalRuler !is null && fIsVerticalRulerVisible)
+                s.x += fVerticalRuler.getWidth() + fGap;
+            return s;
+        }
+
+        /*
+         * @see Layout#layout(Composite, bool)
+         */
+        protected void layout(Composite composite, bool flushCache) {
+            Rectangle clArea= composite.getClientArea();
+            Rectangle trim= getTextWidget().computeTrim(0, 0, 0, 0);
+            int topTrim= - trim.y;
+            int scrollbarHeight= trim.height - topTrim; // scrollbar is only under the client area
+
+            int x= clArea.x;
+            int width= clArea.width;
+
+            if (fOverviewRuler !is null && fIsOverviewRulerVisible) {
+                int overviewRulerWidth= fOverviewRuler.getWidth();
+                fOverviewRuler.getControl().setBounds(clArea.x + clArea.width - overviewRulerWidth - 1, clArea.y + scrollbarHeight, overviewRulerWidth, clArea.height - 3*scrollbarHeight);
+                fOverviewRuler.getHeaderControl().setBounds(clArea.x + clArea.width - overviewRulerWidth - 1, clArea.y, overviewRulerWidth, scrollbarHeight);
+
+                width -= overviewRulerWidth + fGap;
+            }
+
+            if (fVerticalRuler !is null && fIsVerticalRulerVisible) {
+                int verticalRulerWidth= fVerticalRuler.getWidth();
+                final Control verticalRulerControl= fVerticalRuler.getControl();
+                int oldWidth= verticalRulerControl.getBounds().width;
+                verticalRulerControl.setBounds(clArea.x, clArea.y + topTrim, verticalRulerWidth, clArea.height - scrollbarHeight - topTrim);
+                if (flushCache && getVisualAnnotationModel() !is null && oldWidth is verticalRulerWidth)
+                    verticalRulerControl.redraw();
+
+                x += verticalRulerWidth + fGap;
+                width -= verticalRulerWidth + fGap;
+            }
+
+            getTextWidget().setBounds(x, clArea.y, width, clArea.height);
+        }
+    }
+
+    /**
+     * The size of the gap between the vertical ruler and the text widget
+     * (value <code>2</code>).
+     * <p>
+     * Note: As of 3.2, the text editor framework is no longer using 2 as
+     * gap but 1, see {{@link #GAP_SIZE_1 }.
+     * </p>
+     */
+    protected final static int GAP_SIZE= 2;
+    /**
+     * The size of the gap between the vertical ruler and the text widget
+     * (value <code>1</code>).
+     * @since 3.2
+     */
+    protected final static int GAP_SIZE_1= 1;
+    /**
+     * Partial name of the position category to manage remembered selections.
+     * @since 3.0
+     */
+    protected final static String _SELECTION_POSITION_CATEGORY= "__selection_category"; //$NON-NLS-1$
+    /**
+     * Key of the model annotation model inside the visual annotation model.
+     * @since 3.0
+     */
+    private static Object MODEL_ANNOTATION_MODEL_;
+    protected static Object MODEL_ANNOTATION_MODEL(){
+        if( MODEL_ANNOTATION_MODEL_ is null ){
+            synchronized(SourceViewer.classinfo ){
+                if( MODEL_ANNOTATION_MODEL_ is null ){
+                    MODEL_ANNOTATION_MODEL_ = new Object();
+                }
+            }
+        }
+        return MODEL_ANNOTATION_MODEL_;
+    }
+
+    /** The viewer's content assistant */
+    protected IContentAssistant fContentAssistant;
+    /**
+     * The viewer's facade to its content assistant.
+     * @since 3.4
+     */
+    private ContentAssistantFacade fContentAssistantFacade;
+    /**
+     * Flag indicating whether the viewer's content assistant is installed.
+     * @since 2.0
+     */
+    protected bool fContentAssistantInstalled;
+    /**
+     * This viewer's quick assist assistant.
+     * @since 3.2
+     */
+    protected IQuickAssistAssistant fQuickAssistAssistant;
+    /**
+     * Flag indicating whether this viewer's quick assist assistant is installed.
+     * @since 3.2
+     */
+    protected bool fQuickAssistAssistantInstalled;
+    /** The viewer's content formatter */
+    protected IContentFormatter fContentFormatter;
+    /** The viewer's model reconciler */
+    protected IReconciler fReconciler;
+    /** The viewer's presentation reconciler */
+    protected IPresentationReconciler fPresentationReconciler;
+    /** The viewer's annotation hover */
+    protected IAnnotationHover fAnnotationHover;
+    /**
+     * Stack of saved selections in the underlying document
+     * @since 3.0
+     */
+    protected const Stack fSelections;
+    /**
+     * Position updater for saved selections
+     * @since 3.0
+     */
+    protected IPositionUpdater fSelectionUpdater= null;
+    /**
+     * Position category used by the selection updater
+     * @since 3.0
+     */
+    protected String fSelectionCategory;
+    /**
+     * The viewer's overview ruler annotation hover
+     * @since 3.0
+     */
+    protected IAnnotationHover fOverviewRulerAnnotationHover;
+    /**
+     * The viewer's information presenter
+     * @since 2.0
+     */
+    protected IInformationPresenter fInformationPresenter;
+
+    /** Visual vertical ruler */
+    private IVerticalRuler fVerticalRuler;
+    /** Visibility of vertical ruler */
+    private bool fIsVerticalRulerVisible;
+    /** The DWT widget used when supporting a vertical ruler */
+    private Composite fComposite;
+    /** The vertical ruler's annotation model */
+    private IAnnotationModel fVisualAnnotationModel;
+    /** The viewer's range indicator to be shown in the vertical ruler */
+    private Annotation fRangeIndicator;
+    /** The viewer's vertical ruler hovering controller */
+    private AnnotationBarHoverManager fVerticalRulerHoveringController;
+    /**
+     * The viewer's overview ruler hovering controller
+     * @since 2.1
+     */
+    private AbstractHoverInformationControlManager fOverviewRulerHoveringController;
+
+    /**
+     * The overview ruler.
+     * @since 2.1
+     */
+    private IOverviewRuler fOverviewRuler;
+    /**
+     * The visibility of the overview ruler
+     * @since 2.1
+     */
+    private bool fIsOverviewRulerVisible;
+
+
+    /**
+     * Constructs a new source viewer. The vertical ruler is initially visible.
+     * The viewer has not yet been initialized with a source viewer configuration.
+     *
+     * @param parent the parent of the viewer's control
+     * @param ruler the vertical ruler used by this source viewer
+     * @param styles the DWT style bits for the viewer's control,
+     *          <em>if <code>DWT.WRAP</code> is set then a custom document adapter needs to be provided, see {@link #createDocumentAdapter()}
+     */
+    public this(Composite parent, IVerticalRuler ruler, int styles) {
+        this(parent, ruler, null, false, styles);
+    }
+
+    /**
+     * Constructs a new source viewer. The vertical ruler is initially visible.
+     * The overview ruler visibility is controlled by the value of <code>showAnnotationsOverview</code>.
+     * The viewer has not yet been initialized with a source viewer configuration.
+     *
+     * @param parent the parent of the viewer's control
+     * @param verticalRuler the vertical ruler used by this source viewer
+     * @param overviewRuler the overview ruler
+     * @param showAnnotationsOverview <code>true</code> if the overview ruler should be visible, <code>false</code> otherwise
+     * @param styles the DWT style bits for the viewer's control,
+     *          <em>if <code>DWT.WRAP</code> is set then a custom document adapter needs to be provided, see {@link #createDocumentAdapter()}
+     * @since 2.1
+     */
+    public this(Composite parent, IVerticalRuler verticalRuler, IOverviewRuler overviewRuler, bool showAnnotationsOverview, int styles) {
+        fSelections= new Stack();
+        super();
+
+        fVerticalRuler= verticalRuler;
+        fIsVerticalRulerVisible= (verticalRuler !is null);
+        fOverviewRuler= overviewRuler;
+        fIsOverviewRulerVisible= (showAnnotationsOverview && overviewRuler !is null);
+
+        createControl(parent, styles);
+    }
+
+    /*
+     * @see TextViewer#createControl(Composite, int)
+     */
+    protected void createControl(Composite parent, int styles) {
+
+        if (fVerticalRuler !is null || fOverviewRuler !is null) {
+            styles= (styles & ~DWT.BORDER);
+            fComposite= new Canvas(parent, DWT.NONE);
+            fComposite.setLayout(createLayout());
+            parent= fComposite;
+        }
+
+        super.createControl(parent, styles);
+
+        if (fVerticalRuler !is null)
+            fVerticalRuler.createControl(fComposite, this);
+        if (fOverviewRuler !is null)
+            fOverviewRuler.createControl(fComposite, this);
+    }
+
+    /**
+     * Creates the layout used for this viewer.
+     * Subclasses may override this method.
+     *
+     * @return the layout used for this viewer
+     * @since 3.0
+     */
+    protected Layout createLayout() {
+        return new RulerLayout(GAP_SIZE_1);
+    }
+
+    /*
+     * @see TextViewer#getControl()
+     */
+    public Control getControl() {
+        if (fComposite !is null)
+            return fComposite;
+        return super.getControl();
+    }
+
+    /*
+     * @see ISourceViewer#setAnnotationHover(IAnnotationHover)
+     */
+    public void setAnnotationHover(IAnnotationHover annotationHover) {
+        fAnnotationHover= annotationHover;
+    }
+
+    /**
+     * Sets the overview ruler's annotation hover of this source viewer.
+     * The annotation hover provides the information to be displayed in a hover
+     * popup window if requested over the overview rulers area. The annotation
+     * hover is assumed to be line oriented.
+     *
+     * @param annotationHover the hover to be used, <code>null</code> is a valid argument
+     * @since 3.0
+     */
+    public void setOverviewRulerAnnotationHover(IAnnotationHover annotationHover) {
+        fOverviewRulerAnnotationHover= annotationHover;
+    }
+
+    /*
+     * @see ISourceViewer#configure(SourceViewerConfiguration)
+     */
+    public void configure(SourceViewerConfiguration configuration) {
+
+        if (getTextWidget() is null)
+            return;
+
+        setDocumentPartitioning(configuration.getConfiguredDocumentPartitioning(this));
+
+        // install content type independent plug-ins
+        fPresentationReconciler= configuration.getPresentationReconciler(this);
+        if (fPresentationReconciler !is null)
+            fPresentationReconciler.install(this);
+
+        fReconciler= configuration.getReconciler(this);
+        if (fReconciler !is null)
+            fReconciler.install(this);
+
+        fContentAssistant= configuration.getContentAssistant(this);
+        if (fContentAssistant !is null) {
+            fContentAssistant.install(this);
+            if ( cast(IContentAssistantExtension4)fContentAssistant  && cast(IContentAssistantExtension4)fContentAssistant )
+                fContentAssistantFacade= new ContentAssistantFacade(fContentAssistant);
+            fContentAssistantInstalled= true;
+        }
+
+        fQuickAssistAssistant= configuration.getQuickAssistAssistant(this);
+        if (fQuickAssistAssistant !is null) {
+            fQuickAssistAssistant.install(this);
+            fQuickAssistAssistantInstalled= true;
+        }
+
+        fContentFormatter= configuration.getContentFormatter(this);
+
+        fInformationPresenter= configuration.getInformationPresenter(this);
+        if (fInformationPresenter !is null)
+            fInformationPresenter.install(this);
+
+        setUndoManager(configuration.getUndoManager(this));
+
+        getTextWidget().setTabs(configuration.getTabWidth(this));
+
+        setAnnotationHover(configuration.getAnnotationHover(this));
+        setOverviewRulerAnnotationHover(configuration.getOverviewRulerAnnotationHover(this));
+
+        setHoverControlCreator(configuration.getInformationControlCreator(this));
+
+        setHyperlinkPresenter(configuration.getHyperlinkPresenter(this));
+        IHyperlinkDetector[] hyperlinkDetectors= configuration.getHyperlinkDetectors(this);
+        int eventStateMask= configuration.getHyperlinkStateMask(this);
+        setHyperlinkDetectors(hyperlinkDetectors, eventStateMask);
+
+        // install content type specific plug-ins
+        String[] types= configuration.getConfiguredContentTypes(this);
+        for (int i= 0; i < types.length; i++) {
+
+            String t= types[i];
+
+            setAutoEditStrategies(configuration.getAutoEditStrategies(this, t), t);
+            setTextDoubleClickStrategy(configuration.getDoubleClickStrategy(this, t), t);
+
+            int[] stateMasks= configuration.getConfiguredTextHoverStateMasks(this, t);
+            if (stateMasks !is null) {
+                for (int j= 0; j < stateMasks.length; j++)  {
+                    int stateMask= stateMasks[j];
+                    setTextHover(configuration.getTextHover(this, t, stateMask), t, stateMask);
+                }
+            } else {
+                setTextHover(configuration.getTextHover(this, t), t, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
+            }
+
+            String[] prefixes= configuration.getIndentPrefixes(this, t);
+            if (prefixes !is null && prefixes.length > 0)
+                setIndentPrefixes(prefixes, t);
+
+            prefixes= configuration.getDefaultPrefixes(this, t);
+            if (prefixes !is null && prefixes.length > 0)
+                setDefaultPrefixes(prefixes, t);
+        }
+
+        activatePlugins();
+    }
+
+    /**
+     * After this method has been executed the caller knows that any installed annotation hover has been installed.
+     */
+    protected void ensureAnnotationHoverManagerInstalled() {
+        if (fVerticalRuler !is null && (fAnnotationHover !is null || !isVerticalRulerOnlyShowingAnnotations()) && fVerticalRulerHoveringController is null && fHoverControlCreator !is null) {
+            fVerticalRulerHoveringController= new AnnotationBarHoverManager(fVerticalRuler, this, fAnnotationHover, fHoverControlCreator);
+            fVerticalRulerHoveringController.install(fVerticalRuler.getControl());
+            fVerticalRulerHoveringController.getInternalAccessor().setInformationControlReplacer(new StickyHoverManager(this));
+        }
+    }
+
+    /**
+     * After this method has been executed the caller knows that any installed overview hover has been installed.
+     */
+    protected void ensureOverviewHoverManagerInstalled() {
+        if (fOverviewRuler !is null &&  fOverviewRulerAnnotationHover !is null  && fOverviewRulerHoveringController is null && fHoverControlCreator !is null)  {
+            fOverviewRulerHoveringController= new OverviewRulerHoverManager(fOverviewRuler, this, fOverviewRulerAnnotationHover, fHoverControlCreator);
+            fOverviewRulerHoveringController.install(fOverviewRuler.getControl());
+            fOverviewRulerHoveringController.getInternalAccessor().setInformationControlReplacer(new StickyHoverManager(this));
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#setHoverEnrichMode(dwtx.jface.text.ITextViewerExtension8.EnrichMode)
+     * @since 3.4
+     */
+    public void setHoverEnrichMode(ITextViewerExtension8_EnrichMode mode) {
+        super.setHoverEnrichMode(mode);
+        if (fVerticalRulerHoveringController !is null)
+            fVerticalRulerHoveringController.getInternalAccessor().setHoverEnrichMode(mode);
+        if (fOverviewRulerHoveringController !is null)
+            fOverviewRulerHoveringController.getInternalAccessor().setHoverEnrichMode(mode);
+    }
+
+    /*
+     * @see TextViewer#activatePlugins()
+     */
+    public void activatePlugins() {
+        ensureAnnotationHoverManagerInstalled();
+        ensureOverviewHoverManagerInstalled();
+        super.activatePlugins();
+    }
+
+    /*
+     * @see ISourceViewer#setDocument(IDocument, IAnnotationModel)
+     */
+    public void setDocument(IDocument document) {
+        setDocument(document, null, -1, -1);
+    }
+
+    /*
+     * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int)
+     */
+    public void setDocument(IDocument document, int visibleRegionOffset, int visibleRegionLength) {
+        setDocument(document, null, visibleRegionOffset, visibleRegionLength);
+    }
+
+    /*
+     * @see ISourceViewer#setDocument(IDocument, IAnnotationModel)
+     */
+    public void setDocument(IDocument document, IAnnotationModel annotationModel) {
+        setDocument(document, annotationModel, -1, -1);
+    }
+
+    /**
+     * Creates the visual annotation model on top of the given annotation model.
+     *
+     * @param annotationModel the wrapped annotation model
+     * @return the visual annotation model on top of the given annotation model
+     * @since 3.0
+     */
+    protected IAnnotationModel createVisualAnnotationModel(IAnnotationModel annotationModel) {
+        IAnnotationModelExtension model= new AnnotationModel();
+        model.addAnnotationModel(MODEL_ANNOTATION_MODEL, annotationModel);
+        return cast(IAnnotationModel) model;
+    }
+
+    /**
+     * Disposes the visual annotation model.
+     *
+     * @since 3.1
+     */
+    protected void disposeVisualAnnotationModel() {
+        if (fVisualAnnotationModel !is null) {
+            if (getDocument() !is null)
+                fVisualAnnotationModel.disconnect(getDocument());
+
+            if ( cast(IAnnotationModelExtension)fVisualAnnotationModel )
+                (cast(IAnnotationModelExtension)fVisualAnnotationModel).removeAnnotationModel(MODEL_ANNOTATION_MODEL);
+
+            fVisualAnnotationModel= null;
+        }
+    }
+
+    /*
+     * @see ISourceViewer#setDocument(IDocument, IAnnotationModel, int, int)
+     */
+    public void setDocument(IDocument document, IAnnotationModel annotationModel, int modelRangeOffset, int modelRangeLength) {
+        disposeVisualAnnotationModel();
+
+        if (annotationModel !is null && document !is null) {
+            fVisualAnnotationModel= createVisualAnnotationModel(annotationModel);
+            fVisualAnnotationModel.connect(document);
+        }
+
+        if (modelRangeOffset is -1 && modelRangeLength is -1)
+            super.setDocument(document);
+        else
+            super.setDocument(document, modelRangeOffset, modelRangeLength);
+
+        if (fVerticalRuler !is null)
+            fVerticalRuler.setModel(fVisualAnnotationModel);
+
+        if (fOverviewRuler !is null)
+            fOverviewRuler.setModel(fVisualAnnotationModel);
+    }
+
+    /*
+     * @see ISourceViewer#getAnnotationModel()
+     */
+    public IAnnotationModel getAnnotationModel() {
+        if ( cast(IAnnotationModelExtension)fVisualAnnotationModel ) {
+            IAnnotationModelExtension extension= cast(IAnnotationModelExtension) fVisualAnnotationModel;
+            return extension.getAnnotationModel(MODEL_ANNOTATION_MODEL);
+        }
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ISourceViewerExtension3#getQuickAssistAssistant()
+     * @since 3.2
+     */
+    public IQuickAssistAssistant getQuickAssistAssistant() {
+        return fQuickAssistAssistant;
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * @since 3.4
+     */
+    public final ContentAssistantFacade getContentAssistantFacade() {
+        return fContentAssistantFacade;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ISourceViewerExtension3#getQuickAssistInvocationContext()
+     * @since 3.2
+     */
+    public IQuickAssistInvocationContext getQuickAssistInvocationContext() {
+        Point selection= getSelectedRange();
+        return new TextInvocationContext(this, selection.x, selection.x);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ISourceViewerExtension2#getVisualAnnotationModel()
+     * @since 3.0
+     */
+    public IAnnotationModel getVisualAnnotationModel() {
+        return fVisualAnnotationModel;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ISourceViewerExtension2#unconfigure()
+     * @since 3.0
+     */
+    public void unconfigure() {
+        clearRememberedSelection();
+
+        if (fPresentationReconciler !is null) {
+            fPresentationReconciler.uninstall();
+            fPresentationReconciler= null;
+        }
+
+        if (fReconciler !is null) {
+            fReconciler.uninstall();
+            fReconciler= null;
+        }
+
+        if (fContentAssistant !is null) {
+            fContentAssistant.uninstall();
+            fContentAssistantInstalled= false;
+            fContentAssistant= null;
+            if (fContentAssistantFacade !is null)
+                fContentAssistantFacade= null;
+        }
+
+        if (fQuickAssistAssistant !is null) {
+            fQuickAssistAssistant.uninstall();
+            fQuickAssistAssistantInstalled= false;
+            fQuickAssistAssistant= null;
+        }
+
+        fContentFormatter= null;
+
+        if (fInformationPresenter !is null) {
+            fInformationPresenter.uninstall();
+            fInformationPresenter= null;
+        }
+
+        fAutoIndentStrategies= null;
+        fDoubleClickStrategies= null;
+        fTextHovers= null;
+        fIndentChars= null;
+        fDefaultPrefixChars= null;
+
+        if (fVerticalRulerHoveringController !is null) {
+            fVerticalRulerHoveringController.dispose();
+            fVerticalRulerHoveringController= null;
+        }
+
+        if (fOverviewRulerHoveringController !is null) {
+            fOverviewRulerHoveringController.dispose();
+            fOverviewRulerHoveringController= null;
+        }
+
+        if (fUndoManager !is null) {
+            fUndoManager.disconnect();
+            fUndoManager= null;
+        }
+
+        setHyperlinkDetectors(null, DWT.NONE);
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#handleDispose()
+     */
+    protected void handleDispose() {
+        unconfigure();
+
+        disposeVisualAnnotationModel();
+
+        fVerticalRuler= null;
+
+        fOverviewRuler= null;
+
+        // http://dev.eclipse.org/bugs/show_bug.cgi?id=15300
+        fComposite= null;
+
+        super.handleDispose();
+    }
+
+    /*
+     * @see ITextOperationTarget#canDoOperation(int)
+     */
+    public bool canDoOperation(int operation) {
+
+        if (getTextWidget() is null || (!redraws() && operation !is FORMAT))
+            return false;
+
+        if (operation is CONTENTASSIST_PROPOSALS)
+            return fContentAssistant !is null && fContentAssistantInstalled && isEditable();
+
+        if (operation is CONTENTASSIST_CONTEXT_INFORMATION)
+            return fContentAssistant !is null && fContentAssistantInstalled && isEditable();
+
+        if (operation is QUICK_ASSIST)
+            return fQuickAssistAssistant !is null && fQuickAssistAssistantInstalled && isEditable();
+
+        if (operation is INFORMATION)
+            return fInformationPresenter !is null;
+
+        if (operation is FORMAT) {
+            return fContentFormatter !is null && isEditable();
+        }
+
+        return super.canDoOperation(operation);
+    }
+
+    /**
+     * Creates a new formatting context for a format operation.
+     * <p>
+     * After the use of the context, clients are required to call
+     * its <code>dispose</code> method.
+     *
+     * @return The new formatting context
+     * @since 3.0
+     */
+    protected IFormattingContext createFormattingContext() {
+        return new FormattingContext();
+    }
+
+    /**
+     * Remembers and returns the current selection. The saved selection can be restored
+     * by calling <code>restoreSelection()</code>.
+     *
+     * @return the current selection
+     * @see dwtx.jface.text.ITextViewer#getSelectedRange()
+     * @since 3.0
+     */
+    protected Point rememberSelection() {
+
+        final Point selection= getSelectedRange();
+        final IDocument document= getDocument();
+
+        if (fSelections.isEmpty()) {
+            fSelectionCategory= _SELECTION_POSITION_CATEGORY ~ Integer.toString(toHash());
+            fSelectionUpdater= new NonDeletingPositionUpdater(fSelectionCategory);
+            document.addPositionCategory(fSelectionCategory);
+            document.addPositionUpdater(fSelectionUpdater);
+        }
+
+        try {
+
+            final Position position= new Position(selection.x, selection.y);
+            document.addPosition(fSelectionCategory, position);
+            fSelections.push(position);
+
+        } catch (BadLocationException exception) {
+            // Should not happen
+        } catch (BadPositionCategoryException exception) {
+            // Should not happen
+        }
+
+        return selection;
+    }
+
+    /**
+     * Restores a previously saved selection in the document.
+     * <p>
+     * If no selection was previously saved, nothing happens.
+     *
+     * @since 3.0
+     */
+    protected void restoreSelection() {
+
+        if (!fSelections.isEmpty()) {
+
+            final IDocument document= getDocument();
+            final Position position= cast(Position) fSelections.pop();
+
+            try {
+                document.removePosition(fSelectionCategory, position);
+                Point currentSelection= getSelectedRange();
+                if (currentSelection is null || currentSelection.x !is position.getOffset() || currentSelection.y !is position.getLength())
+                    setSelectedRange(position.getOffset(), position.getLength());
+
+                if (fSelections.isEmpty())
+                    clearRememberedSelection();
+            } catch (BadPositionCategoryException exception) {
+                // Should not happen
+            }
+        }
+    }
+
+    protected void clearRememberedSelection() {
+        if (!fSelections.isEmpty())
+            fSelections.clear();
+
+        IDocument document= getDocument();
+        if (document !is null && fSelectionUpdater !is null) {
+            document.removePositionUpdater(fSelectionUpdater);
+            try {
+                document.removePositionCategory(fSelectionCategory);
+            } catch (BadPositionCategoryException e) {
+                // ignore
+            }
+        }
+        fSelectionUpdater= null;
+        fSelectionCategory= null;
+    }
+
+    /*
+     * @see ITextOperationTarget#doOperation(int)
+     */
+    public void doOperation(int operation) {
+
+        if (getTextWidget() is null || (!redraws() && operation !is FORMAT))
+            return;
+
+        switch (operation) {
+            case CONTENTASSIST_PROPOSALS:
+                fContentAssistant.showPossibleCompletions();
+                return;
+            case CONTENTASSIST_CONTEXT_INFORMATION:
+                fContentAssistant.showContextInformation();
+                return;
+            case QUICK_ASSIST:
+                // FIXME: must find a way to post to the status line
+                /* String msg= */ fQuickAssistAssistant.showPossibleQuickAssists();
+                // setStatusLineErrorMessage(msg);
+                return;
+            case INFORMATION:
+                fInformationPresenter.showInformation();
+                return;
+            case FORMAT:
+                {
+                    final Point selection= rememberSelection();
+                    final IRewriteTarget target= getRewriteTarget();
+                    final IDocument document= getDocument();
+                    IFormattingContext context= null;
+                    DocumentRewriteSession rewriteSession= null;
+
+                    if ( cast(IDocumentExtension4)document ) {
+                        IDocumentExtension4 extension= cast(IDocumentExtension4) document;
+                        DocumentRewriteSessionType type= selection.y is 0 || selection.y > 1000 ? DocumentRewriteSessionType.SEQUENTIAL : DocumentRewriteSessionType.UNRESTRICTED_SMALL;
+                        rewriteSession= extension.startRewriteSession(type);
+                    } else {
+                        setRedraw(false);
+                        target.beginCompoundChange();
+                    }
+
+                    try {
+
+                        final String rememberedContents= document.get();
+
+                        try {
+
+                            if ( cast(IContentFormatterExtension)fContentFormatter ) {
+                                final IContentFormatterExtension extension= cast(IContentFormatterExtension) fContentFormatter;
+                                context= createFormattingContext();
+                                if (selection.y is 0) {
+                                    context.setProperty(stringcast(FormattingContextProperties.CONTEXT_DOCUMENT), Boolean.TRUE);
+                                } else {
+                                    context.setProperty(stringcast(FormattingContextProperties.CONTEXT_DOCUMENT), Boolean.FALSE);
+                                    context.setProperty(stringcast(FormattingContextProperties.CONTEXT_REGION), new Region(selection.x, selection.y));
+                                }
+                                extension.format(document, context);
+                            } else {
+                                IRegion r;
+                                if (selection.y is 0) {
+                                    IRegion coverage= getModelCoverage();
+                                    r= coverage is null ? new Region(0, 0) : coverage;
+                                } else {
+                                    r= new Region(selection.x, selection.y);
+                                }
+                                fContentFormatter.format(document, r);
+                            }
+
+                            updateSlaveDocuments(document);
+
+                        } catch (RuntimeException x) {
+                            // fire wall for https://bugs.eclipse.org/bugs/show_bug.cgi?id=47472
+                            // if something went wrong we undo the changes we just did
+                            // TODO to be removed after 3.0 M8
+                            document.set(rememberedContents);
+                            throw x;
+                        }
+
+                    } finally {
+
+                        if ( cast(IDocumentExtension4)document ) {
+                            IDocumentExtension4 extension= cast(IDocumentExtension4) document;
+                            extension.stopRewriteSession(rewriteSession);
+                        } else {
+                            target.endCompoundChange();
+                            setRedraw(true);
+                        }
+
+                        restoreSelection();
+                        if (context !is null)
+                            context.dispose();
+                    }
+                    return;
+                }
+            default:
+                super.doOperation(operation);
+        }
+    }
+
+    /**
+     * Updates all slave documents of the given document. This default implementation calls <code>updateSlaveDocument</code>
+     * for their current visible range. Subclasses may reimplement.
+     *
+     * @param masterDocument the master document
+     * @since 3.0
+     */
+    protected void updateSlaveDocuments(IDocument masterDocument) {
+        ISlaveDocumentManager manager= getSlaveDocumentManager();
+        if ( cast(ISlaveDocumentManagerExtension)manager ) {
+            ISlaveDocumentManagerExtension extension= cast(ISlaveDocumentManagerExtension) manager;
+            IDocument[] slaves= extension.getSlaveDocuments(masterDocument);
+            if (slaves !is null) {
+                for (int i= 0; i < slaves.length; i++) {
+                    if ( auto child = cast(ChildDocument)slaves[i] ) {
+                        Position p= child.getParentDocumentRange();
+                        try {
+
+                            if (!updateSlaveDocument(child, p.getOffset(), p.getLength()))
+                                child.repairLineInformation();
+
+                        } catch (BadLocationException e) {
+                            // ignore
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /*
+     * @see ITextOperationTargetExtension#enableOperation(int, bool)
+     * @since 2.0
+     */
+    public void enableOperation(int operation, bool enable) {
+
+        switch (operation) {
+            case CONTENTASSIST_PROPOSALS:
+            case CONTENTASSIST_CONTEXT_INFORMATION: {
+
+                if (fContentAssistant is null)
+                    return;
+
+                if (enable) {
+                    if (!fContentAssistantInstalled) {
+                        fContentAssistant.install(this);
+                        fContentAssistantInstalled= true;
+                    }
+                } else if (fContentAssistantInstalled) {
+                    fContentAssistant.uninstall();
+                    fContentAssistantInstalled= false;
+                }
+                break;
+            }
+            case QUICK_ASSIST: {
+
+                if (fQuickAssistAssistant is null)
+                    return;
+
+                if (enable) {
+                    if (!fQuickAssistAssistantInstalled) {
+                        fQuickAssistAssistant.install(this);
+                        fQuickAssistAssistantInstalled= true;
+                    }
+                } else if (fContentAssistantInstalled) {
+                    fQuickAssistAssistant.uninstall();
+                    fContentAssistantInstalled= false;
+                }
+            }
+        }
+    }
+
+    /*
+     * @see ISourceViewer#setRangeIndicator(Annotation)
+     */
+    public void setRangeIndicator(Annotation rangeIndicator) {
+        fRangeIndicator= rangeIndicator;
+    }
+
+    /*
+     * @see ISourceViewer#setRangeIndication(int, int, bool)
+     */
+    public void setRangeIndication(int start, int length, bool moveCursor) {
+
+        if (moveCursor) {
+            setSelectedRange(start, 0);
+            revealRange(start, length);
+        }
+
+        if (fRangeIndicator !is null && cast(IAnnotationModelExtension)fVisualAnnotationModel ) {
+            IAnnotationModelExtension extension= cast(IAnnotationModelExtension) fVisualAnnotationModel;
+            extension.modifyAnnotationPosition(fRangeIndicator, new Position(start, length));
+        }
+    }
+
+    /*
+     * @see ISourceViewer#getRangeIndication()
+     */
+    public IRegion getRangeIndication() {
+        if (fRangeIndicator !is null && fVisualAnnotationModel !is null) {
+            Position position= fVisualAnnotationModel.getPosition(fRangeIndicator);
+            if (position !is null)
+                return new Region(position.getOffset(), position.getLength());
+        }
+
+        return null;
+    }
+
+    /*
+     * @see ISourceViewer#removeRangeIndication()
+     */
+    public void removeRangeIndication() {
+        if (fRangeIndicator !is null && fVisualAnnotationModel !is null)
+            fVisualAnnotationModel.removeAnnotation(fRangeIndicator);
+    }
+
+    /*
+     * @see ISourceViewer#showAnnotations(bool)
+     */
+    public void showAnnotations(bool show) {
+        bool old= fIsVerticalRulerVisible;
+
+        fIsVerticalRulerVisible= (fVerticalRuler !is null && (show || !isVerticalRulerOnlyShowingAnnotations()));
+        if (old !is fIsVerticalRulerVisible && fComposite !is null && !fComposite.isDisposed())
+            fComposite.layout();
+
+        if (fIsVerticalRulerVisible && show)
+            ensureAnnotationHoverManagerInstalled();
+        else if (fVerticalRulerHoveringController !is null) {
+            fVerticalRulerHoveringController.dispose();
+            fVerticalRulerHoveringController= null;
+        }
+    }
+
+    /**
+     * Tells whether the vertical ruler only acts as annotation ruler.
+     *
+     * @return <code>true</code> if the vertical ruler only show annotations
+     * @since 3.3
+     */
+    private bool isVerticalRulerOnlyShowingAnnotations() {
+        if ( cast(VerticalRuler)fVerticalRuler )
+            return true;
+
+        if ( cast(CompositeRuler)fVerticalRuler ) {
+            Iterator iter= (cast(CompositeRuler)fVerticalRuler).getDecoratorIterator();
+            return iter.hasNext() && cast(AnnotationRulerColumn)iter.next() && !iter.hasNext();
+        }
+        return false;
+    }
+
+    /**
+     * Returns the vertical ruler of this viewer.
+     *
+     * @return the vertical ruler of this viewer
+     * @since 3.0
+     */
+    protected final IVerticalRuler getVerticalRuler() {
+        return fVerticalRuler;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ISourceViewerExtension#showAnnotationsOverview(bool)
+     * @since 2.1
+     */
+    public void showAnnotationsOverview(bool show) {
+        bool old= fIsOverviewRulerVisible;
+        fIsOverviewRulerVisible= (show && fOverviewRuler !is null);
+        if (old !is fIsOverviewRulerVisible) {
+            if (fComposite !is null && !fComposite.isDisposed())
+                fComposite.layout();
+            if (fIsOverviewRulerVisible) {
+                ensureOverviewHoverManagerInstalled();
+            } else if (fOverviewRulerHoveringController !is null) {
+                fOverviewRulerHoveringController.dispose();
+                fOverviewRulerHoveringController= null;
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.ISourceViewer#getCurrentAnnotationHover()
+     * @since 3.2
+     */
+    public IAnnotationHover getCurrentAnnotationHover() {
+        if (fVerticalRulerHoveringController is null)
+            return null;
+        return fVerticalRulerHoveringController.getCurrentAnnotationHover();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/SourceViewerConfiguration.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,486 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.SourceViewerConfiguration;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+import dwt.DWT;
+import dwt.graphics.RGB;
+import dwt.widgets.Shell;
+import dwtx.jface.text.DefaultAutoIndentStrategy;
+import dwtx.jface.text.DefaultInformationControl;
+import dwtx.jface.text.DefaultTextDoubleClickStrategy;
+import dwtx.jface.text.IAutoEditStrategy;
+import dwtx.jface.text.IAutoIndentStrategy;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentExtension3;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.ITextDoubleClickStrategy;
+import dwtx.jface.text.ITextHover;
+import dwtx.jface.text.ITextViewerExtension2;
+import dwtx.jface.text.IUndoManager;
+import dwtx.jface.text.TextViewerUndoManager;
+import dwtx.jface.text.contentassist.IContentAssistant;
+import dwtx.jface.text.formatter.IContentFormatter;
+import dwtx.jface.text.hyperlink.DefaultHyperlinkPresenter;
+import dwtx.jface.text.hyperlink.IHyperlinkDetector;
+import dwtx.jface.text.hyperlink.IHyperlinkPresenter;
+import dwtx.jface.text.hyperlink.URLHyperlinkDetector;
+import dwtx.jface.text.information.IInformationPresenter;
+import dwtx.jface.text.presentation.IPresentationReconciler;
+import dwtx.jface.text.presentation.PresentationReconciler;
+import dwtx.jface.text.quickassist.IQuickAssistAssistant;
+import dwtx.jface.text.reconciler.IReconciler;
+
+
+/**
+ * This class bundles the configuration space of a source viewer. Instances of
+ * this class are passed to the <code>configure</code> method of
+ * <code>ISourceViewer</code>.
+ * <p>
+ * Each method in this class get as argument the source viewer for which it
+ * should provide a particular configuration setting such as a presentation
+ * reconciler. Based on its specific knowledge about the returned object, the
+ * configuration might share such objects or compute them according to some
+ * rules.</p>
+ * <p>
+ * Clients should subclass and override just those methods which must be
+ * specific to their needs.</p>
+ *
+ * @see dwtx.jface.text.source.ISourceViewer
+ */
+public class SourceViewerConfiguration {
+
+
+    /**
+     * Creates a new source viewer configuration that behaves according to
+     * specification of this class' methods.
+     */
+    public this() {
+//         super();
+    }
+
+    /**
+     * Returns the visual width of the tab character. This implementation always
+     * returns 4.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return the tab width
+     */
+    public int getTabWidth(ISourceViewer sourceViewer) {
+        return 4;
+    }
+
+    /**
+     * Returns the undo manager for the given source viewer. This implementation
+     * always returns a new instance of <code>DefaultUndoManager</code> whose
+     * history length is set to 25.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return an undo manager or <code>null</code> if no undo/redo should not be supported
+     */
+    public IUndoManager getUndoManager(ISourceViewer sourceViewer) {
+        return new TextViewerUndoManager(25);
+    }
+
+    /**
+     * Returns the reconciler ready to be used with the given source viewer.
+     * This implementation always returns <code>null</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return a reconciler or <code>null</code> if reconciling should not be supported
+     */
+    public IReconciler getReconciler(ISourceViewer sourceViewer) {
+        return null;
+    }
+
+    /**
+     * Returns the presentation reconciler ready to be used with the given source viewer.
+     *
+     * @param sourceViewer the source viewer
+     * @return the presentation reconciler or <code>null</code> if presentation reconciling should not be supported
+     */
+    public IPresentationReconciler getPresentationReconciler(ISourceViewer sourceViewer) {
+        PresentationReconciler reconciler= new PresentationReconciler();
+        reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
+        return reconciler;
+    }
+
+    /**
+     * Returns the content formatter ready to be used with the given source viewer.
+     * This implementation always returns <code>null</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return a content formatter or <code>null</code> if formatting should not be supported
+     */
+    public IContentFormatter getContentFormatter(ISourceViewer sourceViewer) {
+        return null;
+    }
+
+    /**
+     * Returns the content assistant ready to be used with the given source viewer.
+     * This implementation always returns <code>null</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return a content assistant or <code>null</code> if content assist should not be supported
+     */
+    public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
+        return null;
+    }
+
+    /**
+     * Returns the quick assist assistant ready to be used with the given
+     * source viewer.
+     * This implementation always returns <code>null</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return a quick assist assistant or <code>null</code> if quick assist should not be supported
+     * @since 3.2
+     */
+    public IQuickAssistAssistant getQuickAssistAssistant(ISourceViewer sourceViewer) {
+        return null;
+    }
+
+    /**
+     * Returns the auto indentation strategy ready to be used with the given source viewer
+     * when manipulating text of the given content type. This implementation always
+     * returns an new instance of <code>DefaultAutoIndentStrategy</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @param contentType the content type for which the strategy is applicable
+     * @return the auto indent strategy or <code>null</code> if automatic indentation is not to be enabled
+     * @deprecated since 3.1 use {@link #getAutoEditStrategies(ISourceViewer, String)} instead
+     */
+    public IAutoIndentStrategy getAutoIndentStrategy(ISourceViewer sourceViewer, String contentType) {
+        return new DefaultAutoIndentStrategy();
+    }
+
+    /**
+     * Returns the auto edit strategies ready to be used with the given source viewer
+     * when manipulating text of the given content type. For backward compatibility, this implementation always
+     * returns an array containing the result of {@link #getAutoIndentStrategy(ISourceViewer, String)}.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @param contentType the content type for which the strategies are applicable
+     * @return the auto edit strategies or <code>null</code> if automatic editing is not to be enabled
+     * @since 3.1
+     */
+    public IAutoEditStrategy[] getAutoEditStrategies(ISourceViewer sourceViewer, String contentType) {
+        return [ getAutoIndentStrategy(sourceViewer, contentType) ];
+    }
+
+    /**
+     * Returns the default prefixes to be used by the line-prefix operation
+     * in the given source viewer for text of the given content type. This implementation always
+     * returns <code>null</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @param contentType the content type for which the prefix is applicable
+     * @return the default prefixes or <code>null</code> if the prefix operation should not be supported
+     * @since 2.0
+     */
+    public String[] getDefaultPrefixes(ISourceViewer sourceViewer, String contentType) {
+        return null;
+    }
+
+    /**
+     * Returns the double-click strategy ready to be used in this viewer when double clicking
+     * onto text of the given content type. This implementation always returns a new instance of
+     * <code>DefaultTextDoubleClickStrategy</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @param contentType the content type for which the strategy is applicable
+     * @return a double-click strategy or <code>null</code> if double clicking should not be supported
+     */
+    public ITextDoubleClickStrategy getDoubleClickStrategy(ISourceViewer sourceViewer, String contentType) {
+        return new DefaultTextDoubleClickStrategy();
+    }
+
+    /**
+     * Returns the prefixes to be used by the line-shift operation. This implementation
+     * always returns <code>new String[] { "\t", "    ", "" }</code>.
+     * <p>
+     * <strong>Note:</strong> <em>This default is incorrect but cannot be changed in order not
+     * to break any existing clients. Subclasses should overwrite this method and
+     * use {@link #getIndentPrefixesForTab(int)} if applicable.</em>
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @param contentType the content type for which the prefix is applicable
+     * @return the prefixes or <code>null</code> if the prefix operation should not be supported
+     */
+    public String[] getIndentPrefixes(ISourceViewer sourceViewer, String contentType) {
+        return [ "\t", "    ", "" ]; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+    }
+
+    /**
+     * Computes and returns the indent prefixes for tab indentation
+     * which is represented as <code>tabSizeInSpaces</code>.
+     *
+     * @param tabWidth the display tab width
+     * @return the indent prefixes
+     * @see #getIndentPrefixes(ISourceViewer, String)
+     * @since 3.3
+     */
+    protected String[] getIndentPrefixesForTab(int tabWidth) {
+        String[] indentPrefixes= new String[tabWidth + 2];
+        for (int i= 0; i <= tabWidth; i++) {
+            char[] spaceChars= new char[i];
+            Arrays.fill(spaceChars, ' ');
+            String spaces= new_String(spaceChars);
+            if (i < tabWidth)
+                indentPrefixes[i]= spaces ~ '\t';
+            else
+                indentPrefixes[i]= new_String(spaces);
+        }
+        indentPrefixes[tabWidth + 1]= ""; //$NON-NLS-1$
+        return indentPrefixes;
+    }
+
+    /**
+     * Returns the annotation hover which will provide the information to be
+     * shown in a hover popup window when requested for the given
+     * source viewer. This implementation always returns <code>null</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return an annotation hover or <code>null</code> if no hover support should be installed
+     */
+    public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+        return null;
+    }
+
+    /**
+     * Returns the annotation hover which will provide the information to be
+     * shown in a hover popup window when requested for the overview ruler
+     * of the given source viewer.This implementation always returns the general
+     * annotation hover returned by <code>getAnnotationHover</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return an annotation hover or <code>null</code> if no hover support should be installed
+     * @since 3.0
+     */
+    public IAnnotationHover getOverviewRulerAnnotationHover(ISourceViewer sourceViewer) {
+        return getAnnotationHover(sourceViewer);
+    }
+
+    /**
+     * Returns the DWT event state masks for which text hover are configured for
+     * the given content type.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @param contentType the content type
+     * @return an <code>int</code> array with the configured DWT event state masks
+     *          or <code>null</code> if text hovers are not supported for the given content type
+     * @since 2.1
+     */
+    public int[] getConfiguredTextHoverStateMasks(ISourceViewer sourceViewer, String contentType) {
+        return null;
+    }
+
+    /**
+     * Returns the text hover which will provide the information to be shown
+     * in a text hover popup window when requested for the given source viewer and
+     * the given content type. This implementation always returns <code>
+     * null</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @param contentType the content type
+     * @param stateMask the DWT event state mask
+     * @return a text hover or <code>null</code> if no hover support should be installed
+     * @since 2.1
+     */
+    public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType, int stateMask) {
+        if (stateMask is ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK)
+            return getTextHover(sourceViewer, contentType);
+        return null;
+    }
+
+    /**
+     * Returns the text hover which will provide the information to be shown
+     * in a text hover popup window when requested for the given source viewer and
+     * the given content type. This implementation always returns <code>
+     * null</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @param contentType the content type
+     * @return a text hover or <code>null</code> if no hover support should be installed
+     */
+    public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) {
+        return null;
+    }
+
+    /**
+     * Returns the information control creator. The creator is a factory creating information
+     * controls for the given source viewer. This implementation always returns a creator for
+     * <code>DefaultInformationControl</code> instances.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return the information control creator or <code>null</code> if no information support should be installed
+     * @since 2.0
+     */
+    public IInformationControlCreator getInformationControlCreator(ISourceViewer sourceViewer) {
+        return new class()  IInformationControlCreator {
+            public IInformationControl createInformationControl(Shell parent) {
+                return new DefaultInformationControl(parent);
+            }
+        };
+    }
+
+    /**
+     * Returns the information presenter which will determine and shown
+     * information requested for the current cursor position. This implementation
+     * always returns <code>null</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return an information presenter <code>null</code> if  no information presenter should be installed
+     * @since 2.0
+     */
+    public dwtx.jface.text.information.IInformationPresenter.IInformationPresenter getInformationPresenter(ISourceViewer sourceViewer) {
+        return null;
+    }
+
+    /**
+     * Returns all configured content types for the given source viewer. This list
+     * tells the caller which content types must be configured for the given source
+     * viewer, i.e. for which content types the given source viewer's functionalities
+     * must be specified. This implementation always returns <code>
+     * new String[] { IDocument.DEFAULT_CONTENT_TYPE }</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return the configured content types for the given viewer
+     */
+    public String[] getConfiguredContentTypes(ISourceViewer sourceViewer) {
+        return [ IDocument.DEFAULT_CONTENT_TYPE ];
+    }
+
+    /**
+     * Returns the configured partitioning for the given source viewer. The partitioning is
+     * used when the querying content types from the source viewer's input document.  This
+     * implementation always returns <code>IDocumentExtension3.DEFAULT_PARTITIONING</code>.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return the configured partitioning
+     * @see #getConfiguredContentTypes(ISourceViewer)
+     * @since 3.0
+     */
+    public String getConfiguredDocumentPartitioning(ISourceViewer sourceViewer) {
+        return IDocumentExtension3.DEFAULT_PARTITIONING;
+    }
+
+    /**
+     * Returns the hyperlink detectors which be used to detect hyperlinks
+     * in the given source viewer. This
+     * implementation always returns an array with an URL hyperlink detector.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return an array with hyperlink detectors or <code>null</code> if no hyperlink support should be installed
+     * @since 3.1
+     */
+    public IHyperlinkDetector[] getHyperlinkDetectors(ISourceViewer sourceViewer) {
+        if (sourceViewer is null)
+            return null;
+
+        return [ new URLHyperlinkDetector() ];
+    }
+
+    /**
+     * Returns the hyperlink presenter for the given source viewer.
+     * This implementation always returns the {@link DefaultHyperlinkPresenter}.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return the hyperlink presenter or <code>null</code> if no hyperlink support should be installed
+     * @since 3.1
+     */
+    public IHyperlinkPresenter getHyperlinkPresenter(ISourceViewer sourceViewer) {
+        return new DefaultHyperlinkPresenter(new RGB(0, 0, 255));
+    }
+
+    /**
+     * Returns the DWT event state mask which in combination
+     * with the left mouse button activates hyperlinking.
+     * This implementation always returns the {@link DWT#MOD1}.
+     *
+     * @param sourceViewer the source viewer to be configured by this configuration
+     * @return the DWT event state mask to activate hyperlink mode
+     * @since 3.1
+     */
+    public int getHyperlinkStateMask(ISourceViewer sourceViewer) {
+        return DWT.MOD1;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/TextInvocationContext.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,124 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.TextInvocationContext;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.quickassist.IQuickAssistInvocationContext;
+
+
+/**
+ * Text quick assist invocation context.
+ * <p>
+ * Clients may extend this class to add additional context information.
+ * </p>
+ * 
+ * @since 3.3
+ */
+public class TextInvocationContext : IQuickAssistInvocationContext {
+
+    private ISourceViewer fSourceViewer;
+    private int fOffset;
+    private int fLength;
+    
+    public this(ISourceViewer sourceViewer, int offset, int length) {
+        fSourceViewer= sourceViewer;
+        fOffset= offset;
+        fLength= length;
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistInvocationContext#getOffset()
+     */
+    public int getOffset() {
+        return fOffset;
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistInvocationContext#getLength()
+     */
+    public int getLength() {
+        return fLength;
+    }
+
+    /*
+     * @see dwtx.jface.text.quickassist.IQuickAssistInvocationContext#getSourceViewer()
+     */
+    public ISourceViewer getSourceViewer() {
+        return fSourceViewer;
+    }
+    
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/VerticalRuler.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,664 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.VerticalRuler;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.MouseEvent;
+import dwt.events.MouseListener;
+import dwt.events.PaintEvent;
+import dwt.events.PaintListener;
+import dwt.graphics.Font;
+import dwt.graphics.GC;
+import dwt.graphics.Image;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Canvas;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextListener;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.IViewportListener;
+import dwtx.jface.text.JFaceTextUtil;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextEvent;
+
+
+/**
+ * A vertical ruler which is connected to a text viewer. Single column standard
+ * implementation of {@link dwtx.jface.text.source.IVerticalRuler}.
+ * <p>
+ * The same can be achieved by using <code>CompositeRuler</code> configured
+ * with an <code>AnnotationRulerColumn</code>. Clients may use this class as
+ * is.
+ *
+ * @see dwtx.jface.text.ITextViewer
+ */
+public final class VerticalRuler : IVerticalRuler, IVerticalRulerExtension {
+
+    /**
+     * Internal listener class.
+     */
+    class InternalListener : IViewportListener, IAnnotationModelListener, ITextListener {
+
+        /*
+         * @see IViewportListener#viewportChanged(int)
+         */
+        public void viewportChanged(int verticalPosition) {
+            if (verticalPosition !is fScrollPos)
+                redraw();
+        }
+
+        /*
+         * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
+         */
+        public void modelChanged(IAnnotationModel model) {
+            update();
+        }
+
+        /*
+         * @see ITextListener#textChanged(TextEvent)
+         */
+        public void textChanged(TextEvent e) {
+            if (fTextViewer !is null && e.getViewerRedrawState())
+                redraw();
+        }
+    }
+
+    /** The vertical ruler's text viewer */
+    private ITextViewer fTextViewer;
+    /** The ruler's canvas */
+    private Canvas fCanvas;
+    /** The vertical ruler's model */
+    private IAnnotationModel fModel;
+    /** Cache for the actual scroll position in pixels */
+    private int fScrollPos;
+    /** The buffer for double buffering */
+    private Image fBuffer;
+    /** The line of the last mouse button activity */
+    private int fLastMouseButtonActivityLine= -1;
+    /** The internal listener */
+    private InternalListener fInternalListener;
+    /** The width of this vertical ruler */
+    private int fWidth;
+    /**
+     * The annotation access of this vertical ruler
+     * @since 3.0
+     */
+    private IAnnotationAccess fAnnotationAccess;
+
+    /**
+     * Constructs a vertical ruler with the given width.
+     *
+     * @param width the width of the vertical ruler
+     */
+    public this(int width) {
+        this(width, null);
+    }
+
+    /**
+     * Constructs a vertical ruler with the given width and the given annotation
+     * access.
+     *
+     * @param width the width of the vertical ruler
+     * @param annotationAcccess the annotation access
+     * @since 3.0
+     */
+    public this(int width, IAnnotationAccess annotationAcccess) {
+
+        fInternalListener= new InternalListener();
+
+        fWidth= width;
+        fAnnotationAccess= annotationAcccess;
+    }
+
+    /*
+     * @see IVerticalRuler#getControl()
+     */
+    public Control getControl() {
+        return fCanvas;
+    }
+
+    /*
+     * @see IVerticalRuler#createControl(Composite, ITextViewer)
+     */
+    public Control createControl(Composite parent, ITextViewer textViewer) {
+
+        fTextViewer= textViewer;
+
+        fCanvas= new Canvas(parent, DWT.NO_BACKGROUND);
+
+        fCanvas.addPaintListener(new class()  PaintListener {
+            public void paintControl(PaintEvent event) {
+                if (fTextViewer !is null)
+                    doubleBufferPaint(event.gc);
+            }
+        });
+
+        fCanvas.addDisposeListener(new class()  DisposeListener {
+            public void widgetDisposed(DisposeEvent e) {
+                handleDispose();
+                fTextViewer= null;
+            }
+        });
+
+        fCanvas.addMouseListener(new class()  MouseListener {
+            public void mouseUp(MouseEvent event) {
+            }
+
+            public void mouseDown(MouseEvent event) {
+                fLastMouseButtonActivityLine= toDocumentLineNumber(event.y);
+            }
+
+            public void mouseDoubleClick(MouseEvent event) {
+                fLastMouseButtonActivityLine= toDocumentLineNumber(event.y);
+            }
+        });
+
+        if (fTextViewer !is null) {
+            fTextViewer.addViewportListener(fInternalListener);
+            fTextViewer.addTextListener(fInternalListener);
+        }
+
+        return fCanvas;
+    }
+
+    /**
+     * Disposes the ruler's resources.
+     */
+    private void handleDispose() {
+
+        if (fTextViewer !is null) {
+            fTextViewer.removeViewportListener(fInternalListener);
+            fTextViewer.removeTextListener(fInternalListener);
+            fTextViewer= null;
+        }
+
+        if (fModel !is null)
+            fModel.removeAnnotationModelListener(fInternalListener);
+
+        if (fBuffer !is null) {
+            fBuffer.dispose();
+            fBuffer= null;
+        }
+    }
+
+
+    /**
+     * Double buffer drawing.
+     *
+     * @param dest the GC to draw into
+     */
+    private void doubleBufferPaint(GC dest) {
+
+        Point size= fCanvas.getSize();
+
+        if (size.x <= 0 || size.y <= 0)
+            return;
+
+        if (fBuffer !is null) {
+            Rectangle r= fBuffer.getBounds();
+            if (r.width !is size.x || r.height !is size.y) {
+                fBuffer.dispose();
+                fBuffer= null;
+            }
+        }
+        if (fBuffer is null)
+            fBuffer= new Image(fCanvas.getDisplay(), size.x, size.y);
+
+        GC gc= new GC(fBuffer);
+        gc.setFont(fTextViewer.getTextWidget().getFont());
+        try {
+            gc.setBackground(fCanvas.getBackground());
+            gc.fillRectangle(0, 0, size.x, size.y);
+
+            if ( cast(ITextViewerExtension5)fTextViewer )
+                doPaint1(gc);
+            else
+                doPaint(gc);
+
+        } finally {
+            gc.dispose();
+        }
+
+        dest.drawImage(fBuffer, 0, 0);
+    }
+
+    /**
+     * Returns the document offset of the upper left corner of the
+     * widgets view port, possibly including partially visible lines.
+     *
+     * @return the document offset of the upper left corner including partially visible lines
+     * @since 2.0
+     */
+    private int getInclusiveTopIndexStartOffset() {
+
+        StyledText textWidget= fTextViewer.getTextWidget();
+        if (textWidget !is null && !textWidget.isDisposed()) {
+            int top= JFaceTextUtil.getPartialTopIndex(fTextViewer);
+            try {
+                IDocument document= fTextViewer.getDocument();
+                return document.getLineOffset(top);
+            } catch (BadLocationException x) {
+            }
+        }
+
+        return -1;
+    }
+
+
+
+    /**
+     * Draws the vertical ruler w/o drawing the Canvas background.
+     *
+     * @param gc  the GC to draw into
+     */
+    protected void doPaint(GC gc) {
+
+        if (fModel is null || fTextViewer is null)
+            return;
+
+        IAnnotationAccessExtension annotationAccessExtension= null;
+        if ( cast(IAnnotationAccessExtension)fAnnotationAccess )
+            annotationAccessExtension= cast(IAnnotationAccessExtension) fAnnotationAccess;
+
+        StyledText styledText= fTextViewer.getTextWidget();
+        IDocument doc= fTextViewer.getDocument();
+
+        int topLeft= getInclusiveTopIndexStartOffset();
+        int bottomRight= fTextViewer.getBottomIndexEndOffset();
+        int viewPort= bottomRight - topLeft;
+
+        Point d= fCanvas.getSize();
+        fScrollPos= styledText.getTopPixel();
+
+        int topLine= -1, bottomLine= -1;
+        try {
+            IRegion region= fTextViewer.getVisibleRegion();
+            topLine= doc.getLineOfOffset(region.getOffset());
+            bottomLine= doc.getLineOfOffset(region.getOffset() + region.getLength());
+        } catch (BadLocationException x) {
+            return;
+        }
+
+        // draw Annotations
+        Rectangle r= new Rectangle(0, 0, 0, 0);
+        int maxLayer= 1;    // loop at least once though layers.
+
+        for (int layer= 0; layer < maxLayer; layer++) {
+            Iterator iter= fModel.getAnnotationIterator();
+            while (iter.hasNext()) {
+                IAnnotationPresentation annotationPresentation= null;
+                Annotation annotation= cast(Annotation) iter.next();
+
+                int lay= IAnnotationAccessExtension.DEFAULT_LAYER;
+                if (annotationAccessExtension !is null)
+                    lay= annotationAccessExtension.getLayer(annotation);
+                else if ( cast(IAnnotationPresentation)annotation ) {
+                    annotationPresentation= cast(IAnnotationPresentation)annotation;
+                    lay= annotationPresentation.getLayer();
+                }
+                maxLayer= Math.max(maxLayer, lay+1);    // dynamically update layer maximum
+                if (lay !is layer)   // wrong layer: skip annotation
+                    continue;
+
+                Position position= fModel.getPosition(annotation);
+                if (position is null)
+                    continue;
+
+                if (!position.overlapsWith(topLeft, viewPort))
+                    continue;
+
+                try {
+
+                    int offset= position.getOffset();
+                    int length= position.getLength();
+
+                    int startLine= doc.getLineOfOffset(offset);
+                    if (startLine < topLine)
+                        startLine= topLine;
+
+                    int endLine= startLine;
+                    if (length > 0)
+                        endLine= doc.getLineOfOffset(offset + length - 1);
+                    if (endLine > bottomLine)
+                        endLine= bottomLine;
+
+                    startLine -= topLine;
+                    endLine -= topLine;
+
+                    r.x= 0;
+                    r.y= JFaceTextUtil.computeLineHeight(styledText, 0, startLine, startLine)  - fScrollPos;
+
+                    r.width= d.x;
+                    int lines= endLine - startLine;
+
+                    r.height= JFaceTextUtil.computeLineHeight(styledText, startLine, endLine + 1, (lines+1));
+
+                    if (r.y < d.y && annotationAccessExtension !is null)  // annotation within visible area
+                        annotationAccessExtension.paint(annotation, gc, fCanvas, r);
+                    else if (annotationPresentation !is null)
+                        annotationPresentation.paint(gc, fCanvas, r);
+
+                } catch (BadLocationException e) {
+                }
+            }
+        }
+    }
+
+    /**
+     * Draws the vertical ruler w/o drawing the Canvas background. Uses
+     * <code>ITextViewerExtension5</code> for its implementation. Will replace
+     * <code>doPaint(GC)</code>.
+     *
+     * @param gc  the GC to draw into
+     */
+    protected void doPaint1(GC gc) {
+
+        if (fModel is null || fTextViewer is null)
+            return;
+
+        IAnnotationAccessExtension annotationAccessExtension= null;
+        if ( cast(IAnnotationAccessExtension)fAnnotationAccess )
+            annotationAccessExtension= cast(IAnnotationAccessExtension) fAnnotationAccess;
+
+        ITextViewerExtension5 extension= cast(ITextViewerExtension5) fTextViewer;
+        StyledText textWidget= fTextViewer.getTextWidget();
+
+        fScrollPos= textWidget.getTopPixel();
+        Point dimension= fCanvas.getSize();
+
+        // draw Annotations
+        Rectangle r= new Rectangle(0, 0, 0, 0);
+        int maxLayer= 1;    // loop at least once through layers.
+
+        for (int layer= 0; layer < maxLayer; layer++) {
+            Iterator iter= fModel.getAnnotationIterator();
+            while (iter.hasNext()) {
+                IAnnotationPresentation annotationPresentation= null;
+                Annotation annotation= cast(Annotation) iter.next();
+
+                int lay= IAnnotationAccessExtension.DEFAULT_LAYER;
+                if (annotationAccessExtension !is null)
+                    lay= annotationAccessExtension.getLayer(annotation);
+                else if ( cast(IAnnotationPresentation)annotation ) {
+                    annotationPresentation= cast(IAnnotationPresentation)annotation;
+                    lay= annotationPresentation.getLayer();
+                }
+                maxLayer= Math.max(maxLayer, lay+1);    // dynamically update layer maximum
+                if (lay !is layer)   // wrong layer: skip annotation
+                    continue;
+
+                Position position= fModel.getPosition(annotation);
+                if (position is null)
+                    continue;
+
+                IRegion widgetRegion= extension.modelRange2WidgetRange(new Region(position.getOffset(), position.getLength()));
+                if (widgetRegion is null)
+                    continue;
+
+                int startLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset());
+                if (startLine is -1)
+                    continue;
+
+                int endLine= extension.widgetLineOfWidgetOffset(widgetRegion.getOffset() + Math.max(widgetRegion.getLength() -1, 0));
+                if (endLine is -1)
+                    continue;
+
+                r.x= 0;
+                r.y= JFaceTextUtil.computeLineHeight(textWidget, 0, startLine, startLine)  - fScrollPos;
+
+                r.width= dimension.x;
+                int lines= endLine - startLine;
+
+                r.height= JFaceTextUtil.computeLineHeight(textWidget, startLine, endLine + 1, lines+1);
+
+                if (r.y < dimension.y && annotationAccessExtension !is null)  // annotation within visible area
+                    annotationAccessExtension.paint(annotation, gc, fCanvas, r);
+                else if (annotationPresentation !is null)
+                    annotationPresentation.paint(gc, fCanvas, r);
+            }
+        }
+    }
+
+    /**
+     * Thread-safe implementation.
+     * Can be called from any thread.
+     */
+    /*
+     * @see IVerticalRuler#update()
+     */
+    public void update() {
+        if (fCanvas !is null && !fCanvas.isDisposed()) {
+            Display d= fCanvas.getDisplay();
+            if (d !is null) {
+                d.asyncExec(new class()  Runnable {
+                    public void run() {
+                        redraw();
+                    }
+                });
+            }
+        }
+    }
+
+    /**
+     * Redraws the vertical ruler.
+     */
+    private void redraw() {
+        if (fCanvas !is null && !fCanvas.isDisposed()) {
+            GC gc= new GC(fCanvas);
+            doubleBufferPaint(gc);
+            gc.dispose();
+        }
+    }
+
+    /*
+     * @see IVerticalRuler#setModel(IAnnotationModel)
+     */
+    public void setModel(IAnnotationModel model) {
+        if (model !is fModel) {
+
+            if (fModel !is null)
+                fModel.removeAnnotationModelListener(fInternalListener);
+
+            fModel= model;
+
+            if (fModel !is null)
+                fModel.addAnnotationModelListener(fInternalListener);
+
+            update();
+        }
+    }
+
+    /*
+     * @see IVerticalRuler#getModel()
+     */
+    public IAnnotationModel getModel() {
+        return fModel;
+    }
+
+    /*
+     * @see IVerticalRulerInfo#getWidth()
+     */
+    public int getWidth() {
+        return fWidth;
+    }
+
+    /*
+     * @see IVerticalRulerInfo#getLineOfLastMouseButtonActivity()
+     */
+    public int getLineOfLastMouseButtonActivity() {
+        IDocument doc= fTextViewer.getDocument();
+        if (doc is null || fLastMouseButtonActivityLine >= fTextViewer.getDocument().getNumberOfLines())
+            fLastMouseButtonActivityLine= -1;
+        return fLastMouseButtonActivityLine;
+    }
+
+    /*
+     * @see IVerticalRulerInfo#toDocumentLineNumber(int)
+     */
+    public int toDocumentLineNumber(int y_coordinate) {
+        if (fTextViewer is null  || y_coordinate is -1)
+            return -1;
+
+        StyledText text= fTextViewer.getTextWidget();
+        int line= text.getLineIndex(y_coordinate);
+
+        if (line is text.getLineCount() - 1) {
+            // check whether y_coordinate exceeds last line
+            if (y_coordinate > text.getLinePixel(line + 1))
+                return -1;
+        }
+
+        return widgetLine2ModelLine(fTextViewer, line);
+    }
+
+    /**
+     * Returns the line of the viewer's document that corresponds to the given widget line.
+     *
+     * @param viewer the viewer
+     * @param widgetLine the widget line
+     * @return the corresponding line of the viewer's document
+     * @since 2.1
+     */
+    protected final static int widgetLine2ModelLine(ITextViewer viewer, int widgetLine) {
+
+        if ( cast(ITextViewerExtension5)viewer ) {
+            ITextViewerExtension5 extension= cast(ITextViewerExtension5) viewer;
+            return extension.widgetLine2ModelLine(widgetLine);
+        }
+
+        try {
+            IRegion r= viewer.getVisibleRegion();
+            IDocument d= viewer.getDocument();
+            return widgetLine += d.getLineOfOffset(r.getOffset());
+        } catch (BadLocationException x) {
+        }
+        return widgetLine;
+    }
+
+    /*
+     * @see IVerticalRulerExtension#setFont(Font)
+     * @since 2.0
+     */
+    public void setFont(Font font) {
+    }
+
+    /*
+     * @see IVerticalRulerExtension#setLocationOfLastMouseButtonActivity(int, int)
+     * @since 2.0
+     */
+    public void setLocationOfLastMouseButtonActivity(int x, int y) {
+        fLastMouseButtonActivityLine= toDocumentLineNumber(y);
+    }
+
+    /**
+     * Adds the given mouse listener.
+     *
+     * @param listener the listener to be added
+     * @deprecated will be removed
+     * @since 2.0
+     */
+    public void addMouseListener(MouseListener listener) {
+        if (fCanvas !is null && !fCanvas.isDisposed())
+            fCanvas.addMouseListener(listener);
+    }
+
+    /**
+     * Removes the given mouse listener.
+     *
+     * @param listener the listener to be removed
+     * @deprecated will be removed
+     * @since 2.0
+     */
+    public void removeMouseListener(MouseListener listener) {
+        if (fCanvas !is null && !fCanvas.isDisposed())
+            fCanvas.removeMouseListener(listener);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/VerticalRulerEvent.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.VerticalRulerEvent;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.VisualAnnotationModel; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * An event sent to {@link dwtx.jface.text.source.IVerticalRulerListener} instances when annotation
+ * related event occurs on the vertical ruler.
+ *
+ * @since 3.0
+ */
+public class VerticalRulerEvent {
+
+    private Annotation fAnnotation;
+
+    /**
+     * Creates a new event.
+     *
+     * @param annotation the annotation concerned, or <code>null</code>
+     */
+    public this(Annotation annotation) {
+        fAnnotation= annotation;
+    }
+
+    /**
+     * @return the concerned annotation or <code>null</code>
+     */
+    public Annotation getSelectedAnnotation() {
+        return fAnnotation;
+    }
+
+    /**
+     * @param annotation the concerned annotation, or <code>null</code>
+     */
+    public void setSelectedAnnotation(Annotation annotation) {
+        fAnnotation= annotation;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/VisualAnnotationModel.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,211 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.VisualAnnotationModel;
+
+import dwtx.jface.text.source.ISharedTextColors; // packageimport
+import dwtx.jface.text.source.ILineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationPresentation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfoExtension; // packageimport
+import dwtx.jface.text.source.ICharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.TextInvocationContext; // packageimport
+import dwtx.jface.text.source.LineChangeHover; // packageimport
+import dwtx.jface.text.source.IChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationMap; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListenerExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationHover; // packageimport
+import dwtx.jface.text.source.ContentAssistantFacade; // packageimport
+import dwtx.jface.text.source.IAnnotationAccess; // packageimport
+import dwtx.jface.text.source.IVerticalRulerExtension; // packageimport
+import dwtx.jface.text.source.IVerticalRulerColumn; // packageimport
+import dwtx.jface.text.source.LineNumberRulerColumn; // packageimport
+import dwtx.jface.text.source.MatchingCharacterPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension; // packageimport
+import dwtx.jface.text.source.DefaultCharacterPairMatcher; // packageimport
+import dwtx.jface.text.source.LineNumberChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension; // packageimport
+import dwtx.jface.text.source.ISourceViewer; // packageimport
+import dwtx.jface.text.source.AnnotationModel; // packageimport
+import dwtx.jface.text.source.ILineDifferExtension2; // packageimport
+import dwtx.jface.text.source.IAnnotationModelListener; // packageimport
+import dwtx.jface.text.source.IVerticalRuler; // packageimport
+import dwtx.jface.text.source.DefaultAnnotationHover; // packageimport
+import dwtx.jface.text.source.SourceViewer; // packageimport
+import dwtx.jface.text.source.SourceViewerConfiguration; // packageimport
+import dwtx.jface.text.source.AnnotationBarHoverManager; // packageimport
+import dwtx.jface.text.source.CompositeRuler; // packageimport
+import dwtx.jface.text.source.ImageUtilities; // packageimport
+import dwtx.jface.text.source.IAnnotationModel; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension3; // packageimport
+import dwtx.jface.text.source.ILineDiffInfo; // packageimport
+import dwtx.jface.text.source.VerticalRulerEvent; // packageimport
+import dwtx.jface.text.source.ChangeRulerColumn; // packageimport
+import dwtx.jface.text.source.ILineDiffer; // packageimport
+import dwtx.jface.text.source.AnnotationModelEvent; // packageimport
+import dwtx.jface.text.source.AnnotationColumn; // packageimport
+import dwtx.jface.text.source.AnnotationRulerColumn; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension; // packageimport
+import dwtx.jface.text.source.AbstractRulerColumn; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension; // packageimport
+import dwtx.jface.text.source.AnnotationMap; // packageimport
+import dwtx.jface.text.source.IVerticalRulerInfo; // packageimport
+import dwtx.jface.text.source.IAnnotationModelExtension2; // packageimport
+import dwtx.jface.text.source.LineRange; // packageimport
+import dwtx.jface.text.source.IAnnotationAccessExtension2; // packageimport
+import dwtx.jface.text.source.VerticalRuler; // packageimport
+import dwtx.jface.text.source.JFaceTextMessages; // packageimport
+import dwtx.jface.text.source.IOverviewRuler; // packageimport
+import dwtx.jface.text.source.Annotation; // packageimport
+import dwtx.jface.text.source.IVerticalRulerListener; // packageimport
+import dwtx.jface.text.source.ISourceViewerExtension4; // packageimport
+import dwtx.jface.text.source.AnnotationPainter; // packageimport
+import dwtx.jface.text.source.IAnnotationHoverExtension2; // packageimport
+import dwtx.jface.text.source.OverviewRuler; // packageimport
+import dwtx.jface.text.source.OverviewRulerHoverManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.Position;
+
+
+
+/**
+ * Annotation model for visual annotations. Assume a viewer's input element is annotated with
+ * some semantic annotation such as a breakpoint and that it is simultaneously shown in multiple
+ * viewers. A source viewer, e.g., supports visual range indication for which it utilizes
+ * annotations. The range indicating annotation is specific to the visual presentation
+ * of the input element in this viewer and thus should only be visible in this viewer. The
+ * breakpoints however are independent from the input element's presentation and thus should
+ * be shown in all viewers in which the element is shown. As a viewer supports one vertical
+ * ruler which is based on one annotation model, there must be a visual annotation model for
+ * each viewer which all wrap the same element specific model annotation model.
+ */
+class VisualAnnotationModel : AnnotationModel , IAnnotationModelListener {
+
+    /** The wrapped model annotation model */
+    private IAnnotationModel fModel;
+
+    /**
+     * Constructs a visual annotation model which wraps the given
+     * model based annotation model
+     *
+     * @param modelAnnotationModel the model based annotation model
+     */
+    public this(IAnnotationModel modelAnnotationModel) {
+        fModel= modelAnnotationModel;
+    }
+
+    /**
+     * Returns the visual annotation model's wrapped model based annotation model.
+     *
+     * @return the model based annotation model
+     */
+    public IAnnotationModel getModelAnnotationModel() {
+        return fModel;
+    }
+
+    /*
+     * @see IAnnotationModel#addAnnotationModelListener(IAnnotationModelListener)
+     */
+    public void addAnnotationModelListener(IAnnotationModelListener listener) {
+
+        if (fModel !is null && fAnnotationModelListeners.isEmpty())
+            fModel.addAnnotationModelListener(this);
+
+        super.addAnnotationModelListener(listener);
+    }
+
+    /*
+     * @see IAnnotationModel#connect(IDocument)
+     */
+    public void connect(IDocument document) {
+        super.connect(document);
+        if (fModel !is null)
+            fModel.connect(document);
+    }
+
+    /*
+     * @see IAnnotationModel#disconnect(IDocument)
+     */
+    public void disconnect(IDocument document) {
+        super.disconnect(document);
+        if (fModel !is null)
+            fModel.disconnect(document);
+    }
+
+    /*
+     * @see IAnnotationModel#getAnnotationIterator()
+     */
+    public Iterator getAnnotationIterator() {
+
+        if (fModel is null)
+            return super.getAnnotationIterator();
+
+        ArrayList a= new ArrayList(20);
+
+        Iterator e= fModel.getAnnotationIterator();
+        while (e.hasNext())
+            a.add(e.next());
+
+        e= super.getAnnotationIterator();
+        while (e.hasNext())
+            a.add(e.next());
+
+        return a.iterator();
+    }
+
+    /*
+     * @see IAnnotationModel#getPosition(Annotation)
+     */
+    public Position getPosition(Annotation annotation) {
+
+        Position p= cast(Position) getAnnotationMap().get(annotation);
+        if (p !is null)
+            return p;
+
+        if (fModel !is null)
+            return fModel.getPosition(annotation);
+
+        return null;
+    }
+
+    /*
+     * @see IAnnotationModelListener#modelChanged(IAnnotationModel)
+     */
+    public void modelChanged(IAnnotationModel model) {
+        if (model is fModel) {
+            Iterator iter= (new ArrayList(fAnnotationModelListeners)).iterator();
+            while (iter.hasNext()) {
+                IAnnotationModelListener l= cast(IAnnotationModelListener)iter.next();
+                l.modelChanged(this);
+            }
+        }
+    }
+
+    /*
+     * @see IAnnotationModel#removeAnnotationModelListener(IAnnotationModelListener)
+     */
+    public void removeAnnotationModelListener(IAnnotationModelListener listener) {
+        super.removeAnnotationModelListener(listener);
+
+        if (fModel !is null && fAnnotationModelListeners.isEmpty())
+            fModel.removeAnnotationModelListener(this);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/projection/AnnotationBag.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.projection.AnnotationBag;
+
+import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport
+import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport
+import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport
+import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport
+import dwtx.jface.text.source.projection.IProjectionListener; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+import dwtx.jface.text.source.Annotation;
+
+/**
+ * A bag of annotations.
+ * <p>
+ * This class is not intended to be subclassed.
+ * </p>
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class AnnotationBag : Annotation {
+
+    private Set fAnnotations;
+
+    /**
+     * Creates a new annotation bag.
+     *
+     * @param type the annotation type
+     */
+    public this(String type) {
+        super(type, false, null);
+    }
+
+    /**
+     * Adds the given annotation to the annotation bag.
+     *
+     * @param annotation the annotation to add
+     */
+    public void add(Annotation annotation) {
+        if (fAnnotations is null)
+            fAnnotations= new HashSet(2);
+        fAnnotations.add(annotation);
+    }
+
+    /**
+     * Removes the given annotation from the annotation bag.
+     *
+     * @param annotation the annotation to remove
+     */
+    public void remove(Annotation annotation) {
+        if (fAnnotations !is null) {
+            fAnnotations.remove(annotation);
+            if (fAnnotations.isEmpty())
+                fAnnotations= null;
+        }
+    }
+
+    /**
+     * Returns whether the annotation bag is empty.
+     *
+     * @return <code>true</code> if the annotation bag is empty, <code>false</code> otherwise
+     */
+    public bool isEmpty() {
+        return fAnnotations is null;
+    }
+
+    /**
+     * Returns an iterator for all annotation inside this
+     * annotation bag or <code>null</code> if the bag is empty.
+     *
+     * @return an iterator for all annotations in the bag or <code>null</code>
+     * @since 3.1
+     */
+    public Iterator iterator() {
+        if (!isEmpty())
+            return fAnnotations.iterator();
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/projection/IProjectionListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.projection.IProjectionListener;
+
+import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport
+import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport
+import dwtx.jface.text.source.projection.AnnotationBag; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport
+import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport
+import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Implementers registered with a
+ * {@link dwtx.jface.text.source.projection.ProjectionViewer} get
+ * informed when the projection mode of the viewer gets enabled and when it gets
+ * disabled.
+ *
+ * @since 3.0
+ */
+public interface IProjectionListener {
+
+    /**
+     * Tells this listener that projection has been enabled.
+     */
+    void projectionEnabled();
+
+    /**
+     * Tells this listener that projection has been disabled.
+     */
+    void projectionDisabled();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/projection/IProjectionPosition.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.projection.IProjectionPosition;
+
+import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport
+import dwtx.jface.text.source.projection.AnnotationBag; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport
+import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport
+import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport
+import dwtx.jface.text.source.projection.IProjectionListener; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+
+
+/**
+ * An <code>IProjectionPosition</code> is a position that is associated with a
+ * <code>ProjectionAnnotation</code> and that is able to compute its collapsed
+ * regions. That is, if a <code>Position</code> implements this interface,
+ * <code>ProjectionViewer</code> will delegate to the
+ * {@link #computeProjectionRegions(IDocument) computeProjectionRegions} method
+ * when determining the document regions that should be collapsed for a certain
+ * <code>ProjectionAnnotation</code>.
+ *
+ * @since 3.1
+ */
+public interface IProjectionPosition {
+
+    /**
+     * Returns an array of regions that should be collapsed when the annotation
+     * belonging to this position is collapsed. May return null instead of
+     * an empty array.
+     *
+     * @param document the document that this position is attached to
+     * @return the foldable regions for this position
+     * @throws BadLocationException if accessing the document fails
+     */
+    IRegion[] computeProjectionRegions(IDocument document) ;
+
+    /**
+     * Returns the offset of the caption (the anchor region) of this projection
+     * position. The returned offset is relative to the receivers offset into
+     * the document.
+     *
+     * @param document the document that this position is attached to
+     * @return the caption offset relative to the position's offset
+     * @throws BadLocationException if accessing the document fails
+     */
+    int computeCaptionOffset(IDocument document) ;
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/projection/ProjectionAnnotation.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,191 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.projection.ProjectionAnnotation;
+
+import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport
+import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport
+import dwtx.jface.text.source.projection.AnnotationBag; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport
+import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport
+import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport
+import dwtx.jface.text.source.projection.IProjectionListener; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+import dwt.DWT;
+import dwt.graphics.FontMetrics;
+import dwt.graphics.GC;
+import dwt.graphics.Image;
+import dwt.graphics.Rectangle;
+import dwt.widgets.Canvas;
+import dwt.widgets.Display;
+import dwtx.jface.resource.ImageDescriptor;
+import dwtx.jface.text.source.Annotation;
+import dwtx.jface.text.source.IAnnotationPresentation;
+import dwtx.jface.text.source.ImageUtilities;
+
+/**
+ * Annotation used to represent the projection of a master document onto a
+ * {@link dwtx.jface.text.projection.ProjectionDocument}. A projection
+ * annotation can be either expanded or collapsed. If expanded it corresponds to
+ * a segment of the projection document. If collapsed, it represents a region of
+ * the master document that does not have a corresponding segment in the
+ * projection document.
+ * <p>
+ * Clients may subclass or use as is.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class ProjectionAnnotation : Annotation , IAnnotationPresentation {
+
+    private static class DisplayDisposeRunnable : Runnable {
+
+        public void run() {
+            if (fgCollapsedImage !is null) {
+                fgCollapsedImage.dispose();
+                fgCollapsedImage= null;
+            }
+            if (fgExpandedImage !is null) {
+                fgExpandedImage.dispose();
+                fgExpandedImage= null;
+            }
+        }
+    }
+
+    /**
+     * The type of projection annotations.
+     */
+    public static const String TYPE= "dwtx.projection"; //$NON-NLS-1$
+
+
+    private static const int COLOR= DWT.COLOR_GRAY;
+    private static Image fgCollapsedImage;
+    private static Image fgExpandedImage;
+
+
+    /** The state of this annotation */
+    private bool fIsCollapsed= false;
+    /** Indicates whether this annotation should be painted as range */
+    private bool fIsRangeIndication= false;
+
+    /**
+     * Creates a new expanded projection annotation.
+     */
+    public this() {
+        this(false);
+    }
+
+    /**
+     * Creates a new projection annotation. When <code>isCollapsed</code>
+     * is <code>true</code> the annotation is initially collapsed.
+     *
+     * @param isCollapsed <code>true</code> if the annotation should initially be collapsed, <code>false</code> otherwise
+     */
+    public this(bool isCollapsed) {
+        super(TYPE, false, null);
+        fIsCollapsed= isCollapsed;
+    }
+
+    /**
+     * Enables and disables the range indication for this annotation.
+     *
+     * @param rangeIndication the enable state for the range indication
+     */
+    public void setRangeIndication(bool rangeIndication) {
+        fIsRangeIndication= rangeIndication;
+    }
+
+    private void drawRangeIndication(GC gc, Canvas canvas, Rectangle r) {
+        final int MARGIN= 3;
+
+        /* cap the height - at least on GTK, large numbers are converted to
+         * negatives at some point */
+        int height= Math.min(r.y + r.height - MARGIN, canvas.getSize().y);
+
+        gc.setForeground(canvas.getDisplay().getSystemColor(COLOR));
+        gc.setLineWidth(0); // NOTE: 0 means width is 1 but with optimized performance
+        gc.drawLine(r.x + 4, r.y + 12, r.x + 4, height);
+        gc.drawLine(r.x + 4, height, r.x + r.width - MARGIN, height);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationPresentation#paint(dwt.graphics.GC, dwt.widgets.Canvas, dwt.graphics.Rectangle)
+     */
+    public void paint(GC gc, Canvas canvas, Rectangle rectangle) {
+        Image image= getImage(canvas.getDisplay());
+        if (image !is null) {
+            ImageUtilities.drawImage(image, gc, canvas, rectangle, DWT.CENTER, DWT.TOP);
+            if (fIsRangeIndication) {
+                FontMetrics fontMetrics= gc.getFontMetrics();
+                int delta= (fontMetrics.getHeight() - image.getBounds().height)/2;
+                rectangle.y += delta;
+                rectangle.height -= delta;
+                drawRangeIndication(gc, canvas, rectangle);
+            }
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationPresentation#getLayer()
+     */
+    public int getLayer() {
+        return IAnnotationPresentation.DEFAULT_LAYER;
+    }
+
+    private Image getImage(Display display) {
+        initializeImages(display);
+        return isCollapsed() ? fgCollapsedImage : fgExpandedImage;
+    }
+
+    private void initializeImages(Display display) {
+        if (fgCollapsedImage is null) {
+            ImageDescriptor descriptor= ImageDescriptor.createFromFile( getImportData!("dwtx.jface.text.source.projection.collapsed.gif")); //$NON-NLS-1$
+            fgCollapsedImage= descriptor.createImage(display);
+            descriptor= ImageDescriptor.createFromFile( getImportData!( "dwtx.jface.text.source.projection.expanded.gif")); //$NON-NLS-1$
+            fgExpandedImage= descriptor.createImage(display);
+
+            display.disposeExec(new DisplayDisposeRunnable());
+        }
+    }
+
+    /**
+     * Returns the state of this annotation.
+     *
+     * @return <code>true</code> if collapsed
+     */
+    public bool isCollapsed() {
+        return fIsCollapsed;
+    }
+
+    /**
+     * Marks this annotation as being collapsed.
+     */
+    public void markCollapsed() {
+        fIsCollapsed= true;
+    }
+
+    /**
+     * Marks this annotation as being unfolded.
+     */
+    public void markExpanded() {
+        fIsCollapsed= false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/projection/ProjectionAnnotationHover.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,204 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.projection.ProjectionAnnotationHover;
+
+import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport
+import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport
+import dwtx.jface.text.source.projection.AnnotationBag; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport
+import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport
+import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport
+import dwtx.jface.text.source.projection.IProjectionListener; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+import dwt.widgets.Shell;
+import dwtx.jface.resource.JFaceResources;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.information.IInformationProviderExtension2;
+import dwtx.jface.text.source.IAnnotationHover;
+import dwtx.jface.text.source.IAnnotationHoverExtension;
+import dwtx.jface.text.source.IAnnotationModel;
+import dwtx.jface.text.source.IAnnotationModelExtension;
+import dwtx.jface.text.source.ILineRange;
+import dwtx.jface.text.source.ISourceViewer;
+import dwtx.jface.text.source.ISourceViewerExtension2;
+import dwtx.jface.text.source.LineRange;
+
+/**
+ * Annotation hover for projection annotations.
+ *
+ * @since 3.0
+ */
+class ProjectionAnnotationHover : IAnnotationHover, IAnnotationHoverExtension, IInformationProviderExtension2 {
+
+
+    private IInformationControlCreator fInformationControlCreator;
+    private IInformationControlCreator fInformationPresenterControlCreator;
+
+    /**
+     * Sets the hover control creator for this projection annotation hover.
+     *
+     * @param creator the creator
+     */
+    public void setHoverControlCreator(IInformationControlCreator creator) {
+        fInformationControlCreator= creator;
+    }
+
+    /**
+     * Sets the information presenter control creator for this projection annotation hover.
+     *
+     * @param creator the creator
+     * @since 3.3
+     */
+    public void setInformationPresenterControlCreator(IInformationControlCreator creator) {
+        fInformationPresenterControlCreator= creator;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationHover#getHoverInfo(dwtx.jface.text.source.ISourceViewer, int)
+     */
+    public String getHoverInfo(ISourceViewer sourceViewer, int lineNumber) {
+        // this is a no-op as semantics is defined by the implementation of the annotation hover extension
+        return null;
+    }
+
+    /*
+     * @since 3.1
+     */
+    private bool isCaptionLine(ProjectionAnnotation annotation, Position position, IDocument document, int line) {
+        if (position.getOffset() > -1 && position.getLength() > -1) {
+            try {
+                int captionOffset;
+                if ( cast(IProjectionPosition)position )
+                    captionOffset= (cast(IProjectionPosition) position).computeCaptionOffset(document);
+                else
+                    captionOffset= 0;
+                int startLine= document.getLineOfOffset(position.getOffset() + captionOffset);
+                return line is startLine;
+            } catch (BadLocationException x) {
+            }
+        }
+        return false;
+    }
+
+    private String getProjectionTextAtLine(ISourceViewer viewer, int line, int numberOfLines) {
+
+        IAnnotationModel model= null;
+        if ( cast(ISourceViewerExtension2)viewer ) {
+            ISourceViewerExtension2 viewerExtension= cast(ISourceViewerExtension2) viewer;
+            IAnnotationModel visual= viewerExtension.getVisualAnnotationModel();
+            if ( cast(IAnnotationModelExtension)visual ) {
+                IAnnotationModelExtension modelExtension= cast(IAnnotationModelExtension) visual;
+                model= modelExtension.getAnnotationModel(ProjectionSupport.PROJECTION);
+            }
+        }
+
+        if (model !is null) {
+            try {
+                IDocument document= viewer.getDocument();
+                Iterator e= model.getAnnotationIterator();
+                while (e.hasNext()) {
+                    ProjectionAnnotation annotation= cast(ProjectionAnnotation) e.next();
+                    if (!annotation.isCollapsed())
+                        continue;
+
+                    Position position= model.getPosition(annotation);
+                    if (position is null)
+                        continue;
+
+                    if (isCaptionLine(annotation, position, document, line))
+                        return getText(document, position.getOffset(), position.getLength(), numberOfLines);
+
+                }
+            } catch (BadLocationException x) {
+            }
+        }
+
+        return null;
+    }
+
+    private String getText(IDocument document, int offset, int length, int numberOfLines)  {
+        int endOffset= offset + length;
+
+        try {
+            int endLine= document.getLineOfOffset(offset) + Math.max(0, numberOfLines -1);
+            IRegion lineInfo= document.getLineInformation(endLine);
+            endOffset= Math.min(endOffset, lineInfo.getOffset() + lineInfo.getLength());
+        } catch (BadLocationException x) {
+        }
+
+        return document.get(offset, endOffset - offset);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverInfo(dwtx.jface.text.source.ISourceViewer, dwtx.jface.text.source.ILineRange, int)
+     */
+    public Object getHoverInfo(ISourceViewer sourceViewer, ILineRange lineRange, int visibleLines) {
+        return stringcast(getProjectionTextAtLine(sourceViewer, lineRange.getStartLine(), visibleLines));
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverLineRange(dwtx.jface.text.source.ISourceViewer, int)
+     */
+    public ILineRange getHoverLineRange(ISourceViewer viewer, int lineNumber) {
+        return new LineRange(lineNumber, 1);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationHoverExtension#canHandleMouseCursor()
+     */
+    public bool canHandleMouseCursor() {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IAnnotationHoverExtension#getHoverControlCreator()
+     */
+    public IInformationControlCreator getHoverControlCreator() {
+        if (fInformationControlCreator is null) {
+            fInformationControlCreator= new class()  IInformationControlCreator {
+                public IInformationControl createInformationControl(Shell parent) {
+                    return new SourceViewerInformationControl(parent, false, JFaceResources.TEXT_FONT, null);
+                }
+            };
+        }
+        return fInformationControlCreator;
+    }
+
+    /*
+     * @see dwtx.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator()
+     * @since 3.3
+     */
+    public IInformationControlCreator getInformationPresenterControlCreator() {
+        if (fInformationPresenterControlCreator is null) {
+            fInformationPresenterControlCreator= new class()  IInformationControlCreator {
+                public IInformationControl createInformationControl(Shell parent) {
+                    return new SourceViewerInformationControl(parent, true, JFaceResources.TEXT_FONT, null);
+                }
+            };
+        }
+        return fInformationPresenterControlCreator;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/projection/ProjectionAnnotationModel.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,202 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.projection.ProjectionAnnotationModel;
+
+import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport
+import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport
+import dwtx.jface.text.source.projection.AnnotationBag; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport
+import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport
+import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport
+import dwtx.jface.text.source.projection.IProjectionListener; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.source.Annotation;
+import dwtx.jface.text.source.AnnotationModel;
+
+
+/**
+ * A projection annotation model. It provides methods for modifying the
+ * expansion state of the managed projection annotations.
+ * <p>
+ * Do not subclass. Use it as is.
+ * </p>
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ProjectionAnnotationModel : AnnotationModel {
+
+
+    /**
+     * Creates a new, empty projection annotation model.
+     */
+    public this() {
+    }
+
+    /**
+     * Changes the state of the given annotation to collapsed. An appropriate
+     * annotation model change event is sent out.
+     *
+     * @param annotation the annotation
+     */
+    public void collapse(Annotation annotation) {
+        if ( cast(ProjectionAnnotation)annotation ) {
+            ProjectionAnnotation projection= cast(ProjectionAnnotation) annotation;
+            if (!projection.isCollapsed()) {
+                projection.markCollapsed();
+                modifyAnnotation(projection, true);
+            }
+        }
+    }
+
+    /**
+     * Changes the state of the given annotation to expanded. An appropriate
+     * annotation model change event is sent out.
+     *
+     * @param annotation the annotation
+     */
+    public void expand(Annotation annotation) {
+        if ( cast(ProjectionAnnotation)annotation ) {
+            ProjectionAnnotation projection= cast(ProjectionAnnotation) annotation;
+            if (projection.isCollapsed()) {
+                projection.markExpanded();
+                modifyAnnotation(projection, true);
+            }
+        }
+    }
+
+    /**
+     * Toggles the expansion state of the given annotation. An appropriate
+     * annotation model change event is sent out.
+     *
+     * @param annotation the annotation
+     */
+    public void toggleExpansionState(Annotation annotation) {
+        if ( cast(ProjectionAnnotation)annotation ) {
+            ProjectionAnnotation projection= cast(ProjectionAnnotation) annotation;
+
+            if (projection.isCollapsed())
+                projection.markExpanded();
+            else
+                projection.markCollapsed();
+
+            modifyAnnotation(projection, true);
+        }
+    }
+
+    /**
+     * Expands all annotations that overlap with the given range and are collapsed.
+     *
+     * @param offset the range offset
+     * @param length the range length
+     * @return <code>true</code> if any annotation has been expanded, <code>false</code> otherwise
+     */
+    public bool expandAll(int offset, int length) {
+        return expandAll(offset, length, true);
+    }
+
+    /**
+     * Collapses all annotations that overlap with the given range and are collapsed.
+     *
+     * @param offset the range offset
+     * @param length the range length
+     * @return <code>true</code> if any annotation has been collapse, <code>false</code>
+     *         otherwise
+     * @since 3.2
+     */
+    public bool collapseAll(int offset, int length) {
+
+        bool collapsing= false;
+
+        Iterator iterator= getAnnotationIterator();
+        while (iterator.hasNext()) {
+            ProjectionAnnotation annotation= cast(ProjectionAnnotation) iterator.next();
+            if (!annotation.isCollapsed()) {
+                Position position= getPosition(annotation);
+                if (position !is null && position.overlapsWith(offset, length) /* || is a delete at the boundary */ ) {
+                    annotation.markCollapsed();
+                    modifyAnnotation(annotation, false);
+                    collapsing= true;
+                }
+            }
+        }
+
+        if (collapsing)
+            fireModelChanged();
+
+        return collapsing;
+    }
+
+    /**
+     * Expands all annotations that overlap with the given range and are collapsed. Fires a model change event if
+     * requested.
+     *
+     * @param offset the offset of the range
+     * @param length the length of the range
+     * @param fireModelChanged <code>true</code> if a model change event
+     *            should be fired, <code>false</code> otherwise
+     * @return <code>true</code> if any annotation has been expanded, <code>false</code> otherwise
+     */
+    protected bool expandAll(int offset, int length, bool fireModelChanged_) {
+
+        bool expanding= false;
+
+        Iterator iterator= getAnnotationIterator();
+        while (iterator.hasNext()) {
+            ProjectionAnnotation annotation= cast(ProjectionAnnotation) iterator.next();
+            if (annotation.isCollapsed()) {
+                Position position= getPosition(annotation);
+                if (position !is null && position.overlapsWith(offset, length) /* || is a delete at the boundary */ ) {
+                    annotation.markExpanded();
+                    modifyAnnotation(annotation, false);
+                    expanding= true;
+                }
+            }
+        }
+
+        if (expanding && fireModelChanged_)
+            fireModelChanged();
+
+        return expanding;
+    }
+
+    /**
+     * Modifies the annotation model.
+     *
+     * @param deletions the list of deleted annotations
+     * @param additions the set of annotations to add together with their associated position
+     * @param modifications the list of modified annotations
+     */
+    public void modifyAnnotations(Annotation[] deletions, Map additions, Annotation[] modifications) {
+        try {
+            replaceAnnotations(deletions, additions, false);
+            if (modifications !is null) {
+                for (int i= 0; i < modifications.length; i++)
+                    modifyAnnotation(modifications[i], false);
+            }
+        } catch (BadLocationException x) {
+        }
+        fireModelChanged();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/projection/ProjectionRulerColumn.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,249 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.projection.ProjectionRulerColumn;
+
+import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport
+import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport
+import dwtx.jface.text.source.projection.AnnotationBag; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport
+import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport
+import dwtx.jface.text.source.projection.IProjectionListener; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.dwtxhelper.Collection;
+
+import dwt.DWT;
+import dwt.events.MouseEvent;
+import dwt.events.MouseMoveListener;
+import dwt.events.MouseTrackAdapter;
+import dwt.graphics.Color;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.source.AnnotationRulerColumn;
+import dwtx.jface.text.source.CompositeRuler;
+import dwtx.jface.text.source.IAnnotationAccess;
+import dwtx.jface.text.source.IAnnotationModel;
+import dwtx.jface.text.source.IAnnotationModelExtension;
+
+
+/**
+ * A ruler column for controlling the behavior of a
+ * {@link dwtx.jface.text.source.projection.ProjectionViewer}.
+ *
+ * @since 3.0
+ */
+class ProjectionRulerColumn : AnnotationRulerColumn {
+
+    private ProjectionAnnotation fCurrentAnnotation;
+
+    /**
+     * Creates a new projection ruler column.
+     *
+     * @param model the column's annotation model
+     * @param width the width in pixels
+     * @param annotationAccess the annotation access
+     */
+    public this(IAnnotationModel model, int width, IAnnotationAccess annotationAccess) {
+        super(model, width, annotationAccess);
+    }
+
+    /**
+     * Creates a new projection ruler column.
+     *
+     * @param width the width in pixels
+     * @param annotationAccess the annotation access
+     */
+    public this(int width, IAnnotationAccess annotationAccess) {
+        super(width, annotationAccess);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.AnnotationRulerColumn#mouseClicked(int)
+     */
+    protected void mouseClicked(int line) {
+        clearCurrentAnnotation();
+        ProjectionAnnotation annotation= findAnnotation(line, true);
+        if (annotation !is null) {
+            ProjectionAnnotationModel model= cast(ProjectionAnnotationModel) getModel();
+            model.toggleExpansionState(annotation);
+        }
+    }
+
+    /**
+     * Returns the projection annotation of the column's annotation
+     * model that contains the given line.
+     *
+     * @param line the line
+     * @param exact <code>true</code> if the annotation range must match exactly
+     * @return the projection annotation containing the given line
+     */
+    private ProjectionAnnotation findAnnotation(int line, bool exact) {
+
+        ProjectionAnnotation previousAnnotation= null;
+
+        IAnnotationModel model= getModel();
+        if (model !is null) {
+            IDocument document= getCachedTextViewer().getDocument();
+
+            int previousDistance= Integer.MAX_VALUE;
+
+            Iterator e= model.getAnnotationIterator();
+            while (e.hasNext()) {
+                Object next= e.next();
+                if ( cast(ProjectionAnnotation)next ) {
+                    ProjectionAnnotation annotation= cast(ProjectionAnnotation) next;
+                    Position p= model.getPosition(annotation);
+                    if (p is null)
+                        continue;
+
+                    int distance= getDistance(annotation, p, document, line);
+                    if (distance is -1)
+                        continue;
+
+                    if (!exact) {
+                        if (distance < previousDistance) {
+                            previousAnnotation= annotation;
+                            previousDistance= distance;
+                        }
+                    } else if (distance is 0) {
+                        previousAnnotation= annotation;
+                    }
+                }
+            }
+        }
+
+        return previousAnnotation;
+    }
+
+    /**
+     * Returns the distance of the given line to the start line of the given position in the given document. The distance is
+     * <code>-1</code> when the line is not included in the given position.
+     *
+     * @param annotation the annotation
+     * @param position the position
+     * @param document the document
+     * @param line the line
+     * @return <code>-1</code> if line is not contained, a position number otherwise
+     */
+    private int getDistance(ProjectionAnnotation annotation, Position position, IDocument document, int line) {
+        if (position.getOffset() > -1 && position.getLength() > -1) {
+            try {
+                int startLine= document.getLineOfOffset(position.getOffset());
+                int endLine= document.getLineOfOffset(position.getOffset() + position.getLength());
+                if (startLine <= line && line < endLine) {
+                    if (annotation.isCollapsed()) {
+                        int captionOffset;
+                        if ( cast(IProjectionPosition)position )
+                            captionOffset= (cast(IProjectionPosition) position).computeCaptionOffset(document);
+                        else
+                            captionOffset= 0;
+
+                        int captionLine= document.getLineOfOffset(position.getOffset() + captionOffset);
+                        if (startLine <= captionLine && captionLine < endLine)
+                            return Math.abs(line - captionLine);
+                    }
+                    return line - startLine;
+                }
+            } catch (BadLocationException x) {
+            }
+        }
+        return -1;
+    }
+
+    private bool clearCurrentAnnotation() {
+        if (fCurrentAnnotation !is null) {
+            fCurrentAnnotation.setRangeIndication(false);
+            fCurrentAnnotation= null;
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.IVerticalRulerColumn#createControl(dwtx.jface.text.source.CompositeRuler, dwt.widgets.Composite)
+     */
+    public Control createControl(CompositeRuler parentRuler, Composite parentControl) {
+        Control control= super.createControl(parentRuler, parentControl);
+
+        // set background
+        Display display= parentControl.getDisplay();
+        Color background= display.getSystemColor(DWT.COLOR_LIST_BACKGROUND);
+        control.setBackground(background);
+
+        // install hover listener
+        control.addMouseTrackListener(new class()  MouseTrackAdapter {
+            public void mouseExit(MouseEvent e) {
+                if (clearCurrentAnnotation())
+                    redraw();
+            }
+        });
+
+        // install mouse move listener
+        control.addMouseMoveListener(new class()  MouseMoveListener {
+            public void mouseMove(MouseEvent e) {
+                bool redraw_= false;
+                ProjectionAnnotation annotation= findAnnotation(toDocumentLineNumber(e.y), false);
+                if (annotation !is fCurrentAnnotation) {
+                    if (fCurrentAnnotation !is null) {
+                        fCurrentAnnotation.setRangeIndication(false);
+                        redraw_= true;
+                    }
+                    fCurrentAnnotation= annotation;
+                    if (fCurrentAnnotation !is null && !fCurrentAnnotation.isCollapsed()) {
+                        fCurrentAnnotation.setRangeIndication(true);
+                        redraw_= true;
+                    }
+                }
+                if (redraw_)
+                    redraw();
+            }
+        });
+        return control;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.AnnotationRulerColumn#setModel(dwtx.jface.text.source.IAnnotationModel)
+     */
+    public void setModel(IAnnotationModel model) {
+        if ( cast(IAnnotationModelExtension)model ) {
+            IAnnotationModelExtension extension= cast(IAnnotationModelExtension) model;
+            model= extension.getAnnotationModel(ProjectionSupport.PROJECTION);
+        }
+        super.setModel(model);
+    }
+
+    /*
+     * @see dwtx.jface.text.source.AnnotationRulerColumn#isPropagatingMouseListener()
+     */
+    protected bool isPropagatingMouseListener() {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.AnnotationRulerColumn#hasAnnotation(int)
+     */
+    protected bool hasAnnotation(int lineNumber) {
+        return findAnnotation(lineNumber, true) !is null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/projection/ProjectionSummary.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,346 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.projection.ProjectionSummary;
+
+import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport
+import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport
+import dwtx.jface.text.source.projection.AnnotationBag; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport
+import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport
+import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport
+import dwtx.jface.text.source.projection.IProjectionListener; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport
+
+
+import dwt.dwthelper.utils;
+import tango.core.Thread;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+import dwtx.core.runtime.IProgressMonitor;
+import dwtx.core.runtime.NullProgressMonitor;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ISynchronizable;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.source.Annotation;
+import dwtx.jface.text.source.IAnnotationAccess;
+import dwtx.jface.text.source.IAnnotationAccessExtension;
+import dwtx.jface.text.source.IAnnotationModel;
+import dwtx.jface.text.source.IAnnotationModelExtension;
+
+
+/**
+ * Strategy for managing annotation summaries for collapsed ranges.
+ *
+ * @since 3.0
+ */
+class ProjectionSummary {
+
+    private class Summarizer {
+
+        Thread thread;
+        private bool fReset= true;
+
+        /**
+         * Creates a new thread.
+         */
+        public this() {
+            thread = new Thread( &run );
+            fProgressMonitor= new NullProgressMonitor(); // might be given by client in the future
+            thread.isDaemon(true);
+            thread.start();
+        }
+
+        /**
+         * Resets the thread.
+         */
+        public void reset() {
+            synchronized (fLock) {
+                fReset= true;
+                fProgressMonitor.setCanceled(true);
+            }
+        }
+
+        /*
+         * @see java.lang.Thread#run()
+         */
+        public void run() {
+            while (true) {
+                synchronized (fLock) {
+                    if (!fReset)
+                        break;
+                    fReset= false;
+                    fProgressMonitor.setCanceled(false);
+                }
+                internalUpdateSummaries(fProgressMonitor);
+            }
+
+            synchronized (fLock) {
+                fSummarizer= null;
+            }
+        }
+    }
+
+
+    private ProjectionViewer fProjectionViewer;
+    private IAnnotationModel fAnnotationModel;
+    private IAnnotationAccess fAnnotationAccess;
+    private List fConfiguredAnnotationTypes;
+
+    private Object fLock;
+    private IProgressMonitor fProgressMonitor;
+    private /+volatile+/ Summarizer fSummarizer;
+
+    /**
+     * Creates a new projection summary.
+     *
+     * @param projectionViewer the projection viewer
+     * @param annotationAccess the annotation access
+     */
+    public this(ProjectionViewer projectionViewer, IAnnotationAccess annotationAccess) {
+//         super();
+        fLock= new Object();
+
+        fProjectionViewer= projectionViewer;
+        fAnnotationAccess= annotationAccess;
+    }
+
+    /**
+     * Adds the given annotation type. For now on, annotations of that type are
+     * also reflected in their enclosing collapsed regions.
+     *
+     * @param annotationType the annotation type to add
+     */
+    public void addAnnotationType(String annotationType) {
+        synchronized(fLock) {
+            if (fConfiguredAnnotationTypes is null) {
+                fConfiguredAnnotationTypes= new ArrayList();
+                fConfiguredAnnotationTypes.add(annotationType);
+            } else if (!fConfiguredAnnotationTypes.contains(annotationType))
+                fConfiguredAnnotationTypes.add(annotationType);
+        }
+    }
+
+    /**
+     * Removes the given annotation. Annotation of that type are no
+     * longer reflected in their enclosing collapsed region.
+     *
+     * @param annotationType the annotation type to remove
+     */
+    public void removeAnnotationType(String annotationType) {
+        synchronized (fLock) {
+            if (fConfiguredAnnotationTypes !is null) {
+                fConfiguredAnnotationTypes.remove(annotationType);
+                if (fConfiguredAnnotationTypes.size() is 0)
+                    fConfiguredAnnotationTypes= null;
+            }
+        }
+    }
+
+    /**
+     * Forces an updated of the annotation summary.
+     */
+    public void updateSummaries() {
+        synchronized (fLock) {
+            if (fConfiguredAnnotationTypes !is null) {
+                if (fSummarizer is null)
+                    fSummarizer= new Summarizer();
+                fSummarizer.reset();
+            }
+        }
+    }
+
+    private void internalUpdateSummaries(IProgressMonitor monitor) {
+
+        Object previousLockObject= null;
+        fAnnotationModel= fProjectionViewer.getVisualAnnotationModel();
+        if (fAnnotationModel is null)
+            return;
+
+        try {
+
+
+            IDocument document= fProjectionViewer.getDocument();
+            if ( cast(ISynchronizable)document  && cast(ISynchronizable)fAnnotationModel ) {
+                ISynchronizable sync= cast(ISynchronizable) fAnnotationModel;
+                previousLockObject= sync.getLockObject();
+                sync.setLockObject((cast(ISynchronizable) document).getLockObject());
+            }
+
+
+            removeSummaries(monitor);
+
+            if (isCanceled(monitor))
+                return;
+
+            createSummaries(monitor);
+
+        } finally {
+
+            if ( cast(ISynchronizable)fAnnotationModel ) {
+                ISynchronizable sync= cast(ISynchronizable) fAnnotationModel;
+                sync.setLockObject(previousLockObject);
+            }
+            fAnnotationModel= null;
+
+        }
+    }
+
+    private bool isCanceled(IProgressMonitor monitor) {
+        return monitor !is null && monitor.isCanceled();
+    }
+
+    private void removeSummaries(IProgressMonitor monitor) {
+        IAnnotationModelExtension extension= null;
+        List bags= null;
+
+        if ( cast(IAnnotationModelExtension)fAnnotationModel ) {
+            extension= cast(IAnnotationModelExtension) fAnnotationModel;
+            bags= new ArrayList();
+        }
+
+        Iterator e= fAnnotationModel.getAnnotationIterator();
+        while (e.hasNext()) {
+            Annotation annotation= cast(Annotation) e.next();
+            if ( cast(AnnotationBag)annotation ) {
+                if (bags is null)
+                    fAnnotationModel.removeAnnotation(annotation);
+                else
+                    bags.add(annotation);
+            }
+
+            if (isCanceled(monitor))
+                return;
+        }
+
+        if (bags !is null && bags.size() > 0) {
+            Annotation[] deletions= new Annotation[bags.size()];
+            bags.toArray(deletions);
+            if (!isCanceled(monitor))
+                extension.replaceAnnotations(deletions, null);
+        }
+    }
+
+    private void createSummaries(IProgressMonitor monitor) {
+        ProjectionAnnotationModel model= fProjectionViewer.getProjectionAnnotationModel();
+        if (model is null)
+            return;
+
+        Map additions= new HashMap();
+
+        Iterator e= model.getAnnotationIterator();
+        while (e.hasNext()) {
+            ProjectionAnnotation projection= cast(ProjectionAnnotation) e.next();
+            if (projection.isCollapsed()) {
+                Position position= model.getPosition(projection);
+                if (position !is null) {
+                    IRegion[] summaryRegions= fProjectionViewer.computeCollapsedRegions(position);
+                    if (summaryRegions !is null) {
+                        Position summaryAnchor= fProjectionViewer.computeCollapsedRegionAnchor(position);
+                        if (summaryAnchor !is null)
+                            createSummary(additions, summaryRegions, summaryAnchor);
+                    }
+                }
+            }
+
+            if (isCanceled(monitor))
+                return;
+        }
+
+        if (additions.size() > 0) {
+            if ( cast(IAnnotationModelExtension)fAnnotationModel ) {
+                IAnnotationModelExtension extension= cast(IAnnotationModelExtension) fAnnotationModel;
+                if (!isCanceled(monitor))
+                    extension.replaceAnnotations(null, additions);
+            } else {
+                Iterator e1= additions.keySet().iterator();
+                while (e1.hasNext()) {
+                    AnnotationBag bag= cast(AnnotationBag) e1.next();
+                    Position position= cast(Position) additions.get(bag);
+                    if (isCanceled(monitor))
+                        return;
+                    fAnnotationModel.addAnnotation(bag, position);
+                }
+            }
+        }
+    }
+
+    private void createSummary(Map additions, IRegion[] summaryRegions, Position summaryAnchor) {
+
+        int size= 0;
+        Map map= null;
+
+        synchronized (fLock) {
+            if (fConfiguredAnnotationTypes !is null) {
+                size= fConfiguredAnnotationTypes.size();
+                map= new HashMap();
+                for (int i= 0; i < size; i++) {
+                    String type= stringcast( fConfiguredAnnotationTypes.get(i));
+                    map.put(type, new AnnotationBag(type));
+                }
+            }
+        }
+
+        if (map is null)
+            return;
+
+        IAnnotationModel model= fProjectionViewer.getAnnotationModel();
+        if (model is null)
+            return;
+        Iterator e= model.getAnnotationIterator();
+        while (e.hasNext()) {
+            Annotation annotation= cast(Annotation) e.next();
+            AnnotationBag bag= findBagForType(map, annotation.getType());
+            if (bag !is null) {
+                Position position= model.getPosition(annotation);
+                if (includes(summaryRegions, position))
+                    bag.add(annotation);
+            }
+        }
+
+        for (int i= 0; i < size; i++) {
+            AnnotationBag bag= cast(AnnotationBag) map.get(fConfiguredAnnotationTypes.get(i));
+            if (!bag.isEmpty())
+                additions.put(bag, new Position(summaryAnchor.getOffset(), summaryAnchor.getLength()));
+        }
+    }
+
+    private AnnotationBag findBagForType(Map bagMap, String annotationType) {
+        AnnotationBag bag= cast(AnnotationBag) bagMap.get(annotationType);
+        if (bag is null && cast(IAnnotationAccessExtension)fAnnotationAccess ) {
+            IAnnotationAccessExtension extension= cast(IAnnotationAccessExtension) fAnnotationAccess;
+            Object[] superTypes= extension.getSupertypes(stringcast(annotationType));
+            for (int i= 0; i < superTypes.length && bag is null; i++) {
+                bag= cast(AnnotationBag) bagMap.get(superTypes[i]);
+            }
+        }
+        return bag;
+    }
+
+    private bool includes(IRegion[] regions, Position position) {
+        for (int i= 0; i < regions.length; i++) {
+            IRegion region= regions[i];
+            if (position !is null && !position.isDeleted()
+                    && region.getOffset() <= position.getOffset() &&  position.getOffset() + position.getLength() <= region.getOffset() + region.getLength())
+                return true;
+        }
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/projection/ProjectionSupport.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,399 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.projection.ProjectionSupport;
+
+import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport
+import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport
+import dwtx.jface.text.source.projection.AnnotationBag; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport
+import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport
+import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport
+import dwtx.jface.text.source.projection.IProjectionListener; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.custom.StyledTextContent;
+import dwt.graphics.Color;
+import dwt.graphics.FontMetrics;
+import dwt.graphics.GC;
+import dwt.graphics.Point;
+import dwt.graphics.RGB;
+import dwt.widgets.Display;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.source.Annotation;
+import dwtx.jface.text.source.AnnotationPainter;
+import dwtx.jface.text.source.IAnnotationAccess;
+import dwtx.jface.text.source.IAnnotationHover;
+import dwtx.jface.text.source.IAnnotationModel;
+import dwtx.jface.text.source.ISharedTextColors;
+import dwtx.jface.text.source.ISourceViewer;
+
+/**
+ * Supports the configuration of projection capabilities a {@link dwtx.jface.text.source.projection.ProjectionViewer}.
+ * <p>
+ * This class is not intended to be subclassed. Clients are supposed to configure and use it as is.</p>
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ProjectionSupport {
+
+    /**
+     * Key of the projection annotation model inside the visual annotation
+     * model. Also internally used as key for the projection drawing strategy.
+     */
+    private static Object PROJECTION_;
+    public static Object PROJECTION(){
+        if( PROJECTION_ is null ){
+            synchronized(ProjectionSupport.classinfo){
+                if( PROJECTION_ is null ){
+                    PROJECTION_ = new Object();
+                }
+            }
+        }
+        return PROJECTION_;
+    }
+
+    private static class ProjectionAnnotationsPainter : AnnotationPainter {
+
+        /**
+         * Creates a new painter indicating the location of collapsed regions.
+         *
+         * @param sourceViewer the source viewer for the painter
+         * @param access the annotation access
+         */
+        public this(ISourceViewer sourceViewer, IAnnotationAccess access) {
+            super(sourceViewer, access);
+        }
+
+        /*
+         * @see dwtx.jface.text.source.AnnotationPainter#findAnnotationModel(dwtx.jface.text.source.ISourceViewer)
+         */
+        protected IAnnotationModel findAnnotationModel(ISourceViewer sourceViewer) {
+            if ( cast(ProjectionViewer)sourceViewer ) {
+                ProjectionViewer projectionViewer= cast(ProjectionViewer) sourceViewer;
+                return projectionViewer.getProjectionAnnotationModel();
+            }
+            return null;
+        }
+
+        /*
+         * @see dwtx.jface.text.source.AnnotationPainter#skip(dwtx.jface.text.source.Annotation)
+         */
+        protected bool skip(Annotation annotation) {
+            if ( cast(ProjectionAnnotation)annotation )
+                return !(cast(ProjectionAnnotation) annotation).isCollapsed();
+
+            return super.skip(annotation);
+        }
+    }
+
+    private static class ProjectionDrawingStrategy : AnnotationPainter_IDrawingStrategy {
+        /*
+         * @see dwtx.jface.text.source.AnnotationPainter.IDrawingStrategy#draw(dwt.graphics.GC, dwt.custom.StyledText, int, int, dwt.graphics.Color)
+         */
+        public void draw(Annotation annotation, GC gc, StyledText textWidget, int offset, int length, Color color) {
+            if ( cast(ProjectionAnnotation)annotation ) {
+                ProjectionAnnotation projectionAnnotation= cast(ProjectionAnnotation) annotation;
+                if (projectionAnnotation.isCollapsed()) {
+
+                    if (gc !is null) {
+
+                        StyledTextContent content= textWidget.getContent();
+                        int line= content.getLineAtOffset(offset);
+                        int lineStart= content.getOffsetAtLine(line);
+                        String text= content.getLine(line);
+                        int lineLength= text is null ? 0 : text.length;
+                        int lineEnd= lineStart + lineLength;
+                        Point p= textWidget.getLocationAtOffset(lineEnd);
+
+                        Color c= gc.getForeground();
+                        gc.setForeground(color);
+
+                        FontMetrics metrics= gc.getFontMetrics();
+
+                        // baseline: where the dots are drawn
+                        int baseline= textWidget.getBaseline(offset);
+                        // descent: number of pixels that the box extends over baseline
+                        int descent= Math.min(2, textWidget.getLineHeight(offset) - baseline);
+                        // ascent: so much does the box stand up from baseline
+                        int ascent= metrics.getAscent();
+                        // leading: free space from line top to box upper line
+                        int leading= baseline - ascent;
+                        // height: height of the box
+                        int height= ascent + descent;
+
+                        int width= metrics.getAverageCharWidth();
+                        gc.drawRectangle(p.x, p.y + leading, width, height);
+                        int third= width/3;
+                        int dotsVertical= p.y + baseline - 1;
+                        gc.drawPoint(p.x + third, dotsVertical);
+                        gc.drawPoint(p.x + width - third, dotsVertical);
+
+                        gc.setForeground(c);
+
+                    } else {
+                        textWidget.redrawRange(offset, length, true);
+                    }
+                }
+            }
+        }
+    }
+
+    private class ProjectionListener : IProjectionListener {
+
+        /*
+         * @see dwtx.jface.text.source.projection.IProjectionListener#projectionEnabled()
+         */
+        public void projectionEnabled() {
+            doEnableProjection();
+        }
+
+        /*
+         * @see dwtx.jface.text.source.projection.IProjectionListener#projectionDisabled()
+         */
+        public void projectionDisabled() {
+            doDisableProjection();
+        }
+    }
+
+    private ProjectionViewer fViewer;
+    private IAnnotationAccess fAnnotationAccess;
+    private ISharedTextColors fSharedTextColors;
+    private List fSummarizableTypes;
+    private IInformationControlCreator fInformationControlCreator;
+    private IInformationControlCreator fInformationPresenterControlCreator;
+    private ProjectionListener fProjectionListener;
+    private ProjectionAnnotationsPainter fPainter;
+    private ProjectionRulerColumn fColumn;
+    /**
+     * @since 3.1
+     */
+    private AnnotationPainter_IDrawingStrategy fDrawingStrategy;
+
+    /**
+     * Creates new projection support for the given projection viewer. Initially,
+     * no annotation types are summarized. A default hover control creator and a
+     * default drawing strategy are used.
+     *
+     * @param viewer the projection viewer
+     * @param annotationAccess the annotation access
+     * @param sharedTextColors the shared text colors to use
+     */
+    public this(ProjectionViewer viewer, IAnnotationAccess annotationAccess, ISharedTextColors sharedTextColors) {
+        fViewer= viewer;
+        fAnnotationAccess= annotationAccess;
+        fSharedTextColors= sharedTextColors;
+    }
+
+    /**
+     * Marks the given annotation type to be considered when creating summaries for
+     * collapsed regions of the projection viewer.
+     * <p>
+     * A summary is an annotation that gets created out of all annotations with a
+     * type that has been registered through this method and that are inside the
+     * folded region.
+     * </p>
+     *
+     * @param annotationType the annotation type to consider
+     */
+    public void addSummarizableAnnotationType(String annotationType) {
+        if (fSummarizableTypes is null) {
+            fSummarizableTypes= new ArrayList();
+            fSummarizableTypes.add(annotationType);
+        } else if (!fSummarizableTypes.contains(annotationType))
+            fSummarizableTypes.add(annotationType);
+    }
+
+    /**
+     * Marks the given annotation type to be ignored when creating summaries for
+     * collapsed regions of the projection viewer. This method has only an effect
+     * when <code>addSummarizableAnnotationType</code> has been called before for
+     * the give annotation type.
+     * <p>
+     * A summary is an annotation that gets created out of all annotations with a
+     * type that has been registered through this method and that are inside the
+     * folded region.
+     * </p>
+     *
+     * @param annotationType the annotation type to remove
+     */
+    public void removeSummarizableAnnotationType(String annotationType) {
+        if (fSummarizableTypes !is null)
+            fSummarizableTypes.remove(annotationType);
+        if (fSummarizableTypes.size() is 0)
+            fSummarizableTypes= null;
+    }
+
+    /**
+     * Sets the hover control creator that is used for the annotation hovers
+     * that are shown in the projection viewer's projection ruler column.
+     *
+     * @param creator the hover control creator
+     */
+    public void setHoverControlCreator(IInformationControlCreator creator) {
+        fInformationControlCreator= creator;
+    }
+
+    /**
+     * Sets the information presenter control creator that is used for the annotation
+     * hovers that are shown in the projection viewer's projection ruler column.
+     *
+     * @param creator the information presenter control creator
+     * @since 3.3
+     */
+    public void setInformationPresenterControlCreator(IInformationControlCreator creator) {
+        fInformationPresenterControlCreator= creator;
+    }
+
+    /**
+     * Sets the drawing strategy that the projection support's annotation
+     * painter uses to draw the indication of collapsed regions onto the
+     * projection viewer's text widget. When <code>null</code> is passed in,
+     * the drawing strategy is reset to the default. In order to avoid any
+     * representation use {@link dwtx.jface.text.source.AnnotationPainter.NullStrategy}.
+     *
+     * @param strategy the drawing strategy or <code>null</code> to reset the
+     *            strategy to the default
+     * @since 3.1
+     */
+    public void setAnnotationPainterDrawingStrategy(AnnotationPainter_IDrawingStrategy strategy) {
+        fDrawingStrategy= strategy;
+    }
+
+    /**
+     * Returns the drawing strategy to be used by the support's annotation painter.
+     *
+     * @return the drawing strategy to be used by the support's annotation painter
+     * @since 3.1
+     */
+    private AnnotationPainter_IDrawingStrategy getDrawingStrategy() {
+        if (fDrawingStrategy is null)
+            fDrawingStrategy= new ProjectionDrawingStrategy();
+        return fDrawingStrategy;
+    }
+
+    /**
+     * Installs this projection support on its viewer.
+     */
+    public void install() {
+        fViewer.setProjectionSummary(createProjectionSummary());
+
+        fProjectionListener= new ProjectionListener();
+        fViewer.addProjectionListener(fProjectionListener);
+    }
+
+    /**
+     * Disposes this projection support.
+     */
+    public void dispose() {
+        if (fProjectionListener !is null) {
+            fViewer.removeProjectionListener(fProjectionListener);
+            fProjectionListener= null;
+        }
+    }
+
+    /**
+     * Enables projection mode. If not yet done, installs the projection ruler
+     * column in the viewer's vertical ruler and installs a painter that
+     * indicate the locations of collapsed regions.
+     *
+     */
+    protected void doEnableProjection() {
+
+        if (fPainter is null) {
+            fPainter= new ProjectionAnnotationsPainter(fViewer, fAnnotationAccess);
+            fPainter.addDrawingStrategy(PROJECTION, getDrawingStrategy());
+            fPainter.addAnnotationType(stringcast(ProjectionAnnotation.TYPE), PROJECTION);
+            fPainter.setAnnotationTypeColor(stringcast(ProjectionAnnotation.TYPE), fSharedTextColors.getColor(getColor()));
+            fViewer.addPainter(fPainter);
+        }
+
+        if (fColumn is null) {
+            fColumn= new ProjectionRulerColumn(9, fAnnotationAccess);
+            fColumn.addAnnotationType(stringcast(ProjectionAnnotation.TYPE));
+            fColumn.setHover(createProjectionAnnotationHover());
+            fViewer.addVerticalRulerColumn(fColumn);
+        }
+
+        fColumn.setModel(fViewer.getVisualAnnotationModel());
+    }
+
+    /**
+     * Removes the projection ruler column and the painter from the projection
+     * viewer.
+     */
+    protected void doDisableProjection() {
+        if (fPainter !is null) {
+            fViewer.removePainter(fPainter);
+            fPainter.dispose();
+            fPainter= null;
+        }
+
+        if (fColumn !is null) {
+            fViewer.removeVerticalRulerColumn(fColumn);
+            fColumn= null;
+        }
+    }
+
+    private ProjectionSummary createProjectionSummary() {
+        ProjectionSummary summary= new ProjectionSummary(fViewer, fAnnotationAccess);
+        if (fSummarizableTypes !is null) {
+            int size= fSummarizableTypes.size();
+            for (int i= 0; i < size; i++)
+                summary.addAnnotationType(stringcast(fSummarizableTypes.get(i)));
+        }
+        return summary;
+    }
+
+    private IAnnotationHover createProjectionAnnotationHover() {
+        ProjectionAnnotationHover hover= new ProjectionAnnotationHover();
+        hover.setHoverControlCreator(fInformationControlCreator);
+        hover.setInformationPresenterControlCreator(fInformationPresenterControlCreator);
+        return hover;
+    }
+
+    /**
+     * Implements the contract of {@link dwtx.core.runtime.IAdaptable#getAdapter(java.lang.Class)}
+     * by forwarding the adapter requests to the given viewer.
+     *
+     * @param viewer the viewer
+     * @param required the required class of the adapter
+     * @return the adapter or <code>null</code>
+     *
+     */
+    public Object getAdapter(ISourceViewer viewer, ClassInfo required) {
+        if (ProjectionAnnotationModel.classinfo ==/*eq*/ required) {
+            if ( cast(ProjectionViewer)viewer ) {
+                ProjectionViewer projectionViewer= cast(ProjectionViewer) viewer;
+                return projectionViewer.getProjectionAnnotationModel();
+            }
+        }
+        return null;
+    }
+
+    private RGB getColor() {
+        // TODO read out preference settings
+        Color c= Display.getDefault().getSystemColor(DWT.COLOR_DARK_GRAY);
+        return c.getRGB();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/projection/ProjectionViewer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1836 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.projection.ProjectionViewer;
+
+import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport
+import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport
+import dwtx.jface.text.source.projection.AnnotationBag; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport
+import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport
+import dwtx.jface.text.source.projection.SourceViewerInformationControl; // packageimport
+import dwtx.jface.text.source.projection.IProjectionListener; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport
+
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.core.Exception;
+
+
+
+import dwt.DWTError;
+import dwt.custom.ST;
+import dwt.custom.StyledText;
+import dwt.dnd.Clipboard;
+import dwt.dnd.DND;
+import dwt.dnd.TextTransfer;
+import dwt.dnd.Transfer;
+import dwt.events.VerifyEvent;
+import dwt.graphics.Point;
+import dwt.widgets.Composite;
+import dwt.widgets.Display;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.FindReplaceDocumentAdapter;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentInformationMappingExtension;
+import dwtx.jface.text.IDocumentListener;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ISlaveDocumentManager;
+import dwtx.jface.text.ITextViewerExtension5;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.TextUtilities;
+import dwtx.jface.text.projection.ProjectionDocument;
+import dwtx.jface.text.projection.ProjectionDocumentEvent;
+import dwtx.jface.text.projection.ProjectionDocumentManager;
+import dwtx.jface.text.source.Annotation;
+import dwtx.jface.text.source.AnnotationModelEvent;
+import dwtx.jface.text.source.CompositeRuler;
+import dwtx.jface.text.source.IAnnotationModel;
+import dwtx.jface.text.source.IAnnotationModelExtension;
+import dwtx.jface.text.source.IAnnotationModelListener;
+import dwtx.jface.text.source.IAnnotationModelListenerExtension;
+import dwtx.jface.text.source.IOverviewRuler;
+import dwtx.jface.text.source.IVerticalRuler;
+import dwtx.jface.text.source.IVerticalRulerColumn;
+import dwtx.jface.text.source.SourceViewer;
+
+
+/**
+ * A projection source viewer is a source viewer which supports multiple visible
+ * regions which can dynamically be changed.
+ * <p>
+ * A projection source viewer uses a <code>ProjectionDocumentManager</code>
+ * for the management of the visible document.</p>
+ * <p>
+ * NOTE: The <code>ProjectionViewer</code> only supports projections that cover full lines.
+ * </p>
+ * <p>
+ * This class should not be subclassed.</p>
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class ProjectionViewer : SourceViewer , ITextViewerExtension5 {
+
+    public override IRegion getModelCoverage() {
+        return super.getModelCoverage();
+    }
+    public override int modelLine2WidgetLine(int modelLine) {
+        return super.modelLine2WidgetLine(modelLine);
+    }
+    public override int modelOffset2WidgetOffset(int modelOffset) {
+        return super.modelOffset2WidgetOffset(modelOffset);
+    }
+    public override IRegion modelRange2WidgetRange(IRegion modelRange) {
+        return super.modelRange2WidgetRange(modelRange);
+    }
+    protected override IRegion modelRange2WidgetRange(Position modelPosition) {
+        return super.modelRange2WidgetRange(modelPosition);
+    }
+    public override int widgetOffset2ModelOffset(int widgetOffset) {
+        return super.widgetOffset2ModelOffset(widgetOffset);
+    }
+    public override IRegion widgetRange2ModelRange(IRegion widgetRange) {
+        return super.widgetRange2ModelRange(widgetRange);
+    }
+    public int widgetLine2ModelLine(int widgetLine) {
+        return super.widgetLine2ModelLine(widgetLine);
+    }
+    public int widgetLineOfWidgetOffset(int widgetOffset) {
+        return super.widgetLineOfWidgetOffset(widgetOffset);
+    }
+
+    private static const int BASE= INFORMATION; // see ISourceViewer.INFORMATION
+
+    /** Operation constant for the expand operation. */
+    public static const int EXPAND= BASE + 1;
+    /** Operation constant for the collapse operation. */
+    public static const int COLLAPSE= BASE + 2;
+    /** Operation constant for the toggle projection operation. */
+    public static const int TOGGLE= BASE + 3;
+    /** Operation constant for the expand all operation. */
+    public static const int EXPAND_ALL= BASE + 4;
+    /**
+     * Operation constant for the collapse all operation.
+     *
+     * @since 3.2
+     */
+    public static const int COLLAPSE_ALL= BASE + 5;
+
+    /**
+     * Internal listener to changes of the annotation model.
+     */
+    private class AnnotationModelListener : IAnnotationModelListener, IAnnotationModelListenerExtension {
+
+        /*
+         * @see dwtx.jface.text.source.IAnnotationModelListener#modelChanged(dwtx.jface.text.source.IAnnotationModel)
+         */
+        public void modelChanged(IAnnotationModel model) {
+            processModelChanged(model, null);
+        }
+
+        /*
+         * @see dwtx.jface.text.source.IAnnotationModelListenerExtension#modelChanged(dwtx.jface.text.source.AnnotationModelEvent)
+         */
+        public void modelChanged(AnnotationModelEvent event) {
+            processModelChanged(event.getAnnotationModel(), event);
+        }
+
+        private void processModelChanged(IAnnotationModel model, AnnotationModelEvent event) {
+            if (model is fProjectionAnnotationModel) {
+
+                if (fProjectionSummary !is null)
+                    fProjectionSummary.updateSummaries();
+                processCatchupRequest(event);
+
+            } else if (model is getAnnotationModel() && fProjectionSummary !is null)
+                fProjectionSummary.updateSummaries();
+        }
+    }
+
+    /**
+     * Executes the 'replaceVisibleDocument' operation when called the first time. Self-destructs afterwards.
+     */
+    private class ReplaceVisibleDocumentExecutor : IDocumentListener {
+
+        private IDocument fSlaveDocument;
+        private IDocument fExecutionTrigger;
+
+        /**
+         * Creates a new executor in order to free the given slave document.
+         *
+         * @param slaveDocument the slave document to free
+         */
+        public this(IDocument slaveDocument) {
+            fSlaveDocument= slaveDocument;
+        }
+
+        /**
+         * Installs this executor on the given trigger document.
+         *
+         * @param executionTrigger the trigger document
+         */
+        public void install(IDocument executionTrigger) {
+            if (executionTrigger !is null && fSlaveDocument !is null) {
+                fExecutionTrigger= executionTrigger;
+                fExecutionTrigger.addDocumentListener(this);
+            }
+        }
+
+        /*
+         * @see dwtx.jface.text.IDocumentListener#documentAboutToBeChanged(dwtx.jface.text.DocumentEvent)
+         */
+        public void documentAboutToBeChanged(DocumentEvent event) {
+        }
+
+        /*
+         * @see dwtx.jface.text.IDocumentListener#documentChanged(dwtx.jface.text.DocumentEvent)
+         */
+        public void documentChanged(DocumentEvent event) {
+            fExecutionTrigger.removeDocumentListener(this);
+            executeReplaceVisibleDocument(fSlaveDocument);
+        }
+    }
+
+    /**
+     * A command representing a change of the projection document. This can be either
+     * adding a master document range, removing a master document change, or invalidating
+     * the viewer text presentation.
+     */
+    private static class ProjectionCommand {
+
+        const static int ADD= 0;
+        const static int REMOVE= 1;
+        const static int INVALIDATE_PRESENTATION= 2;
+
+        ProjectionDocument fProjection;
+        int fType;
+        int fOffset;
+        int fLength;
+
+        this(ProjectionDocument projection, int type, int offset, int length) {
+            fProjection= projection;
+            fType= type;
+            fOffset= offset;
+            fLength= length;
+        }
+
+        this(int offset, int length) {
+            fType= INVALIDATE_PRESENTATION;
+            fOffset= offset;
+            fLength= length;
+        }
+
+        int computeExpectedCosts() {
+
+            switch(fType) {
+                case ADD: {
+                    try {
+                        IRegion[] gaps= fProjection.computeUnprojectedMasterRegions(fOffset, fLength);
+                        return gaps is null ? 0 : gaps.length;
+                    } catch (BadLocationException x) {
+                    }
+                    break;
+                }
+                case REMOVE: {
+                    try {
+                        IRegion[] fragments= fProjection.computeProjectedMasterRegions(fOffset, fLength);
+                        return fragments is null ? 0 : fragments.length;
+                    } catch (BadLocationException x) {
+                    }
+                    break;
+                }
+            }
+            return 0;
+        }
+    }
+
+    /**
+     * The queue of projection command objects.
+     */
+    private static class ProjectionCommandQueue {
+
+        final static int REDRAW_COSTS= 15;
+        final static int INVALIDATION_COSTS= 10;
+
+        List fList;
+        int fExpectedExecutionCosts= -1;
+
+        this(){
+            fList= new ArrayList(15);
+        }
+
+        void add(ProjectionCommand command) {
+            fList.add(command);
+        }
+
+        Iterator iterator() {
+            return fList.iterator();
+        }
+
+        void clear() {
+            fList.clear();
+            fExpectedExecutionCosts= -1;
+        }
+
+        bool passedRedrawCostsThreshold() {
+            if (fExpectedExecutionCosts is -1)
+                computeExpectedExecutionCosts();
+            return fExpectedExecutionCosts > REDRAW_COSTS;
+        }
+
+        bool passedInvalidationCostsThreshold() {
+            if (fExpectedExecutionCosts is -1)
+                computeExpectedExecutionCosts();
+            return fExpectedExecutionCosts > INVALIDATION_COSTS;
+        }
+
+        private void computeExpectedExecutionCosts() {
+            int max_costs= Math.max(REDRAW_COSTS, INVALIDATION_COSTS);
+            fExpectedExecutionCosts= fList.size();
+            if (fExpectedExecutionCosts <= max_costs) {
+                ProjectionCommand command;
+                Iterator e= fList.iterator();
+                while (e.hasNext()) {
+                    command= cast(ProjectionCommand) e.next();
+                    fExpectedExecutionCosts += command.computeExpectedCosts();
+                    if (fExpectedExecutionCosts > max_costs)
+                        break;
+                }
+            }
+        }
+    }
+
+    /** The projection annotation model used by this viewer. */
+    private ProjectionAnnotationModel fProjectionAnnotationModel;
+    /** The annotation model listener */
+    private IAnnotationModelListener fAnnotationModelListener;
+    /** The projection summary. */
+    private ProjectionSummary fProjectionSummary;
+    /** Indication that an annotation world change has not yet been processed. */
+    private bool fPendingAnnotationWorldChange= false;
+    /** Indication whether projection changes in the visible document should be considered. */
+    private bool fHandleProjectionChanges= true;
+    /** The list of projection listeners. */
+    private List fProjectionListeners;
+    /** Internal lock for protecting the list of pending requests */
+    private Object fLock;
+    /** The list of pending requests */
+    private List fPendingRequests;
+    /** The replace-visible-document execution trigger */
+    private IDocument fReplaceVisibleDocumentExecutionTrigger;
+    /** <code>true</code> if projection was on the last time we switched to segmented mode. */
+    private bool fWasProjectionEnabled;
+    /** The queue of projection commands used to assess the costs of projection changes. */
+    private ProjectionCommandQueue fCommandQueue;
+    /**
+     * The amount of lines deleted by the last document event issued by the
+     * visible document event.
+     * @since 3.1
+     */
+    private int fDeletedLines;
+
+
+    /**
+     * Creates a new projection source viewer.
+     *
+     * @param parent the DWT parent control
+     * @param ruler the vertical ruler
+     * @param overviewRuler the overview ruler
+     * @param showsAnnotationOverview <code>true</code> if the overview ruler should be shown
+     * @param styles the DWT style bits
+     */
+    public this(Composite parent, IVerticalRuler ruler, IOverviewRuler overviewRuler, bool showsAnnotationOverview, int styles) {
+
+        fAnnotationModelListener= new AnnotationModelListener();
+        fLock= new Object();
+        fPendingRequests= new ArrayList();
+
+        super(parent, ruler, overviewRuler, showsAnnotationOverview, styles);
+    }
+
+    /**
+     * Sets the projection summary for this viewer.
+     *
+     * @param projectionSummary the projection summary.
+     */
+    public void setProjectionSummary(ProjectionSummary projectionSummary) {
+        fProjectionSummary= projectionSummary;
+    }
+
+    /**
+     * Adds the projection annotation model to the given annotation model.
+     *
+     * @param model the model to which the projection annotation model is added
+     */
+    private void addProjectionAnnotationModel(IAnnotationModel model) {
+        if ( cast(IAnnotationModelExtension)model ) {
+            IAnnotationModelExtension extension= cast(IAnnotationModelExtension) model;
+            extension.addAnnotationModel(ProjectionSupport.PROJECTION, fProjectionAnnotationModel);
+            model.addAnnotationModelListener(fAnnotationModelListener);
+        }
+    }
+
+    /**
+     * Removes the projection annotation model from the given annotation model.
+     *
+     * @param model the mode from which the projection annotation model is removed
+     * @return the removed projection annotation model or <code>null</code> if there was none
+     */
+    private IAnnotationModel removeProjectionAnnotationModel(IAnnotationModel model) {
+        if ( cast(IAnnotationModelExtension)model ) {
+            model.removeAnnotationModelListener(fAnnotationModelListener);
+            IAnnotationModelExtension extension= cast(IAnnotationModelExtension) model;
+            return extension.removeAnnotationModel(ProjectionSupport.PROJECTION);
+        }
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.SourceViewer#setDocument(dwtx.jface.text.IDocument, dwtx.jface.text.source.IAnnotationModel, int, int)
+     */
+    public void setDocument(IDocument document, IAnnotationModel annotationModel, int modelRangeOffset, int modelRangeLength) {
+        bool wasProjectionEnabled= false;
+
+        synchronized (fLock) {
+            fPendingRequests.clear();
+        }
+
+        if (fProjectionAnnotationModel !is null) {
+            wasProjectionEnabled= removeProjectionAnnotationModel(getVisualAnnotationModel()) !is null;
+            fProjectionAnnotationModel= null;
+        }
+
+        super.setDocument(document, annotationModel, modelRangeOffset, modelRangeLength);
+
+        if (wasProjectionEnabled && document !is null)
+            enableProjection();
+    }
+
+    /*
+     * @see dwtx.jface.text.source.SourceViewer#createVisualAnnotationModel(dwtx.jface.text.source.IAnnotationModel)
+     */
+    protected IAnnotationModel createVisualAnnotationModel(IAnnotationModel annotationModel) {
+        IAnnotationModel model= super.createVisualAnnotationModel(annotationModel);
+        fProjectionAnnotationModel= new ProjectionAnnotationModel();
+        return model;
+    }
+
+    /**
+     * Returns the projection annotation model.
+     *
+     * @return the projection annotation model
+     */
+    public ProjectionAnnotationModel getProjectionAnnotationModel() {
+        IAnnotationModel model= getVisualAnnotationModel();
+        if ( cast(IAnnotationModelExtension)model ) {
+            IAnnotationModelExtension extension= cast(IAnnotationModelExtension) model;
+            return cast(ProjectionAnnotationModel) extension.getAnnotationModel(ProjectionSupport.PROJECTION);
+        }
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#createSlaveDocumentManager()
+     */
+    protected ISlaveDocumentManager createSlaveDocumentManager() {
+        return new ProjectionDocumentManager();
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#updateSlaveDocument(dwtx.jface.text.IDocument, int, int)
+     */
+    protected bool updateSlaveDocument(IDocument slaveDocument, int modelRangeOffset, int modelRangeLength)  {
+        if ( cast(ProjectionDocument)slaveDocument ) {
+            ProjectionDocument projection= cast(ProjectionDocument) slaveDocument;
+
+            int offset= modelRangeOffset;
+            int length= modelRangeLength;
+
+            if (!isProjectionMode()) {
+                // mimic original TextViewer behavior
+                IDocument master= projection.getMasterDocument();
+                int line= master.getLineOfOffset(modelRangeOffset);
+                offset= master.getLineOffset(line);
+                length= (modelRangeOffset - offset) + modelRangeLength;
+
+            }
+
+            try {
+                fHandleProjectionChanges= false;
+                projection.replaceMasterDocumentRanges(offset, length);
+            } finally {
+                fHandleProjectionChanges= true;
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Adds a projection annotation listener to this viewer. The listener may
+     * not be <code>null</code>. If the listener is already registered, this method
+     * does not have any effect.
+     *
+     * @param listener the listener to add
+     */
+    public void addProjectionListener(IProjectionListener listener) {
+
+        Assert.isNotNull(cast(Object)listener);
+
+        if (fProjectionListeners is null)
+            fProjectionListeners= new ArrayList();
+
+        if (!fProjectionListeners.contains(cast(Object)listener))
+            fProjectionListeners.add(cast(Object)listener);
+    }
+
+    /**
+     * Removes the given listener from this viewer. The listener may not be
+     * <code>null</code>. If the listener is not registered with this viewer,
+     * this method is without effect.
+     *
+     * @param listener the listener to remove
+     */
+    public void removeProjectionListener(IProjectionListener listener) {
+
+        Assert.isNotNull(cast(Object)listener);
+
+        if (fProjectionListeners !is null) {
+            fProjectionListeners.remove(cast(Object)listener);
+            if (fProjectionListeners.size() is 0)
+                fProjectionListeners= null;
+        }
+    }
+
+    /**
+     * Notifies all registered projection listeners
+     * that projection mode has been enabled.
+     */
+    protected void fireProjectionEnabled() {
+        if (fProjectionListeners !is null) {
+            Iterator e= (new ArrayList(fProjectionListeners)).iterator();
+            while (e.hasNext()) {
+                IProjectionListener l= cast(IProjectionListener) e.next();
+                l.projectionEnabled();
+            }
+        }
+    }
+
+    /**
+     * Notifies all registered projection listeners
+     * that projection mode has been disabled.
+     */
+    protected void fireProjectionDisabled() {
+        if (fProjectionListeners !is null) {
+            Iterator e= (new ArrayList(fProjectionListeners)).iterator();
+            while (e.hasNext()) {
+                IProjectionListener l= cast(IProjectionListener) e.next();
+                l.projectionDisabled();
+            }
+        }
+    }
+
+    /**
+     * Returns whether this viewer is in projection mode.
+     *
+     * @return <code>true</code> if this viewer is in projection mode,
+     *         <code>false</code> otherwise
+     */
+    public final bool isProjectionMode() {
+        return getProjectionAnnotationModel() !is null;
+    }
+
+    /**
+     * Disables the projection mode.
+     */
+    public final void disableProjection() {
+        if (isProjectionMode()) {
+            removeProjectionAnnotationModel(getVisualAnnotationModel());
+            fProjectionAnnotationModel.removeAllAnnotations();
+            fFindReplaceDocumentAdapter= null;
+            fireProjectionDisabled();
+        }
+    }
+
+    /**
+     * Enables the projection mode.
+     */
+    public final void enableProjection() {
+        if (!isProjectionMode()) {
+            addProjectionAnnotationModel(getVisualAnnotationModel());
+            fFindReplaceDocumentAdapter= null;
+            fireProjectionEnabled();
+        }
+    }
+
+    private void expandAll() {
+        int offset= 0;
+        IDocument doc= getDocument();
+        int length= doc is null ? 0 : doc.getLength();
+        if (isProjectionMode()) {
+            fProjectionAnnotationModel.expandAll(offset, length);
+        }
+    }
+
+    private void expand() {
+        if (isProjectionMode()) {
+            Position found= null;
+            Annotation bestMatch= null;
+            Point selection= getSelectedRange();
+            for (Iterator e= fProjectionAnnotationModel.getAnnotationIterator(); e.hasNext();) {
+                ProjectionAnnotation annotation= cast(ProjectionAnnotation) e.next();
+                if (annotation.isCollapsed()) {
+                    Position position= fProjectionAnnotationModel.getPosition(annotation);
+                    // take the first most fine grained match
+                    if (position !is null && touches(selection, position))
+                        if (found is null || position.includes(found.offset) && position.includes(found.offset + found.length)) {
+                            found= position;
+                            bestMatch= annotation;
+                        }
+                }
+            }
+
+            if (bestMatch !is null) {
+                fProjectionAnnotationModel.expand(bestMatch);
+                revealRange(selection.x, selection.y);
+            }
+        }
+    }
+
+    private bool touches(Point selection, Position position) {
+        return position.overlapsWith(selection.x, selection.y) || selection.y is 0 && position.offset + position.length is selection.x + selection.y;
+    }
+
+    private void collapse() {
+        if (isProjectionMode()) {
+            Position found= null;
+            Annotation bestMatch= null;
+            Point selection= getSelectedRange();
+            for (Iterator e= fProjectionAnnotationModel.getAnnotationIterator(); e.hasNext();) {
+                ProjectionAnnotation annotation= cast(ProjectionAnnotation) e.next();
+                if (!annotation.isCollapsed()) {
+                    Position position= fProjectionAnnotationModel.getPosition(annotation);
+                    // take the first most fine grained match
+                    if (position !is null && touches(selection, position))
+                        if (found is null || found.includes(position.offset) && found.includes(position.offset + position.length)) {
+                            found= position;
+                            bestMatch= annotation;
+                        }
+                }
+            }
+
+            if (bestMatch !is null) {
+                fProjectionAnnotationModel.collapse(bestMatch);
+                revealRange(selection.x, selection.y);
+            }
+        }
+    }
+
+    /*
+     * @since 3.2
+     */
+    private void collapseAll() {
+        int offset= 0;
+        IDocument doc= getDocument();
+        int length= doc is null ? 0 : doc.getLength();
+        if (isProjectionMode()) {
+            fProjectionAnnotationModel.collapseAll(offset, length);
+        }
+    }
+
+    /**
+     * Adds the given master range to the given projection document. While the
+     * modification is processed, the viewer no longer handles projection
+     * changes, as it is causing them.
+     *
+     * @param projection the projection document
+     * @param offset the offset in the master document
+     * @param length the length in the master document
+     * @throws BadLocationException in case the specified range is invalid
+     *
+     * @see ProjectionDocument#addMasterDocumentRange(int, int)
+     */
+    private void addMasterDocumentRange(ProjectionDocument projection, int offset, int length)  {
+
+        if (fCommandQueue !is null) {
+            fCommandQueue.add(new ProjectionCommand(projection, ProjectionCommand.ADD, offset, length));
+        } else {
+            try {
+                fHandleProjectionChanges= false;
+                // https://bugs.eclipse.org/bugs/show_bug.cgi?id=108258
+                // make sure the document range is strictly line based
+                int end= offset + length;
+                offset= toLineStart(projection.getMasterDocument(), offset, false);
+                length= toLineStart(projection.getMasterDocument(), end, true) - offset;
+                projection.addMasterDocumentRange(offset, length);
+            } finally {
+                fHandleProjectionChanges= true;
+            }
+        }
+    }
+
+    /**
+     * Removes the given master range from the given projection document. While the
+     * modification is processed, the viewer no longer handles projection
+     * changes, as it is causing them.
+     *
+     * @param projection the projection document
+     * @param offset the offset in the master document
+     * @param length the length in the master document
+     * @throws BadLocationException in case the specified range is invalid
+     *
+     * @see ProjectionDocument#removeMasterDocumentRange(int, int)
+     */
+    private void removeMasterDocumentRange(ProjectionDocument projection, int offset, int length)  {
+        if (fCommandQueue !is null) {
+            fCommandQueue.add(new ProjectionCommand(projection, ProjectionCommand.REMOVE, offset, length));
+        } else {
+            try {
+                fHandleProjectionChanges= false;
+                // https://bugs.eclipse.org/bugs/show_bug.cgi?id=108258
+                // make sure the document range is strictly line based
+                int end= offset + length;
+                offset= toLineStart(projection.getMasterDocument(), offset, false);
+                length= toLineStart(projection.getMasterDocument(), end, true) - offset;
+                projection.removeMasterDocumentRange(offset, length);
+            } finally {
+                fHandleProjectionChanges= true;
+            }
+        }
+    }
+
+    /**
+     * Returns the first line offset &lt;= <code>offset</code>. If <code>testLastLine</code>
+     * is <code>true</code> and the offset is on last line then <code>offset</code> is returned.
+     *
+     * @param document the document
+     * @param offset the master document offset
+     * @param testLastLine <code>true</code> if the test for the last line should be performed
+     * @return the closest line offset &gt;= <code>offset</code>
+     * @throws BadLocationException if the offset is invalid
+     * @since 3.2
+     */
+    private int toLineStart(IDocument document, int offset, bool testLastLine)  {
+        if (document is null)
+            return offset;
+
+        if (testLastLine && offset >= document.getLineInformationOfOffset(document.getLength() - 1).getOffset())
+            return offset;
+
+        return document.getLineInformationOfOffset(offset).getOffset();
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#setVisibleRegion(int, int)
+     */
+    public void setVisibleRegion(int start, int length) {
+        fWasProjectionEnabled= isProjectionMode();
+        disableProjection();
+        super.setVisibleRegion(start, length);
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#setVisibleDocument(dwtx.jface.text.IDocument)
+     */
+    protected void setVisibleDocument(IDocument document) {
+        if (!isProjectionMode()) {
+            super.setVisibleDocument(document);
+            return;
+        }
+
+        // In projection mode we don't want to throw away the find/replace document adapter
+        FindReplaceDocumentAdapter adapter= fFindReplaceDocumentAdapter;
+        super.setVisibleDocument(document);
+        fFindReplaceDocumentAdapter= adapter;
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#resetVisibleRegion()
+     */
+    public void resetVisibleRegion() {
+        super.resetVisibleRegion();
+        if (fWasProjectionEnabled)
+            enableProjection();
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextViewer#getVisibleRegion()
+     */
+    public IRegion getVisibleRegion() {
+        disableProjection();
+        IRegion visibleRegion= getModelCoverage();
+        if (visibleRegion is null)
+            visibleRegion= new Region(0, 0);
+
+        return visibleRegion;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextViewer#overlapsWithVisibleRegion(int,int)
+     */
+    public bool overlapsWithVisibleRegion(int offset, int length) {
+        disableProjection();
+        IRegion coverage= getModelCoverage();
+        if (coverage is null)
+            return false;
+
+        bool appending= (offset is coverage.getOffset() + coverage.getLength()) && length is 0;
+        return appending || TextUtilities.overlaps(coverage, new Region(offset, length));
+    }
+
+    /**
+     * Replace the visible document with the given document. Maintains the
+     * scroll offset and the selection.
+     *
+     * @param slave the visible document
+     */
+    private void replaceVisibleDocument(IDocument slave) {
+        if (fReplaceVisibleDocumentExecutionTrigger !is null) {
+            ReplaceVisibleDocumentExecutor executor= new ReplaceVisibleDocumentExecutor(slave);
+            executor.install(fReplaceVisibleDocumentExecutionTrigger);
+        } else
+            executeReplaceVisibleDocument(slave);
+    }
+
+
+    private void executeReplaceVisibleDocument(IDocument visibleDocument) {
+        StyledText textWidget= getTextWidget();
+        try {
+            if (textWidget !is null && !textWidget.isDisposed())
+                textWidget.setRedraw(false);
+
+            int topIndex= getTopIndex();
+            Point selection= getSelectedRange();
+            setVisibleDocument(visibleDocument);
+            Point currentSelection= getSelectedRange();
+            if (currentSelection.x !is selection.x || currentSelection.y !is selection.y)
+                setSelectedRange(selection.x, selection.y);
+            setTopIndex(topIndex);
+
+        } finally {
+            if (textWidget !is null && !textWidget.isDisposed())
+                textWidget.setRedraw(true);
+        }
+    }
+
+    /**
+     * Hides the given range by collapsing it. If requested, a redraw request is issued.
+     *
+     * @param offset the offset of the range to hide
+     * @param length the length of the range to hide
+     * @param fireRedraw <code>true</code> if a redraw request should be issued, <code>false</code> otherwise
+     * @throws BadLocationException in case the range is invalid
+     */
+    private void collapse(int offset, int length, bool fireRedraw)  {
+        ProjectionDocument projection= null;
+
+        IDocument visibleDocument= getVisibleDocument();
+        if ( cast(ProjectionDocument)visibleDocument )
+            projection= cast(ProjectionDocument) visibleDocument;
+        else {
+            IDocument master= getDocument();
+            IDocument slave= createSlaveDocument(getDocument());
+            if ( cast(ProjectionDocument)slave ) {
+                projection= cast(ProjectionDocument) slave;
+                addMasterDocumentRange(projection, 0, master.getLength());
+                replaceVisibleDocument(projection);
+            }
+        }
+
+        if (projection !is null)
+            removeMasterDocumentRange(projection, offset, length);
+
+        if (projection !is null && fireRedraw) {
+            // repaint line above to get the folding box
+            IDocument document= getDocument();
+            int line= document.getLineOfOffset(offset);
+            if (line > 0) {
+                IRegion info= document.getLineInformation(line - 1);
+                internalInvalidateTextPresentation(info.getOffset(), info.getLength());
+            }
+        }
+    }
+
+    /**
+     * Makes the given range visible again while not changing the folding state of any contained
+     * ranges. If requested, a redraw request is issued.
+     *
+     * @param offset the offset of the range to be expanded
+     * @param length the length of the range to be expanded
+     * @param fireRedraw <code>true</code> if a redraw request should be issued,
+     *        <code>false</code> otherwise
+     * @throws BadLocationException in case the range is invalid
+     */
+    private void expand(int offset, int length, bool fireRedraw)  {
+        IDocument slave= getVisibleDocument();
+        if ( cast(ProjectionDocument)slave ) {
+            ProjectionDocument projection= cast(ProjectionDocument) slave;
+
+            // expand
+            addMasterDocumentRange(projection, offset, length);
+
+            // collapse contained regions
+            ProjectionAnnotation[] collapsed= computeCollapsedNestedAnnotations(offset, length);
+            if (collapsed !is null) {
+                for (int i= 0; i < collapsed.length; i++) {
+                    IRegion[] regions= computeCollapsedRegions(fProjectionAnnotationModel.getPosition(collapsed[i]));
+                    if (regions !is null)
+                        for (int j= 0; j < regions.length; j++)
+                            removeMasterDocumentRange(projection, regions[j].getOffset(), regions[j].getLength());
+                }
+            }
+
+            // redraw if requested
+            if (fireRedraw)
+                internalInvalidateTextPresentation(offset, length);
+        }
+    }
+
+    /**
+     * Processes the request for catch up with the annotation model in the UI thread. If the current
+     * thread is not the UI thread or there are pending catch up requests, a new request is posted.
+     *
+     * @param event the annotation model event
+     */
+    protected final void processCatchupRequest(AnnotationModelEvent event) {
+        if (Display.getCurrent() !is null) {
+            bool run= false;
+            synchronized (fLock) {
+                run= fPendingRequests.isEmpty();
+            }
+            if (run) {
+
+                try {
+                    catchupWithProjectionAnnotationModel(event);
+                } catch (BadLocationException x) {
+                    throw new IllegalArgumentException(null);
+                }
+
+            } else
+                postCatchupRequest(event);
+        } else {
+            postCatchupRequest(event);
+        }
+    }
+
+    /**
+     * Posts the request for catch up with the annotation model into the UI thread.
+     *
+     * @param event the annotation model event
+     */
+    protected final void postCatchupRequest(AnnotationModelEvent event) {
+        synchronized (fLock) {
+            fPendingRequests.add(event);
+            if (fPendingRequests.size() is 1) {
+                StyledText widget= getTextWidget();
+                if (widget !is null) {
+                    Display display= widget.getDisplay();
+                    if (display !is null) {
+                        display.asyncExec(new class()  Runnable {
+                            public void run() {
+                                try {
+                                    while (true) {
+                                        AnnotationModelEvent ame= null;
+                                        synchronized (fLock) {
+                                            if (fPendingRequests.size() is 0)
+                                                return;
+                                            ame= cast(AnnotationModelEvent) fPendingRequests.remove(0);
+                                        }
+                                        catchupWithProjectionAnnotationModel(ame);
+                                    }
+                                } catch (BadLocationException x) {
+                                    try {
+                                        catchupWithProjectionAnnotationModel(null);
+                                    } catch (BadLocationException x1) {
+                                        throw new IllegalArgumentException(null);
+                                    } finally {
+                                        synchronized (fLock) {
+                                            fPendingRequests.clear();
+                                        }
+                                    }
+                                }
+                            }
+                        });
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Tests whether the visible document's master document
+     * is identical to this viewer's document.
+     *
+     * @return <code>true</code> if the visible document's master is
+     *          identical to this viewer's document
+     * @since 3.1
+     */
+    private bool isVisibleMasterDocumentSameAsDocument() {
+        IDocument visibleDocument= getVisibleDocument();
+        return ( cast(ProjectionDocument)visibleDocument ) && (cast(ProjectionDocument)visibleDocument).getMasterDocument() is getDocument();
+    }
+
+    /**
+     * Adapts the slave visual document of this viewer to the changes described
+     * in the annotation model event. When the event is <code>null</code>,
+     * this is identical to a world change event.
+     *
+     * @param event the annotation model event or <code>null</code>
+     * @exception BadLocationException in case the annotation model event is no longer in synchronization with the document
+     */
+    private void catchupWithProjectionAnnotationModel(AnnotationModelEvent event)  {
+
+        if (event is null || !isVisibleMasterDocumentSameAsDocument()) {
+
+            fPendingAnnotationWorldChange= false;
+            reinitializeProjection();
+
+        } else if (event.isWorldChange()) {
+
+            if (event.isValid()) {
+                fPendingAnnotationWorldChange= false;
+                reinitializeProjection();
+            } else
+                fPendingAnnotationWorldChange= true;
+
+        } else if (fPendingAnnotationWorldChange) {
+            if (event.isValid()) {
+                fPendingAnnotationWorldChange= false;
+                reinitializeProjection();
+            }
+        } else {
+
+            Annotation[] addedAnnotations= event.getAddedAnnotations();
+            Annotation[] changedAnnotation= event.getChangedAnnotations();
+            Annotation[] removedAnnotations= event.getRemovedAnnotations();
+
+            fCommandQueue= new ProjectionCommandQueue();
+
+            bool isRedrawing= redraws();
+            int topIndex= isRedrawing ? getTopIndex() : -1;
+
+            processDeletions(event, removedAnnotations, true);
+            List coverage= new ArrayList();
+            processChanges(addedAnnotations, true, coverage);
+            processChanges(changedAnnotation, true, coverage);
+
+            ProjectionCommandQueue commandQueue= fCommandQueue;
+            fCommandQueue= null;
+
+            if (commandQueue.passedRedrawCostsThreshold()) {
+                setRedraw(false);
+                try {
+                    executeProjectionCommands(commandQueue, false);
+                } catch (IllegalArgumentException x) {
+                    reinitializeProjection();
+                } finally {
+                    setRedraw(true, topIndex);
+                }
+            } else {
+                try {
+                    bool fireRedraw= !commandQueue.passedInvalidationCostsThreshold();
+                    executeProjectionCommands(commandQueue, fireRedraw);
+                    if (!fireRedraw)
+                        invalidateTextPresentation();
+                } catch (IllegalArgumentException x) {
+                    reinitializeProjection();
+                }
+            }
+        }
+    }
+
+    private void executeProjectionCommands(ProjectionCommandQueue commandQueue, bool fireRedraw)  {
+
+        ProjectionCommand command;
+        Iterator e= commandQueue.iterator();
+        while (e.hasNext()) {
+            command= cast(ProjectionCommand) e.next();
+            switch (command.fType) {
+                case ProjectionCommand.ADD:
+                    addMasterDocumentRange(command.fProjection, command.fOffset, command.fLength);
+                    break;
+                case ProjectionCommand.REMOVE:
+                    removeMasterDocumentRange(command.fProjection, command.fOffset, command.fLength);
+                    break;
+                case ProjectionCommand.INVALIDATE_PRESENTATION:
+                    if (fireRedraw)
+                        invalidateTextPresentation(command.fOffset, command.fLength);
+                    break;
+            }
+        }
+
+        commandQueue.clear();
+    }
+
+    private bool covers(int offset, int length, Position position) {
+        if (!(position.offset is offset && position.length is length) && !position.isDeleted())
+            return offset <= position.getOffset() && position.getOffset() + position.getLength() <= offset + length;
+        return false;
+    }
+
+    private ProjectionAnnotation[] computeCollapsedNestedAnnotations(int offset, int length) {
+        List annotations= new ArrayList(5);
+        Iterator e= fProjectionAnnotationModel.getAnnotationIterator();
+        while (e.hasNext()) {
+            ProjectionAnnotation annotation= cast(ProjectionAnnotation) e.next();
+            if (annotation.isCollapsed()) {
+                Position position= fProjectionAnnotationModel.getPosition(annotation);
+                if (position is null) {
+                    // annotation might already be deleted, we will be informed later on about this deletion
+                    continue;
+                }
+                if (covers(offset, length, position))
+                    annotations.add(annotation);
+            }
+        }
+
+        if (annotations.size() > 0) {
+            ProjectionAnnotation[] result= new ProjectionAnnotation[annotations.size()];
+            annotations.toArray(result);
+            return result;
+        }
+
+        return null;
+    }
+
+    private void internalInvalidateTextPresentation(int offset, int length) {
+        if (fCommandQueue !is null) {
+            fCommandQueue.add(new ProjectionCommand(offset, length));
+        } else {
+            invalidateTextPresentation(offset, length);
+        }
+    }
+
+    /*
+     * We pass the removed annotation into this method for performance reasons only. Otherwise, they could be fetch from the event.
+     */
+    private void processDeletions(AnnotationModelEvent event, Annotation[] removedAnnotations, bool fireRedraw)  {
+        for (int i= 0; i < removedAnnotations.length; i++) {
+            ProjectionAnnotation annotation= cast(ProjectionAnnotation) removedAnnotations[i];
+            if (annotation.isCollapsed()) {
+                Position expanded= event.getPositionOfRemovedAnnotation(annotation);
+                expand(expanded.getOffset(), expanded.getLength(), fireRedraw);
+            }
+        }
+    }
+
+    /**
+     * Computes the region that must be collapsed when the given position is the
+     * position of an expanded projection annotation.
+     *
+     * @param position the position
+     * @return the range that must be collapsed
+     */
+    public IRegion computeCollapsedRegion(Position position) {
+        try {
+            IDocument document= getDocument();
+            if (document is null)
+                return null;
+
+            int line= document.getLineOfOffset(position.getOffset());
+            int offset= document.getLineOffset(line + 1);
+
+            int length= position.getLength() - (offset - position.getOffset());
+            if (length > 0)
+                return new Region(offset, length);
+        } catch (BadLocationException x) {
+        }
+
+        return null;
+    }
+
+    /**
+     * Computes the regions that must be collapsed when the given position is
+     * the position of an expanded projection annotation.
+     *
+     * @param position the position
+     * @return the ranges that must be collapsed, or <code>null</code> if
+     *         there are none
+     * @since 3.1
+     */
+    IRegion[] computeCollapsedRegions(Position position) {
+        try {
+            IDocument document= getDocument();
+            if (document is null)
+                return null;
+
+            if ( cast(IProjectionPosition)position ) {
+                IProjectionPosition projPosition= cast(IProjectionPosition) position;
+                return projPosition.computeProjectionRegions(document);
+            }
+
+            int line= document.getLineOfOffset(position.getOffset());
+            int offset= document.getLineOffset(line + 1);
+
+            int length= position.getLength() - (offset - position.getOffset());
+            if (length > 0)
+                return [new Region(offset, length)];
+
+            return null;
+        } catch (BadLocationException x) {
+            return null;
+        }
+    }
+
+    /**
+     * Computes the collapsed region anchor for the given position. Assuming
+     * that the position is the position of an expanded projection annotation,
+     * the anchor is the region that is still visible after the projection
+     * annotation has been collapsed.
+     *
+     * @param position the position
+     * @return the collapsed region anchor
+     */
+    public Position computeCollapsedRegionAnchor(Position position) {
+        try {
+            IDocument document= getDocument();
+            if (document is null)
+                return null;
+
+            int captionOffset= position.getOffset();
+            if ( cast(IProjectionPosition)position )
+                captionOffset+= (cast(IProjectionPosition) position).computeCaptionOffset(document);
+
+            IRegion lineInfo= document.getLineInformationOfOffset(captionOffset);
+            return new Position(lineInfo.getOffset() + lineInfo.getLength(), 0);
+        } catch (BadLocationException x) {
+        }
+        return null;
+    }
+
+    private void processChanges(Annotation[] annotations, bool fireRedraw, List coverage)  {
+        for (int i= 0; i < annotations.length; i++) {
+            ProjectionAnnotation annotation= cast(ProjectionAnnotation) annotations[i];
+            Position position= fProjectionAnnotationModel.getPosition(annotation);
+
+            if (position is null)
+                continue;
+
+            if (!covers(coverage, position)) {
+                if (annotation.isCollapsed()) {
+                    coverage.add(position);
+                    IRegion[] regions= computeCollapsedRegions(position);
+                    if (regions !is null)
+                        for (int j= 0; j < regions.length; j++)
+                            collapse(regions[j].getOffset(), regions[j].getLength(), fireRedraw);
+                } else {
+                    expand(position.getOffset(), position.getLength(), fireRedraw);
+                }
+            }
+        }
+    }
+
+    private bool covers(List coverage, Position position) {
+        Iterator e= coverage.iterator();
+        while (e.hasNext()) {
+            Position p= cast(Position) e.next();
+            if (p.getOffset() <= position.getOffset() && position.getOffset() + position.getLength() <= p.getOffset() + p.getLength())
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Forces this viewer to throw away any old state and to initialize its content
+     * from its projection annotation model.
+     *
+     * @throws BadLocationException in case something goes wrong during initialization
+     */
+    public final void reinitializeProjection()  {
+
+        ProjectionDocument projection= null;
+
+        ISlaveDocumentManager manager= getSlaveDocumentManager();
+        if (manager !is null) {
+            IDocument master= getDocument();
+            if (master !is null) {
+                IDocument slave= manager.createSlaveDocument(master);
+                if ( cast(ProjectionDocument)slave ) {
+                    projection= cast(ProjectionDocument) slave;
+                    addMasterDocumentRange(projection, 0, master.getLength());
+                }
+            }
+        }
+
+        if (projection !is null) {
+            Iterator e= fProjectionAnnotationModel.getAnnotationIterator();
+            while (e.hasNext()) {
+                ProjectionAnnotation annotation= cast(ProjectionAnnotation) e.next();
+                if (annotation.isCollapsed()) {
+                    Position position= fProjectionAnnotationModel.getPosition(annotation);
+                    if (position !is null) {
+                        IRegion[] regions= computeCollapsedRegions(position);
+                        if (regions !is null)
+                            for (int i= 0; i < regions.length; i++)
+                                removeMasterDocumentRange(projection, regions[i].getOffset(), regions[i].getLength());
+                    }
+                }
+            }
+
+        }
+
+        replaceVisibleDocument(projection);
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#handleVerifyEvent(dwt.events.VerifyEvent)
+     */
+    protected void handleVerifyEvent(VerifyEvent e) {
+        IRegion modelRange= event2ModelRange(e);
+        if (exposeModelRange(modelRange))
+            e.doit= false;
+        else
+            super.handleVerifyEvent(e);
+    }
+
+    /**
+     * Adds the give column as last column to this viewer's vertical ruler.
+     *
+     * @param column the column to be added
+     */
+    public void addVerticalRulerColumn(IVerticalRulerColumn column) {
+        IVerticalRuler ruler= getVerticalRuler();
+        if ( cast(CompositeRuler)ruler ) {
+            CompositeRuler compositeRuler= cast(CompositeRuler) ruler;
+            compositeRuler.addDecorator(99, column);
+        }
+    }
+
+    /**
+     * Removes the give column from this viewer's vertical ruler.
+     *
+     * @param column the column to be removed
+     */
+    public void removeVerticalRulerColumn(IVerticalRulerColumn column) {
+        IVerticalRuler ruler= getVerticalRuler();
+        if ( cast(CompositeRuler)ruler ) {
+            CompositeRuler compositeRuler= cast(CompositeRuler) ruler;
+            compositeRuler.removeDecorator(column);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextViewerExtension5#exposeModelRange(dwtx.jface.text.IRegion)
+     */
+    public bool exposeModelRange(IRegion modelRange) {
+        if (isProjectionMode())
+            return fProjectionAnnotationModel.expandAll(modelRange.getOffset(), modelRange.getLength());
+
+        if (!overlapsWithVisibleRegion(modelRange.getOffset(), modelRange.getLength())) {
+            resetVisibleRegion();
+            return true;
+        }
+
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.SourceViewer#setRangeIndication(int, int, bool)
+     */
+    public void setRangeIndication(int offset, int length, bool moveCursor) {
+        IRegion rangeIndication= getRangeIndication();
+        if (moveCursor && fProjectionAnnotationModel !is null && (rangeIndication is null || offset !is rangeIndication.getOffset() || length !is rangeIndication.getLength())) {
+            List expand= new ArrayList(2);
+            // expand the immediate effected collapsed regions
+            Iterator iterator= fProjectionAnnotationModel.getAnnotationIterator();
+            while (iterator.hasNext()) {
+                ProjectionAnnotation annotation= cast(ProjectionAnnotation)iterator.next();
+                if (annotation.isCollapsed() && willAutoExpand(fProjectionAnnotationModel.getPosition(annotation), offset, length))
+                    expand.add(annotation);
+            }
+
+            if (!expand.isEmpty()) {
+                Iterator e= expand.iterator();
+                while (e.hasNext())
+                    fProjectionAnnotationModel.expand(cast(Annotation)e.next());
+            }
+        }
+        super.setRangeIndication(offset, length, moveCursor);
+    }
+
+    private bool willAutoExpand(Position position, int offset, int length) {
+        if (position is null || position.isDeleted())
+            return false;
+        // right or left boundary
+        if (position.getOffset() is offset || position.getOffset() + position.getLength() is offset + length)
+            return true;
+        // completely embedded in given position
+        if (position.getOffset() < offset && offset + length < position.getOffset() + position.getLength())
+            return true;
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.source.SourceViewer#handleDispose()
+     * @since 3.0
+     */
+    protected void handleDispose() {
+        fWasProjectionEnabled= false;
+        super.handleDispose();
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#handleVisibleDocumentAboutToBeChanged(dwtx.jface.text.DocumentEvent)
+     */
+    protected void handleVisibleDocumentChanged(DocumentEvent event) {
+        if (fHandleProjectionChanges && cast(ProjectionDocumentEvent)event  && isProjectionMode()) {
+            ProjectionDocumentEvent e= cast(ProjectionDocumentEvent) event;
+
+            DocumentEvent master= e.getMasterEvent();
+            if (master !is null)
+                fReplaceVisibleDocumentExecutionTrigger= master.getDocument();
+
+            try {
+
+                int replaceLength= e.getText() is null ? 0 : e.getText().length();
+                if (ProjectionDocumentEvent.PROJECTION_CHANGE is e.getChangeType()) {
+                    if (e.getLength() is 0 && replaceLength !is 0)
+                        fProjectionAnnotationModel.expandAll(e.getMasterOffset(), e.getMasterLength());
+                } else if (master !is null && (replaceLength > 0 || fDeletedLines > 1)) {
+                    try {
+                        int numberOfLines= e.getDocument().getNumberOfLines(e.getOffset(), replaceLength);
+                        if (numberOfLines > 1 || fDeletedLines > 1)
+                            fProjectionAnnotationModel.expandAll(master.getOffset(), master.getLength());
+                    } catch (BadLocationException x) {
+                    }
+                }
+
+            } finally {
+                fReplaceVisibleDocumentExecutionTrigger= null;
+            }
+
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#handleVisibleDocumentAboutToBeChanged(dwtx.jface.text.DocumentEvent)
+     * @since 3.1
+     */
+    protected void handleVisibleDocumentAboutToBeChanged(DocumentEvent event) {
+        if (fHandleProjectionChanges && cast(ProjectionDocumentEvent)event  && isProjectionMode()) {
+            int deletedLines;
+            try {
+                deletedLines= event.getDocument().getNumberOfLines(event.getOffset(), event.getLength());
+            } catch (BadLocationException e1) {
+                deletedLines= 0;
+            }
+            fDeletedLines= deletedLines;
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextViewerExtension5#getCoveredModelRanges(dwtx.jface.text.IRegion)
+     */
+    public IRegion[] getCoveredModelRanges(IRegion modelRange) {
+        if (fInformationMapping is null)
+            return [ new Region(modelRange.getOffset(), modelRange.getLength()) ];
+
+        if ( cast(IDocumentInformationMappingExtension)fInformationMapping ) {
+            IDocumentInformationMappingExtension extension= cast(IDocumentInformationMappingExtension) fInformationMapping;
+            try {
+                return extension.getExactCoverage(modelRange);
+            } catch (BadLocationException x) {
+            }
+        }
+
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.ITextOperationTarget#doOperation(int)
+     */
+    public void doOperation(int operation) {
+        switch (operation) {
+            case TOGGLE:
+                if (canDoOperation(TOGGLE)) {
+                    if (!isProjectionMode()) {
+                        enableProjection();
+                    } else {
+                        expandAll();
+                        disableProjection();
+                    }
+                    return;
+                }
+        }
+
+        if (!isProjectionMode()) {
+            super.doOperation(operation);
+            return;
+        }
+
+        StyledText textWidget= getTextWidget();
+        if (textWidget is null)
+            return;
+
+        Point selection= null;
+        switch (operation) {
+
+            case CUT:
+
+                if (redraws()) {
+                    selection= getSelectedRange();
+                    if (exposeModelRange(new Region(selection.x, selection.y)))
+                        return;
+
+                    if (selection.y is 0)
+                        copyMarkedRegion(true);
+                    else
+                        copyToClipboard(selection.x, selection.y, true, textWidget);
+
+                    selection= textWidget.getSelectionRange();
+                    fireSelectionChanged(selection.x, selection.y);
+                }
+                break;
+
+            case COPY:
+
+                if (redraws()) {
+                    selection= getSelectedRange();
+                    if (selection.y is 0)
+                        copyMarkedRegion(false);
+                    else
+                        copyToClipboard(selection.x, selection.y, false, textWidget);
+                }
+                break;
+
+            case DELETE:
+
+                if (redraws()) {
+                    try {
+                        selection= getSelectedRange();
+                        Point widgetSelection= textWidget.getSelectionRange();
+                        if (selection.y is 0 || selection.y is widgetSelection.y)
+                            getTextWidget().invokeAction(ST.DELETE_NEXT);
+                        else
+                            deleteTextRange(selection.x, selection.y, textWidget);
+
+                        selection= textWidget.getSelectionRange();
+                        fireSelectionChanged(selection.x, selection.y);
+
+                    } catch (BadLocationException x) {
+                        // ignore
+                    }
+                }
+                break;
+
+
+            case EXPAND_ALL:
+                if (redraws())
+                    expandAll();
+                break;
+
+            case EXPAND:
+                if (redraws()) {
+                    expand();
+                }
+                break;
+
+            case COLLAPSE_ALL:
+                if (redraws())
+                    collapseAll();
+                break;
+
+            case COLLAPSE:
+                if (redraws()) {
+                    collapse();
+                }
+                break;
+
+            default:
+                super.doOperation(operation);
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.source.SourceViewer#canDoOperation(int)
+     */
+    public bool canDoOperation(int operation) {
+
+        switch (operation) {
+            case COLLAPSE:
+            case COLLAPSE_ALL:
+            case EXPAND:
+            case EXPAND_ALL:
+                return isProjectionMode();
+            case TOGGLE:
+                return isProjectionMode() || !isSegmented();
+        }
+
+        return super.canDoOperation(operation);
+    }
+
+    private bool isSegmented() {
+        IDocument document= getDocument();
+        int length= document is null ? 0 : document.getLength();
+        IRegion visible= getModelCoverage();
+        bool isSegmented= visible !is null && !(cast(Object)visible).opEquals(new Region(0, length));
+        return isSegmented;
+    }
+
+    private IRegion getMarkedRegion() {
+        if (getTextWidget() is null)
+            return null;
+
+        if (fMarkPosition is null || fMarkPosition.isDeleted())
+            return null;
+
+        int start= fMarkPosition.getOffset();
+        int end= getSelectedRange().x;
+
+        return start > end ? new Region (end, start - end) : new Region(start, end - start);
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#copyMarkedRegion(bool)
+     */
+    protected void copyMarkedRegion(bool delete_) {
+        IRegion markedRegion= getMarkedRegion();
+        if (markedRegion !is null)
+            copyToClipboard(markedRegion.getOffset(), markedRegion.getLength(), delete_, getTextWidget());
+    }
+
+    private void copyToClipboard(int offset, int length, bool delete_, StyledText textWidget) {
+
+        String copyText= null;
+
+        try {
+            IDocument document= getDocument();
+            copyText= document.get(offset, length);
+        } catch (BadLocationException ex) {
+            // XXX: should log here, but JFace Text has no Log
+            // As a fallback solution let the widget handle this
+            textWidget.copy();
+        }
+
+        if (copyText !is null && copyText.equals(textWidget.getSelectionText())) {
+            /*
+             * XXX: Reduce pain of https://bugs.eclipse.org/bugs/show_bug.cgi?id=64498
+             * by letting the widget handle the copy operation in this special case.
+             */
+            textWidget.copy();
+        } else if (copyText !is null) {
+
+            Clipboard clipboard= new Clipboard(textWidget.getDisplay());
+
+            try {
+                Transfer[] dataTypes= [ TextTransfer.getInstance() ];
+                Object[] data= [ stringcast(copyText) ];
+                try {
+                    clipboard.setContents(data, dataTypes);
+                } catch (DWTError e) {
+                    if (e.code !is DND.ERROR_CANNOT_SET_CLIPBOARD)
+                        throw e;
+                    /*
+                     * TODO see https://bugs.eclipse.org/bugs/show_bug.cgi?id=59459
+                     * we should either log and/or inform the user
+                     * silently fail for now.
+                     */
+                    return;
+                }
+
+            } finally {
+                clipboard.dispose();
+            }
+        }
+
+        if (delete_) {
+            try {
+                deleteTextRange(offset, length, textWidget);
+            } catch (BadLocationException x) {
+                // XXX: should log here, but JFace Text has no Log
+            }
+        }
+    }
+
+    private void deleteTextRange(int offset, int length, StyledText textWidget)  {
+        getDocument().replace(offset, length, ""); //$NON-NLS-1$
+        int widgetCaret= modelOffset2WidgetOffset(offset);
+        if (widgetCaret > -1)
+            textWidget.setSelection(widgetCaret);
+    }
+
+    /**
+     * Adapts the behavior of the super class to respect line based folding.
+     *
+     * @param widgetSelection the widget selection
+     * @return the model selection while respecting line based folding
+     */
+    protected Point widgetSelection2ModelSelection(Point widgetSelection) {
+
+        if (!isProjectionMode())
+            return super.widgetSelection2ModelSelection(widgetSelection);
+
+        /*
+         * There is one requirement that governs preservation of logical
+         * positions:
+         *
+         * 1) a selection with widget_length is 0 should never expand to have
+         * model_length > 0.
+         *
+         * There are a number of ambiguities to resolve with projection regions.
+         * A projected region P has a widget-length of zero. Its widget offset
+         * may interact with the selection S in various ways:
+         *
+         * A) P.widget_offset lies at the caret, S.widget_length is zero.
+         * Requirement 1 applies. S is *behind* P (done so by widgetRange2ModelRange).
+         *
+         * B) P.widget_offset lies inside the widget selection. This case is
+         * easy: P is included in S, which is automatically done so by
+         * widgetRange2ModelRange.
+         *
+         * C) P.widget_offset lies at S.widget_end: This is
+         * arguable - our policy is to include P if it belongs to a projection
+         * annotation that overlaps with the widget selection.
+         *
+         * D) P.widget_offset lies at S.widget_offset: Arguable - our policy
+         * is to include P if it belongs to a projection annotation that
+         * overlaps with the widget selection
+         */
+        IRegion modelSelection= widgetRange2ModelRange(new Region(widgetSelection.x, widgetSelection.y));
+        if (modelSelection is null)
+            return null;
+
+        int modelOffset= modelSelection.getOffset();
+        int modelEndOffset= modelOffset + modelSelection.getLength();
+
+        /* Case A: never expand a zero-length selection. S is *behind* P. */
+        if (widgetSelection.y is 0)
+            return new Point(modelEndOffset, 0);
+
+        int widgetSelectionExclusiveEnd= widgetSelection.x + widgetSelection.y;
+        Position[] annotationPositions= computeOverlappingAnnotationPositions(modelSelection);
+        for (int i= 0; i < annotationPositions.length; i++) {
+            IRegion[] regions= computeCollapsedRegions(annotationPositions[i]);
+            if (regions is null)
+                continue;
+            for (int j= 0; j < regions.length; j++) {
+                IRegion modelRange= regions[j];
+                IRegion widgetRange= modelRange2ClosestWidgetRange(modelRange);
+                // only take collapsed ranges, i.e. widget length is 0
+                if (widgetRange !is null && widgetRange.getLength() is 0) {
+                    int widgetOffset= widgetRange.getOffset();
+                    // D) region is collapsed at S.widget_offset
+                    if (widgetOffset is widgetSelection.x)
+                        modelOffset= Math.min(modelOffset, modelRange.getOffset());
+                    // C) region is collapsed at S.widget_end
+                    else if (widgetOffset is widgetSelectionExclusiveEnd)
+                        modelEndOffset= Math.max(modelEndOffset, modelRange.getOffset() + modelRange.getLength());
+                }
+            }
+        }
+        return new Point(modelOffset, modelEndOffset - modelOffset);
+    }
+
+    /**
+     * Returns the positions of all annotations that intersect with
+     * <code>modelSelection</code> and that are at least partly visible.
+     * @param modelSelection a model range
+     * @return the positions of all annotations that intersect with
+     *         <code>modelSelection</code>
+     * @since 3.1
+     */
+    private Position[] computeOverlappingAnnotationPositions(IRegion modelSelection) {
+        List positions= new ArrayList();
+        for (Iterator e= fProjectionAnnotationModel.getAnnotationIterator(); e.hasNext();) {
+            ProjectionAnnotation annotation= cast(ProjectionAnnotation) e.next();
+            Position position= fProjectionAnnotationModel.getPosition(annotation);
+            if (position !is null && position.overlapsWith(modelSelection.getOffset(), modelSelection.getLength()) && modelRange2WidgetRange(position) !is null)
+                positions.add(position);
+        }
+        return arraycast!(Position)( positions.toArray());
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#getFindReplaceDocumentAdapter()
+     */
+    protected FindReplaceDocumentAdapter getFindReplaceDocumentAdapter() {
+        if (fFindReplaceDocumentAdapter is null) {
+            IDocument document= isProjectionMode() ? getDocument() : getVisibleDocument();
+            fFindReplaceDocumentAdapter= new FindReplaceDocumentAdapter(document);
+        }
+        return fFindReplaceDocumentAdapter;
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#findAndSelect(int, java.lang.String, bool, bool, bool, bool)
+     */
+    protected int findAndSelect(int startPosition, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord, bool regExSearch) {
+
+        if (!isProjectionMode())
+            return super.findAndSelect(startPosition, findString, forwardSearch, caseSensitive, wholeWord, regExSearch);
+
+        StyledText textWidget= getTextWidget();
+        if (textWidget is null)
+            return -1;
+
+        try {
+
+            IRegion matchRegion= getFindReplaceDocumentAdapter().find(startPosition, findString, forwardSearch, caseSensitive, wholeWord, regExSearch);
+            if (matchRegion !is null) {
+                exposeModelRange(matchRegion);
+                revealRange(matchRegion.getOffset(), matchRegion.getLength());
+                setSelectedRange(matchRegion.getOffset(), matchRegion.getLength());
+                return matchRegion.getOffset();
+            }
+
+        } catch (BadLocationException x) {
+        }
+
+        return -1;
+    }
+
+    /*
+     * @see dwtx.jface.text.TextViewer#findAndSelectInRange(int, java.lang.String, bool, bool, bool, int, int, bool)
+     */
+    protected int findAndSelectInRange(int startPosition, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord, int rangeOffset, int rangeLength, bool regExSearch) {
+
+        if (!isProjectionMode())
+            return super.findAndSelectInRange(startPosition, findString, forwardSearch, caseSensitive, wholeWord, rangeOffset, rangeLength, regExSearch);
+
+        StyledText textWidget= getTextWidget();
+        if (textWidget is null)
+            return -1;
+
+        try {
+
+            int modelOffset= startPosition;
+            if (forwardSearch && (startPosition is -1 || startPosition < rangeOffset)) {
+                modelOffset= rangeOffset;
+            } else if (!forwardSearch && (startPosition is -1 || startPosition > rangeOffset + rangeLength)) {
+                modelOffset= rangeOffset + rangeLength;
+            }
+
+            IRegion matchRegion= getFindReplaceDocumentAdapter().find(modelOffset, findString, forwardSearch, caseSensitive, wholeWord, regExSearch);
+            if (matchRegion !is null) {
+                int offset= matchRegion.getOffset();
+                int length= matchRegion.getLength();
+                if (rangeOffset <= offset && offset + length <= rangeOffset + rangeLength) {
+                    exposeModelRange(matchRegion);
+                    revealRange(offset, length);
+                    setSelectedRange(offset, length);
+                    return offset;
+                }
+            }
+
+        } catch (BadLocationException x) {
+        }
+
+        return -1;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/source/projection/SourceViewerInformationControl.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,451 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.source.projection.SourceViewerInformationControl;
+
+import dwtx.jface.text.source.projection.ProjectionViewer; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSupport; // packageimport
+import dwtx.jface.text.source.projection.IProjectionPosition; // packageimport
+import dwtx.jface.text.source.projection.AnnotationBag; // packageimport
+import dwtx.jface.text.source.projection.ProjectionSummary; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationHover; // packageimport
+import dwtx.jface.text.source.projection.ProjectionRulerColumn; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotationModel; // packageimport
+import dwtx.jface.text.source.projection.IProjectionListener; // packageimport
+import dwtx.jface.text.source.projection.ProjectionAnnotation; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+
+
+import dwt.DWT;
+import dwt.custom.StyledText;
+import dwt.events.DisposeEvent;
+import dwt.events.DisposeListener;
+import dwt.events.FocusListener;
+import dwt.events.KeyEvent;
+import dwt.events.KeyListener;
+import dwt.graphics.Color;
+import dwt.graphics.Font;
+import dwt.graphics.FontData;
+import dwt.graphics.GC;
+import dwt.graphics.Point;
+import dwt.graphics.Rectangle;
+import dwt.layout.GridData;
+import dwt.layout.GridLayout;
+import dwt.widgets.Composite;
+import dwt.widgets.Control;
+import dwt.widgets.Display;
+import dwt.widgets.Label;
+import dwt.widgets.Shell;
+import dwtx.jface.resource.JFaceResources;
+import dwtx.jface.text.Document;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IInformationControl;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.IInformationControlExtension;
+import dwtx.jface.text.IInformationControlExtension3;
+import dwtx.jface.text.IInformationControlExtension5;
+import dwtx.jface.text.source.SourceViewer;
+import dwtx.jface.text.source.SourceViewerConfiguration;
+
+/**
+ * Source viewer based implementation of {@link dwtx.jface.text.IInformationControl}.
+ * Displays information in a source viewer.
+ *
+ * @since 3.0
+ */
+class SourceViewerInformationControl : IInformationControl, IInformationControlExtension, IInformationControlExtension3, IInformationControlExtension5, DisposeListener {
+
+    /** The control's shell */
+    private Shell fShell;
+    /** The control's text widget */
+    private StyledText fText;
+    /** The symbolic font name of the text font */
+    private const String fSymbolicFontName;
+    /** The text font (do not dispose!) */
+    private Font fTextFont;
+    /** The control's source viewer */
+    private SourceViewer fViewer;
+    /** The optional status field. */
+    private Label fStatusField;
+    /** The separator for the optional status field. */
+    private Label fSeparator;
+    /** The font of the optional status text label.*/
+    private Font fStatusTextFont;
+    /** The maximal widget width. */
+    private int fMaxWidth;
+    /** The maximal widget height. */
+    private int fMaxHeight;
+
+
+    /**
+     * Creates a source viewer information control with the given shell as parent. The given shell
+     * styles are applied to the created shell. The given styles are applied to the created styled
+     * text widget. The text widget will be initialized with the given font. The status field will
+     * contain the given text or be hidden.
+     *
+     * @param parent the parent shell
+     * @param isResizable <code>true</code> if resizable
+     * @param symbolicFontName the symbolic font name
+     * @param statusFieldText the text to be used in the optional status field or <code>null</code>
+     *            if the status field should be hidden
+     */
+    public this(Shell parent, bool isResizable, String symbolicFontName, String statusFieldText) {
+        GridLayout layout;
+        GridData gd;
+
+        int shellStyle= DWT.TOOL | DWT.ON_TOP | (isResizable ? DWT.RESIZE : 0);
+        int textStyle= isResizable ? DWT.V_SCROLL | DWT.H_SCROLL : DWT.NONE;
+
+        fShell= new Shell(parent, DWT.NO_FOCUS | DWT.ON_TOP | shellStyle);
+        Display display= fShell.getDisplay();
+
+        Composite composite= fShell;
+        layout= new GridLayout(1, false);
+        layout.marginHeight= 0;
+        layout.marginWidth= 0;
+        composite.setLayout(layout);
+        gd= new GridData(GridData.FILL_HORIZONTAL);
+        composite.setLayoutData(gd);
+
+        if (statusFieldText !is null) {
+            composite= new Composite(composite, DWT.NONE);
+            layout= new GridLayout(1, false);
+            layout.marginHeight= 0;
+            layout.marginWidth= 0;
+            composite.setLayout(layout);
+            gd= new GridData(GridData.FILL_BOTH);
+            composite.setLayoutData(gd);
+            composite.setForeground(display.getSystemColor(DWT.COLOR_INFO_FOREGROUND));
+            composite.setBackground(display.getSystemColor(DWT.COLOR_INFO_BACKGROUND));
+        }
+
+        // Source viewer
+        fViewer= new SourceViewer(composite, null, textStyle);
+        fViewer.configure(new SourceViewerConfiguration());
+        fViewer.setEditable(false);
+
+        fText= fViewer.getTextWidget();
+        gd= new GridData(GridData.BEGINNING | GridData.FILL_BOTH);
+        fText.setLayoutData(gd);
+        fText.setForeground(parent.getDisplay().getSystemColor(DWT.COLOR_INFO_FOREGROUND));
+        fText.setBackground(parent.getDisplay().getSystemColor(DWT.COLOR_INFO_BACKGROUND));
+        fSymbolicFontName= symbolicFontName;
+        fTextFont= JFaceResources.getFont(symbolicFontName);
+        fText.setFont(fTextFont);
+
+        fText.addKeyListener(new class()  KeyListener {
+
+            public void keyPressed(KeyEvent e)  {
+                if (e.character is 0x1B) // ESC
+                    fShell.dispose();
+            }
+
+            public void keyReleased(KeyEvent e) {}
+        });
+
+        // Status field
+        if (statusFieldText !is null) {
+
+            // Horizontal separator line
+            fSeparator= new Label(composite, DWT.SEPARATOR | DWT.HORIZONTAL | DWT.LINE_DOT);
+            fSeparator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
+
+            // Status field label
+            fStatusField= new Label(composite, DWT.RIGHT);
+            fStatusField.setText(statusFieldText);
+            Font font= fStatusField.getFont();
+            FontData[] fontDatas= font.getFontData();
+            for (int i= 0; i < fontDatas.length; i++)
+                fontDatas[i].setHeight(fontDatas[i].getHeight() * 9 / 10);
+            fStatusTextFont= new Font(fStatusField.getDisplay(), fontDatas);
+            fStatusField.setFont(fStatusTextFont);
+            GridData gd2= new GridData(GridData.FILL_VERTICAL | GridData.FILL_HORIZONTAL | GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
+            fStatusField.setLayoutData(gd2);
+
+            // Regarding the color see bug 41128
+            fStatusField.setForeground(display.getSystemColor(DWT.COLOR_WIDGET_DARK_SHADOW));
+
+            fStatusField.setBackground(display.getSystemColor(DWT.COLOR_INFO_BACKGROUND));
+        }
+
+        addDisposeListener(this);
+    }
+
+    /**
+     * @see dwtx.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
+     * @param input the input object
+     */
+    public void setInput(Object input) {
+        if ( cast(ArrayWrapperString)input )
+            setInformation(stringcast(input));
+        else
+            setInformation(null);
+    }
+
+    /*
+     * @see IInformationControl#setInformation(String)
+     */
+    public void setInformation(String content) {
+        if (content is null) {
+            fViewer.setInput(null);
+            return;
+        }
+
+        IDocument doc= new Document(content);
+        fViewer.setInput(cast(Object)doc);
+    }
+
+    /*
+     * @see IInformationControl#setVisible(bool)
+     */
+    public void setVisible(bool visible) {
+            fShell.setVisible(visible);
+    }
+
+    /*
+     * @see dwt.events.DisposeListener#widgetDisposed(dwt.events.DisposeEvent)
+     */
+    public void widgetDisposed(DisposeEvent event) {
+        if (fStatusTextFont !is null && !fStatusTextFont.isDisposed())
+            fStatusTextFont.dispose();
+
+        fStatusTextFont= null;
+        fTextFont= null;
+        fShell= null;
+        fText= null;
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControl#dispose()
+     */
+    public final void dispose() {
+        if (fShell !is null && !fShell.isDisposed())
+            fShell.dispose();
+        else
+            widgetDisposed(null);
+    }
+
+    /*
+     * @see IInformationControl#setSize(int, int)
+     */
+    public void setSize(int width, int height) {
+
+        if (fStatusField !is null) {
+            GridData gd= cast(GridData)fViewer.getTextWidget().getLayoutData();
+            Point statusSize= fStatusField.computeSize(DWT.DEFAULT, DWT.DEFAULT, true);
+            Point separatorSize= fSeparator.computeSize(DWT.DEFAULT, DWT.DEFAULT, true);
+            gd.heightHint= height - statusSize.y - separatorSize.y;
+        }
+        fShell.setSize(width, height);
+
+        if (fStatusField !is null)
+            fShell.pack(true);
+    }
+
+    /*
+     * @see IInformationControl#setLocation(Point)
+     */
+    public void setLocation(Point location) {
+        fShell.setLocation(location);
+    }
+
+    /*
+     * @see IInformationControl#setSizeConstraints(int, int)
+     */
+    public void setSizeConstraints(int maxWidth, int maxHeight) {
+        fMaxWidth= maxWidth;
+        fMaxHeight= maxHeight;
+    }
+
+    /*
+     * @see IInformationControl#computeSizeHint()
+     */
+    public Point computeSizeHint() {
+        // compute the preferred size
+        int x= DWT.DEFAULT;
+        int y= DWT.DEFAULT;
+        Point size= fShell.computeSize(x, y);
+        if (size.x > fMaxWidth)
+            x= fMaxWidth;
+        if (size.y > fMaxHeight)
+            y= fMaxHeight;
+
+        // recompute using the constraints if the preferred size is larger than the constraints
+        if (x !is DWT.DEFAULT || y !is DWT.DEFAULT)
+            size= fShell.computeSize(x, y, false);
+
+        return size;
+    }
+
+    /*
+     * @see IInformationControl#addDisposeListener(DisposeListener)
+     */
+    public void addDisposeListener(DisposeListener listener) {
+        fShell.addDisposeListener(listener);
+    }
+
+    /*
+     * @see IInformationControl#removeDisposeListener(DisposeListener)
+     */
+    public void removeDisposeListener(DisposeListener listener) {
+        fShell.removeDisposeListener(listener);
+    }
+
+    /*
+     * @see IInformationControl#setForegroundColor(Color)
+     */
+    public void setForegroundColor(Color foreground) {
+        fText.setForeground(foreground);
+    }
+
+    /*
+     * @see IInformationControl#setBackgroundColor(Color)
+     */
+    public void setBackgroundColor(Color background) {
+        fText.setBackground(background);
+    }
+
+    /*
+     * @see IInformationControl#isFocusControl()
+     */
+    public bool isFocusControl() {
+        return fShell.getDisplay().getActiveShell() is fShell;
+    }
+
+    /*
+     * @see IInformationControl#setFocus()
+     */
+    public void setFocus() {
+        fShell.forceFocus();
+        fText.setFocus();
+    }
+
+    /*
+     * @see IInformationControl#addFocusListener(FocusListener)
+     */
+    public void addFocusListener(FocusListener listener) {
+        fText.addFocusListener(listener);
+    }
+
+    /*
+     * @see IInformationControl#removeFocusListener(FocusListener)
+     */
+    public void removeFocusListener(FocusListener listener) {
+        fText.removeFocusListener(listener);
+    }
+
+    /*
+     * @see IInformationControlExtension#hasContents()
+     */
+    public bool hasContents() {
+        return fText.getCharCount() > 0;
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension3#computeTrim()
+     * @since 3.4
+     */
+    public Rectangle computeTrim() {
+        Rectangle trim= fShell.computeTrim(0, 0, 0, 0);
+        addInternalTrim(trim);
+        return trim;
+    }
+
+    /**
+     * Adds the internal trimmings to the given trim of the shell.
+     *
+     * @param trim the shell's trim, will be updated
+     * @since 3.4
+     */
+    private void addInternalTrim(Rectangle trim) {
+        if (fStatusField !is null) {
+            trim.height+= fSeparator.computeSize(DWT.DEFAULT, DWT.DEFAULT).y;
+            trim.height+= fStatusField.computeSize(DWT.DEFAULT, DWT.DEFAULT).y;
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension3#getBounds()
+     * @since 3.4
+     */
+    public Rectangle getBounds() {
+        return fShell.getBounds();
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension3#restoresLocation()
+     * @since 3.4
+     */
+    public bool restoresLocation() {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension3#restoresSize()
+     * @since 3.4
+     */
+    public bool restoresSize() {
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension5#getInformationPresenterControlCreator()
+     * @since 3.4
+     */
+    public IInformationControlCreator getInformationPresenterControlCreator() {
+        return new class()  IInformationControlCreator {
+            public IInformationControl createInformationControl(Shell parent) {
+                return new SourceViewerInformationControl(parent, true, fSymbolicFontName, null);
+            }
+        };
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension5#containsControl(dwt.widgets.Control)
+     * @since 3.4
+     */
+    public bool containsControl(Control control) {
+        do {
+            if (control is fShell)
+                return true;
+            if ( cast(Shell)control )
+                return false;
+            control= control.getParent();
+        } while (control !is null);
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension5#isVisible()
+     * @since 3.4
+     */
+    public bool isVisible() {
+        return fShell !is null && !fShell.isDisposed() && fShell.isVisible();
+    }
+
+    /*
+     * @see dwtx.jface.text.IInformationControlExtension5#computeSizeConstraints(int, int)
+     */
+    public Point computeSizeConstraints(int widthInChars, int heightInChars) {
+        GC gc= new GC(fText);
+        gc.setFont(fTextFont);
+        int width= gc.getFontMetrics().getAverageCharWidth();
+        int height = gc.getFontMetrics().getHeight();
+        gc.dispose();
+
+        return new Point (widthInChars * width, heightInChars * height);
+    }
+}
Binary file dwtx/jface/text/source/projection/images/collapsed.gif has changed
Binary file dwtx/jface/text/source/projection/images/expanded.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/ContextTypeRegistry.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.ContextTypeRegistry;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+/**
+ * A registry for context types. Editor implementors will usually instantiate a
+ * registry and configure the context types available in their editor.
+ * <p>
+ * In order to pick up templates contributed using the <code>dwtx.ui.editors.templates</code>
+ * extension point, use a <code>ContributionContextTypeRegistry</code>.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class ContextTypeRegistry {
+
+    /** all known context types */
+    private const Map fContextTypes;
+
+    this(){
+        fContextTypes= new LinkedHashMap();
+    }
+    /**
+     * Adds a context type to the registry. If there already is a context type
+     * with the same ID registered, it is replaced.
+     *
+     * @param contextType the context type to add
+     */
+    public void addContextType(TemplateContextType contextType) {
+        fContextTypes.put(contextType.getId(), contextType);
+    }
+
+    /**
+     * Returns the context type if the id is valid, <code>null</code> otherwise.
+     *
+     * @param id the id of the context type to retrieve
+     * @return the context type if <code>name</code> is valid, <code>null</code> otherwise
+     */
+    public TemplateContextType getContextType(String id) {
+        return cast(TemplateContextType) fContextTypes.get(id);
+    }
+
+    /**
+     * Returns an iterator over all registered context types.
+     *
+     * @return an iterator over all registered context types
+     */
+    public Iterator contextTypes() {
+        return fContextTypes.values().iterator();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/DocumentTemplateContext.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.DocumentTemplateContext;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.Position;
+
+/**
+ * Instances of this class describe the context of a template as a region of
+ * a document. That region may be either specified by its offset and length, or
+ * by a <code>Position</code> which may or may not be registered with the
+ * document.
+ * <p>
+ * Clients may instantiate and extend this class.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class DocumentTemplateContext : TemplateContext {
+
+    /** The text of the document. */
+    private const IDocument fDocument;
+    /**
+     * The region of the document described by this context. We store a
+     * position since clients may specify the document region as (updateable)
+     * Positions.
+     */
+    private const Position fPosition;
+    /**
+     * The original offset of this context. Will only be updated by the setter
+     * method.
+     */
+    private int fOriginalOffset;
+    /**
+     * The original length of this context. Will only be updated by the setter
+     * method.
+     */
+    private int fOriginalLength;
+
+    /**
+     * Creates a document template context.
+     *
+     * @param type the context type
+     * @param document the document this context applies to
+     * @param offset the offset of the document region
+     * @param length the length of the document region
+     */
+    public this(TemplateContextType type, IDocument document, int offset, int length) {
+        this(type, document, new Position(offset, length));
+    }
+
+    /**
+     * Creates a document template context. The supplied <code>Position</code>
+     * will be queried to compute the <code>getStart</code> and
+     * <code>getEnd</code> methods, which will therefore answer updated
+     * position data if it is registered with the document.
+     *
+     * @param type the context type
+     * @param document the document this context applies to
+     * @param position the position describing the area of the document which
+     *        forms the template context
+     * @since 3.1
+     */
+    public this(TemplateContextType type, IDocument document, Position position) {
+        super(type);
+
+        Assert.isNotNull(cast(Object)document);
+        Assert.isNotNull(position);
+        Assert.isTrue(position.getOffset() <= document.getLength());
+
+        fDocument= document;
+        fPosition= position;
+        fOriginalOffset= fPosition.getOffset();
+        fOriginalLength= fPosition.getLength();
+    }
+
+    /**
+     * Returns the document.
+     *
+     * @return the document
+     */
+    public IDocument getDocument() {
+        return fDocument;
+    }
+
+    /**
+     * Returns the completion offset within the string of the context.
+     *
+     * @return the completion offset within the string of the context
+     */
+    public int getCompletionOffset() {
+        return fOriginalOffset;
+    }
+
+    /**
+     * Sets the completion offset.
+     *
+     * @param newOffset the new completion offset
+     */
+    protected void setCompletionOffset(int newOffset) {
+        fOriginalOffset= newOffset;
+        fPosition.setOffset(newOffset);
+    }
+
+    /**
+     * Returns the completion length within the string of the context.
+     *
+     * @return the completion length within the string of the context
+     */
+    public int getCompletionLength() {
+        return fOriginalLength;
+    }
+
+    /**
+     * Sets the completion length.
+     *
+     * @param newLength the new completion length
+     */
+    protected void setCompletionLength(int newLength) {
+        fOriginalLength= newLength;
+        fPosition.setLength(newLength);
+    }
+
+    /**
+     * Returns the keyword which triggered template insertion.
+     *
+     * @return the keyword which triggered template insertion
+     */
+    public String getKey() {
+        int offset= getStart();
+        int length= getEnd() - offset;
+        try {
+            return fDocument.get(offset, length);
+        } catch (BadLocationException e) {
+            return ""; //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Returns the beginning offset of the keyword.
+     *
+     * @return the beginning offset of the keyword
+     */
+    public int getStart() {
+        return fPosition.getOffset();
+    }
+
+    /**
+     * Returns the end offset of the keyword.
+     *
+     * @return the end offset of the keyword
+     */
+    public int getEnd() {
+        return fPosition.getOffset() + fPosition.getLength();
+    }
+
+    /*
+     * @see dwtx.jface.text.templates.TemplateContext#canEvaluate(dwtx.jface.text.templates.Template)
+     */
+    public bool canEvaluate(Template template_) {
+        return true;
+    }
+
+    /*
+     * @see dwtx.jface.text.templates.TemplateContext#evaluate(dwtx.jface.text.templates.Template)
+     */
+    public TemplateBuffer evaluate(Template template_)  {
+        if (!canEvaluate(template_))
+            return null;
+
+        TemplateTranslator translator= new TemplateTranslator();
+        TemplateBuffer buffer= translator.translate(template_);
+
+        getContextType().resolve(buffer, this);
+
+        return buffer;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/GlobalTemplateVariables.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *     Sebastian Davids: sdavids@gmx.de - see bug 25376
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.GlobalTemplateVariables;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+// import com.ibm.icu.text.DateFormat;
+// import com.ibm.icu.util.Calendar;
+
+/**
+ * Global variables which are available in any context.
+ * <p>
+ * Clients may instantiate the classes contained within this class.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class GlobalTemplateVariables {
+
+    /** The type of the selection variables. */
+    public static const String SELECTION= "selection"; //$NON-NLS-1$
+
+    /**
+     * The cursor variable determines the cursor placement after template edition.
+     */
+    public static class Cursor : SimpleTemplateVariableResolver {
+
+        /** Name of the cursor variable, value= {@value} */
+        public static const String NAME= "cursor"; //$NON-NLS-1$
+
+        /**
+         * Creates a new cursor variable
+         */
+        public this() {
+            super(NAME, TextTemplateMessages.getString("GlobalVariables.variable.description.cursor")); //$NON-NLS-1$
+            setEvaluationString(""); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * The word selection variable determines templates that work on a full
+     * lines selection.
+     */
+    public static class WordSelection : SimpleTemplateVariableResolver {
+
+        /** Name of the word selection variable, value= {@value} */
+        public static const String NAME= "word_selection"; //$NON-NLS-1$
+
+        /**
+         * Creates a new word selection variable
+         */
+        public this() {
+            super(NAME, TextTemplateMessages.getString("GlobalVariables.variable.description.selectedWord")); //$NON-NLS-1$
+        }
+        protected String resolve(TemplateContext context) {
+            String selection= context.getVariable(SELECTION);
+            if (selection is null)
+                return ""; //$NON-NLS-1$
+            return selection;
+        }
+    }
+
+    /**
+     * The line selection variable determines templates that work on selected
+     * lines.
+     */
+    public static class LineSelection : SimpleTemplateVariableResolver {
+
+        /** Name of the line selection variable, value= {@value} */
+        public static const String NAME= "line_selection"; //$NON-NLS-1$
+
+        /**
+         * Creates a new line selection variable
+         */
+        public this() {
+            super(NAME, TextTemplateMessages.getString("GlobalVariables.variable.description.selectedLines")); //$NON-NLS-1$
+        }
+        protected String resolve(TemplateContext context) {
+            String selection= context.getVariable(SELECTION);
+            if (selection is null)
+                return ""; //$NON-NLS-1$
+            return selection;
+        }
+    }
+
+    /**
+     * The dollar variable inserts an escaped dollar symbol.
+     */
+    public static class Dollar : SimpleTemplateVariableResolver {
+        /**
+         * Creates a new dollar variable
+         */
+        public this() {
+            super("dollar", TextTemplateMessages.getString("GlobalVariables.variable.description.dollar")); //$NON-NLS-1$ //$NON-NLS-2$
+            setEvaluationString("$"); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * The date variable evaluates to the current date.
+     */
+    public static class Date : SimpleTemplateVariableResolver {
+        /**
+         * Creates a new date variable
+         */
+        public this() {
+            super("date", TextTemplateMessages.getString("GlobalVariables.variable.description.date")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        protected String resolve(TemplateContext context) {
+            implMissing(__FILE__,__LINE__);
+            return null;
+            //return DateFormat.getDateInstance().format(new java.util.Date());
+        }
+    }
+
+    /**
+     * The year variable evaluates to the current year.
+     */
+    public static class Year : SimpleTemplateVariableResolver {
+        /**
+         * Creates a new year variable
+         */
+        public this() {
+            super("year", TextTemplateMessages.getString("GlobalVariables.variable.description.year")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+        protected String resolve(TemplateContext context) {
+            implMissing(__FILE__,__LINE__);
+            return null;
+            //return Integer.toString(Calendar.getInstance().get(Calendar.YEAR));
+        }
+    }
+
+    /**
+     * The time variable evaluates to the current time.
+     */
+    public static class Time : SimpleTemplateVariableResolver {
+        /**
+         * Creates a new time variable
+         */
+        public this() {
+            super("time", TextTemplateMessages.getString("GlobalVariables.variable.description.time")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        protected String resolve(TemplateContext context) {
+            implMissing(__FILE__,__LINE__);
+            return null;
+            //return DateFormat.getTimeInstance().format(new java.util.Date());
+        }
+    }
+
+    /**
+     * The user variable evaluates to the current user.
+     */
+    public static class User : SimpleTemplateVariableResolver {
+        /**
+         * Creates a new user name variable
+         */
+        public this() {
+            super("user", TextTemplateMessages.getString("GlobalVariables.variable.description.user")); //$NON-NLS-1$ //$NON-NLS-2$
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        protected String resolve(TemplateContext context) {
+            return System.getProperty("user.name"); //$NON-NLS-1$
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/InclusivePositionUpdater.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.InclusivePositionUpdater;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IPositionUpdater;
+import dwtx.jface.text.Position;
+
+/**
+ * Position updater that takes any change in [position.offset, position.offset + position.length] as
+ * belonging to the position.
+ *
+ * @since 3.0
+ */
+class InclusivePositionUpdater : IPositionUpdater {
+
+    /** The position category. */
+    private const String fCategory;
+
+    /**
+     * Creates a new updater for the given <code>category</code>.
+     *
+     * @param category the new category.
+     */
+    public this(String category) {
+        fCategory= category;
+    }
+
+    /*
+     * @see dwtx.jface.text.IPositionUpdater#update(dwtx.jface.text.DocumentEvent)
+     */
+    public void update(DocumentEvent event) {
+
+        int eventOffset= event.getOffset();
+        int eventOldLength= event.getLength();
+        int eventNewLength= event.getText() is null ? 0 : event.getText().length();
+        int deltaLength= eventNewLength - eventOldLength;
+
+        try {
+            Position[] positions= event.getDocument().getPositions(fCategory);
+
+            for (int i= 0; i !is positions.length; i++) {
+
+                Position position= positions[i];
+
+                if (position.isDeleted())
+                    continue;
+
+                int offset= position.getOffset();
+                int length= position.getLength();
+                int end= offset + length;
+
+                if (offset > eventOffset + eventOldLength)
+                    // position comes way
+                    // after change - shift
+                    position.setOffset(offset + deltaLength);
+                else if (end < eventOffset) {
+                    // position comes way before change -
+                    // leave alone
+                } else if (offset <= eventOffset && end >= eventOffset + eventOldLength) {
+                    // event completely internal to the position - adjust length
+                    position.setLength(length + deltaLength);
+                } else if (offset < eventOffset) {
+                    // event extends over end of position - adjust length
+                    int newEnd= eventOffset + eventNewLength;
+                    position.setLength(newEnd - offset);
+                } else if (end > eventOffset + eventOldLength) {
+                    // event extends from before position into it - adjust offset
+                    // and length
+                    // offset becomes end of event, length adjusted accordingly
+                    // we want to recycle the overlapping part
+                    position.setOffset(eventOffset);
+                    int deleted= eventOffset + eventOldLength - offset;
+                    position.setLength(length - deleted + eventNewLength);
+                } else {
+                    // event consumes the position - delete it
+                    position.delete_();
+                }
+            }
+        } catch (BadPositionCategoryException e) {
+            // ignore and return
+        }
+    }
+
+    /**
+     * Returns the position category.
+     *
+     * @return the position category
+     */
+    public String getCategory() {
+        return fCategory;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/JFaceTextTemplateMessages.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.JFaceTextTemplateMessages;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.dwthelper.ResourceBundle;
+import dwtx.dwtxhelper.MessageFormat;
+
+/**
+ * @since 3.0
+ */
+class JFaceTextTemplateMessages {
+
+//     private static const String RESOURCE_BUNDLE= JFaceTextTemplateMessages.classinfo.getName();
+    private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+    static this() {
+        fgResourceBundle = ResourceBundle.getBundle(
+            getImportData!("dwtx.jface.text.templates.JFaceTextTemplateMessages.properties"));
+    }
+
+    private this() {
+    }
+
+    public static String getString(String key) {
+        try {
+            return fgResourceBundle.getString(key);
+        } catch (MissingResourceException e) {
+            return '!' ~ key ~ '!';
+        }
+    }
+
+    public static String getFormattedString(String key, Object[] args... ) {
+        return MessageFormat.format(getString(key), args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/PositionBasedCompletionProposal.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,194 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.templates.PositionBasedCompletionProposal;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+
+
+
+import dwt.graphics.Image;
+import dwt.graphics.Point;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.contentassist.ICompletionProposal;
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2;
+import dwtx.jface.text.contentassist.IContextInformation;
+
+
+/**
+ * A position based completion proposal.
+ * 
+ * @since 3.0
+ */
+final class PositionBasedCompletionProposal : ICompletionProposal, ICompletionProposalExtension2 {
+
+    /** The string to be displayed in the completion proposal popup */
+    private String fDisplayString;
+    /** The replacement string */
+    private String fReplacementString;
+    /** The replacement position. */
+    private Position fReplacementPosition;
+    /** The cursor position after this proposal has been applied */
+    private int fCursorPosition;
+    /** The image to be displayed in the completion proposal popup */
+    private Image fImage;
+    /** The context information of this proposal */
+    private IContextInformation fContextInformation;
+    /** The additional info of this proposal */
+    private String fAdditionalProposalInfo;
+
+    /**
+     * Creates a new completion proposal based on the provided information.  The replacement string is
+     * considered being the display string too. All remaining fields are set to <code>null</code>.
+     *
+     * @param replacementString the actual string to be inserted into the document
+     * @param replacementPosition the position of the text to be replaced
+     * @param cursorPosition the position of the cursor following the insert relative to replacementOffset
+     */
+    public this(String replacementString, Position replacementPosition, int cursorPosition) {
+        this(replacementString, replacementPosition, cursorPosition, null, null, null, null);
+    }
+
+    /**
+     * Creates a new completion proposal. All fields are initialized based on the provided information.
+     *
+     * @param replacementString the actual string to be inserted into the document
+     * @param replacementPosition the position of the text to be replaced
+     * @param cursorPosition the position of the cursor following the insert relative to replacementOffset
+     * @param image the image to display for this proposal
+     * @param displayString the string to be displayed for the proposal
+     * @param contextInformation the context information associated with this proposal
+     * @param additionalProposalInfo the additional information associated with this proposal
+     */
+    public this(String replacementString, Position replacementPosition, int cursorPosition, Image image, String displayString, IContextInformation contextInformation, String additionalProposalInfo) {
+        Assert.isNotNull(replacementString);
+        Assert.isTrue(replacementPosition !is null);
+
+        fReplacementString= replacementString;
+        fReplacementPosition= replacementPosition;
+        fCursorPosition= cursorPosition;
+        fImage= image;
+        fDisplayString= displayString;
+        fContextInformation= contextInformation;
+        fAdditionalProposalInfo= additionalProposalInfo;
+    }
+
+    /*
+     * @see ICompletionProposal#apply(IDocument)
+     */
+    public void apply(IDocument document) {
+        try {
+            document.replace(fReplacementPosition.getOffset(), fReplacementPosition.getLength(), fReplacementString);
+        } catch (BadLocationException x) {
+            // ignore
+        }
+    }
+
+    /*
+     * @see ICompletionProposal#getSelection(IDocument)
+     */
+    public Point getSelection(IDocument document) {
+        return new Point(fReplacementPosition.getOffset() + fCursorPosition, 0);
+    }
+
+    /*
+     * @see ICompletionProposal#getContextInformation()
+     */
+    public IContextInformation getContextInformation() {
+        return fContextInformation;
+    }
+
+    /*
+     * @see ICompletionProposal#getImage()
+     */
+    public Image getImage() {
+        return fImage;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposal#getDisplayString()
+     */
+    public String getDisplayString() {
+        if (fDisplayString !is null)
+            return fDisplayString;
+        return fReplacementString;
+    }
+
+    /*
+     * @see ICompletionProposal#getAdditionalProposalInfo()
+     */
+    public String getAdditionalProposalInfo() {
+        return fAdditionalProposalInfo;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#apply(dwtx.jface.text.ITextViewer, char, int, int)
+     */
+    public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
+        apply(viewer.getDocument());
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#selected(dwtx.jface.text.ITextViewer, bool)
+     */
+    public void selected(ITextViewer viewer, bool smartToggle) {
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#unselected(dwtx.jface.text.ITextViewer)
+     */
+    public void unselected(ITextViewer viewer) {
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#validate(dwtx.jface.text.IDocument, int, dwtx.jface.text.DocumentEvent)
+     */
+    public bool validate(IDocument document, int offset, DocumentEvent event) {
+        try {
+            String content= document.get(fReplacementPosition.getOffset(), offset - fReplacementPosition.getOffset());
+            if (fReplacementString.startsWith(content))
+                return true;
+        } catch (BadLocationException e) {
+            // ignore concurrently modified document
+        }
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/SimpleTemplateVariableResolver.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.SimpleTemplateVariableResolver;
+
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * A simple template variable resolver, which always evaluates to a defined string.
+ * <p>
+ * Clients may instantiate and extend this class.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class SimpleTemplateVariableResolver : TemplateVariableResolver {
+
+    /** The string to which this variable evaluates. */
+    private String fEvaluationString;
+
+    /*
+     * @see TemplateVariableResolver#TemplateVariableResolver(String, String)
+     */
+    protected this(String type, String description) {
+        super(type, description);
+    }
+
+    /**
+     * Sets the string to which this variable evaluates.
+     *
+     * @param evaluationString the evaluation string, may be <code>null</code>.
+     */
+    public final void setEvaluationString(String evaluationString) {
+        fEvaluationString= evaluationString;
+    }
+
+    /*
+     * @see TemplateVariableResolver#evaluate(TemplateContext)
+     */
+    protected String resolve(TemplateContext context) {
+        return fEvaluationString;
+    }
+
+    /**
+     * Returns always <code>true</code>, since simple variables are normally
+     * unambiguous.
+     *
+     * @param context {@inheritDoc}
+     * @return <code>true</code>
+     */
+    protected bool isUnambiguous(TemplateContext context) {
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/Template.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,241 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.Template;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * A template consisting of a name and a pattern.
+ * <p>
+ * Clients may instantiate this class. May become final in the future.
+ * </p>
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class Template {
+
+    private alias .toHash toHash;
+    private alias .equals equals;
+
+    /** The name of this template */
+    private /*final*/ String fName;
+    /** A description of this template */
+    private /*final*/ String fDescription;
+    /** The name of the context type of this template */
+    private /*final*/ String fContextTypeId;
+    /** The template pattern. */
+    private /*final*/ String fPattern;
+    /**
+     * The auto insertable property.
+     * @since 3.1
+     */
+    private const bool fIsAutoInsertable;
+
+    /**
+     * Creates an empty template.
+     */
+    public this() {
+        this("", "", "", "", true); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
+    }
+
+    /**
+     * Creates a copy of a template.
+     *
+     * @param template the template to copy
+     */
+    public this(Template template_) {
+        this(template_.getName(), template_.getDescription(), template_.getContextTypeId(), template_.getPattern(), template_.isAutoInsertable());
+    }
+
+    /**
+     * Creates a template.
+     *
+     * @param name the name of the template
+     * @param description the description of the template
+     * @param contextTypeId the id of the context type in which the template can be applied
+     * @param pattern the template pattern
+     * @deprecated as of 3.1 replaced by {@link #Template(String, String, String, String, bool)}
+     */
+    public this(String name, String description, String contextTypeId, String pattern) {
+        this(name, description, contextTypeId, pattern, true); // templates are auto insertable per default
+    }
+
+    /**
+     * Creates a template.
+     *
+     * @param name the name of the template
+     * @param description the description of the template
+     * @param contextTypeId the id of the context type in which the template can be applied
+     * @param pattern the template pattern
+     * @param isAutoInsertable the auto insertable property of the template
+     * @since 3.1
+     */
+    public this(String name, String description, String contextTypeId, String pattern, bool isAutoInsertable) {
+        Assert.isNotNull(description);
+        fDescription= description;
+        fName= name;
+        Assert.isNotNull(contextTypeId);
+        fContextTypeId= contextTypeId;
+        fPattern= pattern;
+        fIsAutoInsertable= isAutoInsertable;
+    }
+
+    /*
+     * @see Object#hashCode()
+     */
+    public override hash_t toHash() {
+        return fName.toHash() ^ fPattern.toHash() ^ fContextTypeId.toHash();
+    }
+
+    /**
+     * Sets the description of the template.
+     *
+     * @param description the new description
+     * @deprecated Templates should never be modified
+     */
+    public void setDescription(String description) {
+        Assert.isNotNull(description);
+        fDescription= description;
+    }
+
+    /**
+     * Returns the description of the template.
+     *
+     * @return the description of the template
+     */
+    public String getDescription() {
+        return fDescription;
+    }
+
+    /**
+     * Sets the name of the context type in which the template can be applied.
+     *
+     * @param contextTypeId the new context type name
+     * @deprecated Templates should never be modified
+     */
+    public void setContextTypeId(String contextTypeId) {
+        Assert.isNotNull(contextTypeId);
+        fContextTypeId= contextTypeId;
+    }
+
+    /**
+     * Returns the id of the context type in which the template can be applied.
+     *
+     * @return the id of the context type in which the template can be applied
+     */
+    public String getContextTypeId() {
+        return fContextTypeId;
+    }
+
+    /**
+     * Sets the name of the template.
+     *
+     * @param name the name of the template
+     * @deprecated Templates should never be modified
+     */
+    public void setName(String name) {
+        fName= name;
+    }
+
+    /**
+     * Returns the name of the template.
+     *
+     * @return the name of the template
+     */
+    public String getName() {
+        return fName;
+    }
+
+    /**
+     * Sets the pattern of the template.
+     *
+     * @param pattern the new pattern of the template
+     * @deprecated Templates should never be modified
+     */
+    public void setPattern(String pattern) {
+        fPattern= pattern;
+    }
+
+    /**
+     * Returns the template pattern.
+     *
+     * @return the template pattern
+     */
+    public String getPattern() {
+        return fPattern;
+    }
+
+    /**
+     * Returns <code>true</code> if template is enabled and matches the context,
+     * <code>false</code> otherwise.
+     *
+     * @param prefix the prefix (e.g. inside a document) to match
+     * @param contextTypeId the context type id to match
+     * @return <code>true</code> if template is enabled and matches the context,
+     * <code>false</code> otherwise
+     */
+    public bool matches(String prefix, String contextTypeId) {
+        return fContextTypeId.equals(contextTypeId);
+    }
+
+    /*
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public bool equals(Object o) {
+        if (!( cast(Template)o ))
+            return false;
+
+        Template t= cast(Template) o;
+        if (t is this)
+            return true;
+
+        return t.fName.equals(fName)
+                && t.fPattern.equals(fPattern)
+                && t.fContextTypeId.equals(fContextTypeId)
+                && t.fDescription.equals(fDescription)
+                && t.fIsAutoInsertable is fIsAutoInsertable;
+    }
+
+    /**
+     * Returns the auto insertable property of the template.
+     *
+     * @return the auto insertable property of the template
+     * @since 3.1
+     */
+    public bool isAutoInsertable() {
+        return fIsAutoInsertable;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/TemplateBuffer.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.TemplateBuffer;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+/**
+ * A template buffer is a container for a string and variables.
+ * <p>
+ * Clients may instantiate this class.
+ * </p>
+ *
+ * @since 3.0
+ */
+public final class TemplateBuffer {
+
+    /** The string of the template buffer */
+    private String fString;
+    /** The variable positions of the template buffer */
+    private TemplateVariable[] fVariables;
+
+    /**
+     * Creates a template buffer.
+     *
+     * @param string the string
+     * @param variables the variable positions
+     */
+    public this(String string, TemplateVariable[] variables) {
+        setContent(string, variables);
+    }
+
+    /**
+     * Sets the content of the template buffer.
+     *
+     * @param string the string
+     * @param variables the variable positions
+     */
+    public final void setContent(String string, TemplateVariable[] variables) {
+        Assert.isNotNull(string);
+//         Assert.isNotNull(variables);
+
+        // XXX assert non-overlapping variable properties
+
+        fString= string;
+        fVariables= copy(variables);
+    }
+
+    /**
+     * Returns a copy of the given array.
+     *
+     * @param array the array to be copied
+     * @return a copy of the given array or <code>null</code> when <code>array</code> is <code>null</code>
+     * @since 3.1
+     */
+    private static TemplateVariable[] copy(TemplateVariable[] array) {
+        if (array !is null) {
+            TemplateVariable[] copy= new TemplateVariable[array.length];
+            System.arraycopy(array, 0, copy, 0, array.length);
+            return copy;
+        }
+        return null;
+    }
+
+    /**
+     * Returns the string of the template buffer.
+     *
+     * @return the string representation of the template buffer
+     */
+    public final String getString() {
+        return fString;
+    }
+
+    /**
+     * Returns the variable positions of the template buffer. The returned array is
+     * owned by this variable and must not be modified.
+     *
+     * @return the variable positions of the template buffer
+     */
+    public final TemplateVariable[] getVariables() {
+        return fVariables;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/TemplateCompletionProcessor.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,284 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.TemplateCompletionProcessor;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+import dwt.graphics.Image;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextSelection;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.contentassist.ICompletionProposal;
+import dwtx.jface.text.contentassist.IContentAssistProcessor;
+import dwtx.jface.text.contentassist.IContextInformation;
+import dwtx.jface.text.contentassist.IContextInformationValidator;
+
+
+/**
+ * A completion processor that computes template proposals. Subclasses need to
+ * provide implementations for {@link #getTemplates(String)},
+ * {@link #getContextType(ITextViewer, IRegion)} and {@link #getImage(Template)}.
+ *
+ * @since 3.0
+ */
+public abstract class TemplateCompletionProcessor : IContentAssistProcessor {
+
+    private static final class ProposalComparator : Comparator {
+        public int compare(Object o1, Object o2) {
+            return (cast(TemplateProposal) o2).getRelevance() - (cast(TemplateProposal) o1).getRelevance();
+        }
+    }
+
+    private static Comparator fgProposalComparator_;
+    private static Comparator fgProposalComparator(){
+        if(fgProposalComparator_ is null ) {
+            synchronized( TemplateCompletionProcessor.classinfo ){
+                if(fgProposalComparator_ is null ) {
+                    fgProposalComparator_ = new ProposalComparator();
+                }
+            }
+        }
+        return fgProposalComparator_;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(dwtx.jface.text.ITextViewer,
+     *      int)
+     */
+    public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
+
+        ITextSelection selection= cast(ITextSelection) viewer.getSelectionProvider().getSelection();
+
+        // adjust offset to end of normalized selection
+        if (selection.getOffset() is offset)
+            offset= selection.getOffset() + selection.getLength();
+
+        String prefix= extractPrefix(viewer, offset);
+        Region region= new Region(offset - prefix.length(), prefix.length());
+        TemplateContext context= createContext(viewer, region);
+        if (context is null)
+            return new ICompletionProposal[0];
+
+        context.setVariable("selection", selection.getText()); // name of the selection variables {line, word}_selection //$NON-NLS-1$
+
+        Template[] templates= getTemplates(context.getContextType().getId());
+
+        List matches= new ArrayList();
+        for (int i= 0; i < templates.length; i++) {
+            Template template_= templates[i];
+            try {
+                context.getContextType().validate(template_.getPattern());
+            } catch (TemplateException e) {
+                continue;
+            }
+            if (template_.matches(prefix, context.getContextType().getId()))
+                matches.add( cast(Object) createProposal(template_, context, cast(IRegion) region, getRelevance(template_, prefix)));
+        }
+
+        Collections.sort(matches, fgProposalComparator);
+
+        return arraycast!(ICompletionProposal)( matches.toArray());
+    }
+
+    /**
+     * Creates a new proposal.
+     * <p>
+     * Forwards to {@link #createProposal(Template, TemplateContext, IRegion, int)}.
+     * Do neither call nor override.
+     * </p>
+     *
+     * @param template the template to be applied by the proposal
+     * @param context the context for the proposal
+     * @param region the region the proposal applies to
+     * @param relevance the relevance of the proposal
+     * @return a new <code>ICompletionProposal</code> for
+     *         <code>template</code>
+     * @deprecated use the version specifying <code>IRegion</code> as third parameter
+     * @since 3.1
+     */
+    protected ICompletionProposal createProposal(Template template_, TemplateContext context, Region region, int relevance) {
+        return createProposal(template_, context, cast(IRegion) region, relevance);
+    }
+
+    /**
+     * Creates a new proposal.
+     * <p>
+     * The default implementation returns an instance of
+     * {@link TemplateProposal}. Subclasses may replace this method to provide
+     * their own implementations.
+     * </p>
+     *
+     * @param template the template to be applied by the proposal
+     * @param context the context for the proposal
+     * @param region the region the proposal applies to
+     * @param relevance the relevance of the proposal
+     * @return a new <code>ICompletionProposal</code> for
+     *         <code>template</code>
+     */
+    protected ICompletionProposal createProposal(Template template_, TemplateContext context, IRegion region, int relevance) {
+        return new TemplateProposal(template_, context, region, getImage(template_), relevance);
+    }
+
+    /**
+     * Returns the templates valid for the context type specified by <code>contextTypeId</code>.
+     *
+     * @param contextTypeId the context type id
+     * @return the templates valid for this context type id
+     */
+    protected abstract Template[] getTemplates(String contextTypeId);
+
+    /**
+     * Creates a concrete template context for the given region in the document. This involves finding out which
+     * context type is valid at the given location, and then creating a context of this type. The default implementation
+     * returns a <code>DocumentTemplateContext</code> for the context type at the given location.
+     *
+     * @param viewer the viewer for which the context is created
+     * @param region the region into <code>document</code> for which the context is created
+     * @return a template context that can handle template insertion at the given location, or <code>null</code>
+     */
+    protected TemplateContext createContext(ITextViewer viewer, IRegion region) {
+        TemplateContextType contextType= getContextType(viewer, region);
+        if (contextType !is null) {
+            IDocument document= viewer.getDocument();
+            return new DocumentTemplateContext(contextType, document, region.getOffset(), region.getLength());
+        }
+        return null;
+    }
+
+    /**
+     * Returns the context type that can handle template insertion at the given region
+     * in the viewer's document.
+     *
+     * @param viewer the text viewer
+     * @param region the region into the document displayed by viewer
+     * @return the context type that can handle template expansion for the given location, or <code>null</code> if none exists
+     */
+    protected abstract TemplateContextType getContextType(ITextViewer viewer, IRegion region);
+
+    /**
+     * Returns the relevance of a template given a prefix. The default
+     * implementation returns a number greater than zero if the template name
+     * starts with the prefix, and zero otherwise.
+     *
+     * @param template the template to compute the relevance for
+     * @param prefix the prefix after which content assist was requested
+     * @return the relevance of <code>template</code>
+     * @see #extractPrefix(ITextViewer, int)
+     */
+    protected int getRelevance(Template template_, String prefix) {
+        if (template_.getName().startsWith(prefix))
+            return 90;
+        return 0;
+    }
+
+    /**
+     * Heuristically extracts the prefix used for determining template relevance
+     * from the viewer's document. The default implementation returns the String from
+     * offset backwards that forms a java identifier.
+     *
+     * @param viewer the viewer
+     * @param offset offset into document
+     * @return the prefix to consider
+     * @see #getRelevance(Template, String)
+     */
+    protected String extractPrefix(ITextViewer viewer, int offset) {
+        int i= offset;
+        IDocument document= viewer.getDocument();
+        if (i > document.getLength())
+            return ""; //$NON-NLS-1$
+
+        try {
+            while (i > 0) {
+                char ch= document.getChar(i - 1);
+                if (!Character.isJavaIdentifierPart(ch))
+                    break;
+                i--;
+            }
+
+            return document.get(i, offset - i);
+        } catch (BadLocationException e) {
+            return ""; //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Returns the image to be used for the proposal for <code>template</code>.
+     *
+     * @param template the template for which an image should be returned
+     * @return the image for <code>template</code>
+     */
+    protected abstract Image getImage(Template template_);
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistProcessor#computeContextInformation(dwtx.jface.text.ITextViewer, int)
+     */
+    public IContextInformation[] computeContextInformation(ITextViewer viewer, int documentOffset) {
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getCompletionProposalAutoActivationCharacters()
+     */
+    public char[] getCompletionProposalAutoActivationCharacters() {
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getContextInformationAutoActivationCharacters()
+     */
+    public char[] getContextInformationAutoActivationCharacters() {
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getErrorMessage()
+     */
+    public String getErrorMessage() {
+        return null;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.IContentAssistProcessor#getContextInformationValidator()
+     */
+    public IContextInformationValidator getContextInformationValidator() {
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/TemplateContext.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,143 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.TemplateContext;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.jface.text.BadLocationException;
+
+/**
+ * Provides the context for a <code>Template</code> being resolved. Keeps track
+ * of resolved variables.
+ * <p>
+ * Clients may extend this class.
+ * </p>
+ *
+ * @since 3.0
+ */
+public abstract class TemplateContext {
+
+    /** The context type of this context */
+    private const TemplateContextType fContextType;
+    /** Additional variables. */
+    private const Map fVariables;
+    /** A flag to indicate that the context should not be modified. */
+    private bool fReadOnly;
+
+    /**
+     * Creates a template context of a particular context type.
+     *
+     * @param contextType the context type of this context
+     */
+    protected this(TemplateContextType contextType) {
+        fVariables= new HashMap();
+        fContextType= contextType;
+        fReadOnly= true;
+    }
+
+    /**
+     * Returns the context type of this context.
+     *
+     * @return the context type of this context
+     */
+    public TemplateContextType getContextType() {
+        return fContextType;
+    }
+
+    /**
+     * Sets or clears the read-only flag.
+     *
+     * @param readOnly the new read-only state
+     */
+    public void setReadOnly(bool readOnly) {
+        fReadOnly= readOnly;
+    }
+
+    /**
+     * Returns <code>true</code> if the receiver is read-only, <code>false</code> otherwise.
+     *
+     * @return <code>true</code> if the receiver is read-only, <code>false</code> otherwise
+     */
+    public bool isReadOnly() {
+        return fReadOnly;
+    }
+
+    /**
+     * Defines the value of a variable.
+     *
+     * @param name the name of the variable
+     * @param value the value of the variable, <code>null</code> to un-define a variable
+     */
+    public void setVariable(String name, String value) {
+        fVariables.put(name, value);
+    }
+
+    /**
+     * Returns the value of a defined variable.
+     *
+     * @param name the name of the variable
+     * @return returns the value of the variable, <code>null</code> if the variable was not defined
+     */
+    public String getVariable(String name) {
+        return stringcast( fVariables.get(name));
+    }
+
+    /**
+     * Evaluates the template in this context and returns a template buffer.
+     * <p>
+     * Evaluation means translating the template into a <code>TemplateBuffer</code>,
+     * resolving the defined variables in this context and possibly formatting
+     * the resolved buffer.</p>
+     *
+     * @param template the template to evaluate
+     * @return returns the buffer with the evaluated template or <code>null</code> if the buffer could not be created
+     * @throws BadLocationException if evaluation fails due to concurrently changed documents etc.
+     * @throws TemplateException if the template specification is not valid
+     */
+    public abstract TemplateBuffer evaluate(Template template_);
+
+    /**
+     * Tests if the specified template can be evaluated in this context.
+     * <p>Examples are templates defined for a different context (e.g. a javadoc
+     * template cannot be evaluated in Java context).</p>
+     *
+     * @param template the <code>Template</code> to check
+     * @return <code>true</code> if <code>template</code> can be evaluated
+     *         in this context, <code>false</code> otherwise
+     */
+    public abstract bool canEvaluate(Template template_);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/TemplateContextType.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,325 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.TemplateContextType;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.Document;
+import dwtx.jface.text.IDocument;
+import dwtx.text.edits.MalformedTreeException;
+import dwtx.text.edits.MultiTextEdit;
+import dwtx.text.edits.RangeMarker;
+import dwtx.text.edits.ReplaceEdit;
+import dwtx.text.edits.TextEdit;
+
+
+/**
+ * A context type defines a context within which templates are resolved. It
+ * stores a number of <code>TemplateVariableResolver</code>s. A
+ * <code>TemplateBuffer</code> can be resolved in a
+ * <code>TemplateContext</code> using the
+ * {@link #resolve(TemplateBuffer, TemplateContext)} method.
+ * <p>
+ * Clients may extend this class.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class TemplateContextType {
+
+    /** The id of the context type. */
+    private /* final */ String fId= null;
+
+    /** Variable resolvers used by this content type. */
+    private const Map fResolvers;
+
+    /** The name of the context type. */
+    private String fName= null;
+
+    /**
+     * Creates a context type with an identifier. The identifier must be unique,
+     * a qualified name is suggested. The id is also used as name.
+     *
+     * @param id the unique identifier of the context type
+     */
+    public this(String id) {
+        this(id, id);
+    }
+
+    /**
+     * Creates a context type with an identifier. The identifier must be unique, a qualified name is suggested.
+     *
+     * @param id the unique identifier of the context type
+     * @param name the name of the context type
+     */
+    public this(String id, String name) {
+        fResolvers= new HashMap();
+
+        Assert.isNotNull(id);
+        Assert.isNotNull(name);
+        fId= id;
+        fName= name;
+    }
+
+    /**
+     * Returns the id of the context type.
+     *
+     * @return the id of the receiver
+     */
+    public String getId() {
+        return fId;
+    }
+
+
+    /**
+     * Returns the name of the context type.
+     *
+     * @return the name of the context type
+     */
+    public String getName() {
+        return fName;
+    }
+
+    /**
+     * Creates a context type with a <code>null</code> identifier.
+     * <p>
+     * This is a framework-only constructor that exists only so that context
+     * types can be contributed via an extension point and that should not be
+     * called in client code except for subclass constructors; use
+     * {@link #TemplateContextType(String)} instead.
+     * </p>
+     */
+    public this() {
+        fResolvers= new HashMap();
+    }
+
+    /**
+     * Sets the id of this context.
+     * <p>
+     * This is a framework-only method that exists solely so that context types
+     * can be contributed via an extension point and that should not be called
+     * in client code; use {@link #TemplateContextType(String)} instead.
+     * </p>
+     *
+     * @param id the identifier of this context
+     * @throws RuntimeException an unspecified exception if the id has already
+     *         been set on this context type
+     */
+    public final void setId(String id)  {
+        Assert.isNotNull(id);
+        Assert.isTrue(fId is null); // may only be called once when the context is instantiated
+        fId= id;
+    }
+
+    /**
+     * Sets the name of the context type.
+     *
+     * <p>
+     * This is a framework-only method that exists solely so that context types
+     * can be contributed via an extension point and that should not be called
+     * in client code; use {@link #TemplateContextType(String, String)} instead.
+     * </p>
+     *
+     * @param name the name of the context type
+     */
+    public final void setName(String name) {
+        Assert.isTrue(fName is null); // only initialized by extension code
+        fName= name;
+    }
+
+    /**
+     * Adds a variable resolver to the context type. If there already is a resolver
+     * for the same type, the previous one gets replaced by <code>resolver</code>.
+     *
+     * @param resolver the resolver to be added under its name
+     */
+    public void addResolver(TemplateVariableResolver resolver) {
+        Assert.isNotNull(resolver);
+        fResolvers.put(resolver.getType(), resolver);
+    }
+
+    /**
+     * Removes a template variable from the context type.
+     *
+     * @param resolver the variable to be removed
+     */
+    public void removeResolver(TemplateVariableResolver resolver) {
+        Assert.isNotNull(resolver);
+        fResolvers.remove(resolver.getType());
+    }
+
+    /**
+     * Removes all template variables from the context type.
+     */
+    public void removeAllResolvers() {
+        fResolvers.clear();
+    }
+
+    /**
+     * Returns an iterator for the variables known to the context type.
+     *
+     * @return an iterator over the variables in this context type
+     */
+    public Iterator resolvers() {
+        return Collections.unmodifiableMap(fResolvers).values().iterator();
+    }
+
+    /**
+     * Returns the resolver for the given type.
+     *
+     * @param type the type for which a resolver is needed
+     * @return a resolver for the given type, or <code>null</code> if none is registered
+     */
+    protected TemplateVariableResolver getResolver(String type) {
+        return cast(TemplateVariableResolver) fResolvers.get(type);
+    }
+
+    /**
+     * Validates a pattern, a <code>TemplateException</code> is thrown if
+     * validation fails.
+     *
+     * @param pattern the template pattern to validate
+     * @throws TemplateException if the pattern is invalid
+     */
+    public void validate(String pattern)  {
+        TemplateTranslator translator= new TemplateTranslator();
+        TemplateBuffer buffer= translator.translate(pattern);
+        validateVariables(buffer.getVariables());
+    }
+
+    /**
+     * Validates the variables in this context type. If a variable is not valid,
+     * e.g. if its type is not known in this context type, a
+     * <code>TemplateException</code> is thrown.
+     * <p>
+     * The default implementation does nothing.
+     * </p>
+     *
+     * @param variables the variables to validate
+     * @throws TemplateException if one of the variables is not valid in this
+     *         context type
+     */
+    protected void validateVariables(TemplateVariable[] variables)  {
+    }
+
+    /**
+     * Resolves the variables in <code>buffer</code> within <code>context</code>
+     * and edits the template buffer to reflect the resolved variables.
+     *
+     * @param buffer the template buffer
+     * @param context the template context
+     * @throws MalformedTreeException if the positions in the buffer overlap
+     * @throws BadLocationException if the buffer cannot be successfully modified
+     */
+    public void resolve(TemplateBuffer buffer, TemplateContext context)  {
+        Assert.isNotNull(context);
+        TemplateVariable[] variables= buffer.getVariables();
+
+        List positions= variablesToPositions(variables);
+        List edits= new ArrayList(5);
+
+        // iterate over all variables and try to resolve them
+        for (int i= 0; i !is variables.length; i++) {
+            TemplateVariable variable= variables[i];
+
+            if (!variable.isResolved())
+                resolve(variable, context);
+
+            String value= variable.getDefaultValue();
+            int[] offsets= variable.getOffsets();
+            // update buffer to reflect new value
+            for (int k= 0; k !is offsets.length; k++)
+                edits.add(new ReplaceEdit(offsets[k], variable.getInitialLength(), value));
+
+        }
+
+        IDocument document= new Document(buffer.getString());
+        MultiTextEdit edit= new MultiTextEdit(0, document.getLength());
+        edit.addChildren(arraycast!(TextEdit)( positions.toArray()));
+        edit.addChildren(arraycast!(TextEdit)( edits.toArray()));
+        edit.apply(document, TextEdit.UPDATE_REGIONS);
+
+        positionsToVariables(positions, variables);
+
+        buffer.setContent(document.get(), variables);
+    }
+
+    /**
+     * Resolves a single variable in a context. Resolving is delegated to the registered resolver.
+     *
+     * @param variable the variable to resolve
+     * @param context the context in which to resolve the variable
+     * @since 3.3
+     */
+    public void resolve(TemplateVariable variable, TemplateContext context) {
+        String type= variable.getType();
+        TemplateVariableResolver resolver= cast(TemplateVariableResolver) fResolvers.get(type);
+        if (resolver is null)
+            resolver= new TemplateVariableResolver(type, ""); //$NON-NLS-1$
+        resolver.resolve(variable, context);
+    }
+
+    private static List variablesToPositions(TemplateVariable[] variables) {
+        List positions= new ArrayList(5);
+        for (int i= 0; i !is variables.length; i++) {
+            int[] offsets= variables[i].getOffsets();
+            for (int j= 0; j !is offsets.length; j++)
+                positions.add(new RangeMarker(offsets[j], 0));
+        }
+
+        return positions;
+    }
+
+    private static void positionsToVariables(List positions, TemplateVariable[] variables) {
+        Iterator iterator= positions.iterator();
+
+        for (int i= 0; i !is variables.length; i++) {
+            TemplateVariable variable= variables[i];
+
+            int[] offsets= new int[variable.getOffsets().length];
+            for (int j= 0; j !is offsets.length; j++)
+                offsets[j]= (cast(TextEdit) iterator.next()).getOffset();
+
+            variable.setOffsets(offsets);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/TemplateException.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+
+
+module dwtx.jface.text.templates.TemplateException;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * Thrown when a template cannot be validated.
+ * <p>
+ * Clients may instantiate this class.
+ * </p>
+ * <p>
+ * This class is not intended to be serialized.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class TemplateException : Exception {
+
+    /**
+     * Serial version UID for this class.
+     * <p>
+     * Note: This class is not intended to be serialized.
+     * </p>
+     * @since 3.1
+     */
+    private static const long serialVersionUID= 3906362710416699442L;
+
+    /**
+     * Creates a new template exception.
+     */
+    public this() {
+        super(null);
+    }
+
+    /**
+     * Creates a new template exception.
+     *
+     * @param message the message describing the problem that arose
+     */
+    public this(String message) {
+        super(message);
+    }
+
+    /**
+     * Creates a new template exception.
+     *
+     * @param message the message describing the problem that arose
+     * @param cause the original exception
+     */
+    public this(String message, Exception cause) {
+        super(message, cause);
+    }
+
+    /**
+     * Creates a new template exception.
+     *
+     * @param cause the original exception
+     */
+    public this(Exception cause) {
+        super(null, cause);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/TemplateProposal.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,491 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.TemplateProposal;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwt.graphics.Image;
+import dwt.graphics.Point;
+import dwt.widgets.Shell;
+import dwtx.core.runtime.Assert;
+import dwtx.jface.dialogs.MessageDialog;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IInformationControlCreator;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITextViewer;
+import dwtx.jface.text.Position;
+import dwtx.jface.text.Region;
+import dwtx.jface.text.contentassist.ICompletionProposal;
+import dwtx.jface.text.contentassist.ICompletionProposalExtension;
+import dwtx.jface.text.contentassist.ICompletionProposalExtension2;
+import dwtx.jface.text.contentassist.ICompletionProposalExtension3;
+import dwtx.jface.text.contentassist.IContextInformation;
+import dwtx.jface.text.link.ILinkedModeListener;
+import dwtx.jface.text.link.LinkedModeModel;
+import dwtx.jface.text.link.LinkedModeUI;
+import dwtx.jface.text.link.LinkedPosition;
+import dwtx.jface.text.link.LinkedPositionGroup;
+import dwtx.jface.text.link.ProposalPosition;
+
+
+/**
+ * A template completion proposal.
+ * <p>
+ * Clients may subclass.</p>
+ *
+ * @since 3.0
+ */
+public class TemplateProposal : ICompletionProposal, ICompletionProposalExtension, ICompletionProposalExtension2, ICompletionProposalExtension3 {
+
+    private const Template fTemplate;
+    private const TemplateContext fContext;
+    private const Image fImage;
+    private const IRegion fRegion;
+    private int fRelevance;
+
+    private IRegion fSelectedRegion; // initialized by apply()
+    private String fDisplayString;
+    private InclusivePositionUpdater fUpdater;
+    private IInformationControlCreator fInformationControlCreator;
+
+    /**
+     * Creates a template proposal with a template and its context.
+     *
+     * @param template  the template
+     * @param context   the context in which the template was requested.
+     * @param region    the region this proposal is applied to
+     * @param image     the icon of the proposal.
+     */
+    public this(Template template_, TemplateContext context, IRegion region, Image image) {
+        this(template_, context, region, image, 0);
+    }
+
+    /**
+     * Creates a template proposal with a template and its context.
+     *
+     * @param template  the template
+     * @param context   the context in which the template was requested.
+     * @param image     the icon of the proposal.
+     * @param region    the region this proposal is applied to
+     * @param relevance the relevance of the proposal
+     */
+    public this(Template template_, TemplateContext context, IRegion region, Image image, int relevance) {
+        Assert.isNotNull(template_);
+        Assert.isNotNull(context);
+        Assert.isNotNull(cast(Object)region);
+
+        fTemplate= template_;
+        fContext= context;
+        fImage= image;
+        fRegion= region;
+
+        fDisplayString= null;
+
+        fRelevance= relevance;
+    }
+
+    /**
+     * Sets the information control creator for this completion proposal.
+     *
+     * @param informationControlCreator the information control creator
+     * @since 3.1
+     */
+    public final void setInformationControlCreator(IInformationControlCreator informationControlCreator) {
+        fInformationControlCreator= informationControlCreator;
+    }
+
+    /**
+     * Returns the template of this proposal.
+     *
+     * @return the template of this proposal
+     * @since 3.1
+     */
+    protected final Template getTemplate() {
+        return fTemplate;
+    }
+
+    /**
+     * Returns the context in which the template was requested.
+     *
+     * @return the context in which the template was requested
+     * @since 3.1
+     */
+    protected final TemplateContext getContext() {
+        return fContext;
+    }
+
+    /*
+     * @see ICompletionProposal#apply(IDocument)
+     */
+    public final void apply(IDocument document) {
+        // not called anymore
+    }
+
+    /**
+     * Inserts the template offered by this proposal into the viewer's document
+     * and sets up a <code>LinkedModeUI</code> on the viewer to edit any of
+     * the template's unresolved variables.
+     *
+     * @param viewer {@inheritDoc}
+     * @param trigger {@inheritDoc}
+     * @param stateMask {@inheritDoc}
+     * @param offset {@inheritDoc}
+     */
+    public void apply(ITextViewer viewer, char trigger, int stateMask, int offset) {
+
+        IDocument document= viewer.getDocument();
+        try {
+            fContext.setReadOnly(false);
+            int start;
+            TemplateBuffer templateBuffer;
+            {
+                int oldReplaceOffset= getReplaceOffset();
+                try {
+                    // this may already modify the document (e.g. add imports)
+                    templateBuffer= fContext.evaluate(fTemplate);
+                } catch (TemplateException e1) {
+                    fSelectedRegion= fRegion;
+                    return;
+                }
+
+                start= getReplaceOffset();
+                int shift= start - oldReplaceOffset;
+                int end= Math.max(getReplaceEndOffset(), offset + shift);
+
+                // insert template string
+                String templateString= templateBuffer.getString();
+                document.replace(start, end - start, templateString);
+            }
+
+            // translate positions
+            LinkedModeModel model= new LinkedModeModel();
+            TemplateVariable[] variables= templateBuffer.getVariables();
+            bool hasPositions= false;
+            for (int i= 0; i !is variables.length; i++) {
+                TemplateVariable variable= variables[i];
+
+                if (variable.isUnambiguous())
+                    continue;
+
+                LinkedPositionGroup group= new LinkedPositionGroup();
+
+                int[] offsets= variable.getOffsets();
+                int length= variable.getLength();
+
+                LinkedPosition first;
+                {
+                    String[] values= variable.getValues();
+                    ICompletionProposal[] proposals= new ICompletionProposal[values.length];
+                    for (int j= 0; j < values.length; j++) {
+                        ensurePositionCategoryInstalled(document, model);
+                        Position pos= new Position(offsets[0] + start, length);
+                        document.addPosition(getCategory(), pos);
+                        proposals[j]= new PositionBasedCompletionProposal(values[j], pos, length);
+                    }
+
+                    if (proposals.length > 1)
+                        first= new ProposalPosition(document, offsets[0] + start, length, proposals);
+                    else
+                        first= new LinkedPosition(document, offsets[0] + start, length);
+                }
+
+                for (int j= 0; j !is offsets.length; j++)
+                    if (j is 0)
+                        group.addPosition(first);
+                    else
+                        group.addPosition(new LinkedPosition(document, offsets[j] + start, length));
+
+                model.addGroup(group);
+                hasPositions= true;
+            }
+
+            if (hasPositions) {
+                model.forceInstall();
+                LinkedModeUI ui= new LinkedModeUI(model, viewer);
+                ui.setExitPosition(viewer, getCaretOffset(templateBuffer) + start, 0, Integer.MAX_VALUE);
+                ui.enter();
+
+                fSelectedRegion= ui.getSelectedRegion();
+            } else {
+                ensurePositionCategoryRemoved(document);
+                fSelectedRegion= new Region(getCaretOffset(templateBuffer) + start, 0);
+            }
+
+        } catch (BadLocationException e) {
+            openErrorDialog(viewer.getTextWidget().getShell(), e);
+            ensurePositionCategoryRemoved(document);
+            fSelectedRegion= fRegion;
+        } catch (BadPositionCategoryException e) {
+            openErrorDialog(viewer.getTextWidget().getShell(), e);
+            fSelectedRegion= fRegion;
+        }
+
+    }
+
+    private void ensurePositionCategoryInstalled(IDocument document, LinkedModeModel model) {
+        if (!document.containsPositionCategory(getCategory())) {
+            document.addPositionCategory(getCategory());
+            fUpdater= new InclusivePositionUpdater(getCategory());
+            document.addPositionUpdater(fUpdater);
+
+            model.addLinkingListener(new class(document)  ILinkedModeListener {
+                IDocument document_;
+                this( IDocument a ){
+                    document_=a;
+                }
+                /*
+                 * @see dwtx.jface.text.link.ILinkedModeListener#left(dwtx.jface.text.link.LinkedModeModel, int)
+                 */
+                public void left(LinkedModeModel environment, int flags) {
+                    ensurePositionCategoryRemoved(document_);
+                }
+
+                public void suspend(LinkedModeModel environment) {}
+                public void resume(LinkedModeModel environment, int flags) {}
+            });
+        }
+    }
+
+    private void ensurePositionCategoryRemoved(IDocument document) {
+        if (document.containsPositionCategory(getCategory())) {
+            try {
+                document.removePositionCategory(getCategory());
+            } catch (BadPositionCategoryException e) {
+                // ignore
+            }
+            document.removePositionUpdater(fUpdater);
+        }
+    }
+
+    private String getCategory() {
+        return "TemplateProposalCategory_" ~ toString(); //$NON-NLS-1$
+    }
+
+    private int getCaretOffset(TemplateBuffer buffer) {
+
+        TemplateVariable[] variables= buffer.getVariables();
+        for (int i= 0; i !is variables.length; i++) {
+            TemplateVariable variable= variables[i];
+            if (variable.getType().equals(GlobalTemplateVariables.Cursor.NAME))
+                return variable.getOffsets()[0];
+        }
+
+        return buffer.getString().length();
+    }
+
+    /**
+     * Returns the offset of the range in the document that will be replaced by
+     * applying this template.
+     *
+     * @return the offset of the range in the document that will be replaced by
+     *         applying this template
+     * @since 3.1
+     */
+    protected final int getReplaceOffset() {
+        int start;
+        if ( cast(DocumentTemplateContext)fContext ) {
+            DocumentTemplateContext docContext = cast(DocumentTemplateContext)fContext;
+            start= docContext.getStart();
+        } else {
+            start= fRegion.getOffset();
+        }
+        return start;
+    }
+
+    /**
+     * Returns the end offset of the range in the document that will be replaced
+     * by applying this template.
+     *
+     * @return the end offset of the range in the document that will be replaced
+     *         by applying this template
+     * @since 3.1
+     */
+    protected final int getReplaceEndOffset() {
+        int end;
+        if ( cast(DocumentTemplateContext)fContext ) {
+            DocumentTemplateContext docContext = cast(DocumentTemplateContext)fContext;
+            end= docContext.getEnd();
+        } else {
+            end= fRegion.getOffset() + fRegion.getLength();
+        }
+        return end;
+    }
+
+    /*
+     * @see ICompletionProposal#getSelection(IDocument)
+     */
+    public Point getSelection(IDocument document) {
+        return new Point(fSelectedRegion.getOffset(), fSelectedRegion.getLength());
+    }
+
+    /*
+     * @see ICompletionProposal#getAdditionalProposalInfo()
+     */
+    public String getAdditionalProposalInfo() {
+        try {
+            fContext.setReadOnly(true);
+            TemplateBuffer templateBuffer;
+            try {
+                templateBuffer= fContext.evaluate(fTemplate);
+            } catch (TemplateException e) {
+                return null;
+            }
+
+            return templateBuffer.getString();
+
+        } catch (BadLocationException e) {
+            return null;
+        }
+    }
+
+    /*
+     * @see ICompletionProposal#getDisplayString()
+     */
+    public String getDisplayString() {
+        if (fDisplayString is null) {
+            String[] arguments= [ fTemplate.getName(), fTemplate.getDescription() ];
+            fDisplayString= JFaceTextTemplateMessages.getFormattedString("TemplateProposal.displayString", stringcast(arguments)); //$NON-NLS-1$
+        }
+        return fDisplayString;
+    }
+
+    /*
+     * @see ICompletionProposal#getImage()
+     */
+    public Image getImage() {
+        return fImage;
+    }
+
+    /*
+     * @see ICompletionProposal#getContextInformation()
+     */
+    public IContextInformation getContextInformation() {
+        return null;
+    }
+
+    private void openErrorDialog(Shell shell, Exception e) {
+        MessageDialog.openError(shell, JFaceTextTemplateMessages.getString("TemplateProposal.errorDialog.title"), e.msg); //$NON-NLS-1$
+    }
+
+    /**
+     * Returns the relevance.
+     *
+     * @return the relevance
+     */
+    public int getRelevance() {
+        return fRelevance;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension3#getInformationControlCreator()
+     */
+    public IInformationControlCreator getInformationControlCreator() {
+        return fInformationControlCreator;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#selected(dwtx.jface.text.ITextViewer, bool)
+     */
+    public void selected(ITextViewer viewer, bool smartToggle) {
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#unselected(dwtx.jface.text.ITextViewer)
+     */
+    public void unselected(ITextViewer viewer) {
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension2#validate(dwtx.jface.text.IDocument, int, dwtx.jface.text.DocumentEvent)
+     */
+    public bool validate(IDocument document, int offset, DocumentEvent event) {
+        try {
+            int replaceOffset= getReplaceOffset();
+            if (offset >= replaceOffset) {
+                String content= document.get(replaceOffset, offset - replaceOffset);
+                return fTemplate.getName().toLowerCase().startsWith(content.toLowerCase());
+            }
+        } catch (BadLocationException e) {
+            // concurrent modification - ignore
+        }
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension3#getPrefixCompletionText(dwtx.jface.text.IDocument, int)
+     */
+    public CharSequence getPrefixCompletionText(IDocument document, int completionOffset) {
+        return new StringCharSequence( fTemplate.getName() );
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension3#getPrefixCompletionStart(dwtx.jface.text.IDocument, int)
+     */
+    public int getPrefixCompletionStart(IDocument document, int completionOffset) {
+        return getReplaceOffset();
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#apply(dwtx.jface.text.IDocument, char, int)
+     */
+    public void apply(IDocument document, char trigger, int offset) {
+        // not called any longer
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#isValidFor(dwtx.jface.text.IDocument, int)
+     */
+    public bool isValidFor(IDocument document, int offset) {
+        // not called any longer
+        return false;
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#getTriggerCharacters()
+     */
+    public char[] getTriggerCharacters() {
+        // no triggers
+        return new char[0];
+    }
+
+    /*
+     * @see dwtx.jface.text.contentassist.ICompletionProposalExtension#getContextInformationPosition()
+     */
+    public int getContextInformationPosition() {
+        return fRegion.getOffset();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/TemplateTranslator.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,349 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.TemplateTranslator;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import dwtx.dwtxhelper.regex;
+
+/**
+ * The template translator translates a string into a template buffer. Regions marked as variables
+ * are translated into <code>TemplateVariable</code>s.
+ * <p>
+ * The EBNF grammar of a valid string is as follows:
+ * </p>
+ * <p>
+ * template := (text | escape)*. <br />
+ * text := character - dollar. <br />
+ * escape := dollar ('{' variable '}' | dollar). <br />
+ * dollar := '$'. <br />
+ * variable := identifier | identifier ':' type. <br />
+ * type := qualifiedname | qualifiedname '(' arguments ')'. <br />
+ * arguments := (argument ',')* argument. <br />
+ * argument := qualifiedname | argumenttext. <br />
+ * qualifiedname := (identifier '.')* identifier. <br />
+ * argumenttext := "'" (character - "'" | "'" "'")* "'". <br />
+ * </p>
+ * <p>
+ * Clients may only replace the <code>createVariable</code> method of this class.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class TemplateTranslator {
+    /**
+     * Regex pattern for qualifiedname
+     * @since 3.4
+     */
+    private static const String QUALIFIED_NAME= "(?:\\w++\\.)*\\w++"; //$NON-NLS-1$
+
+    /**
+     * Regex pattern for argumenttext
+     * @since 3.4
+     */
+    private static const String ARGUMENT_TEXT= "'(?:(?:'')|(?:[^']))*'"; //$NON-NLS-1$
+
+    /**
+     * Regex pattern for argument
+     * @since 3.4
+     */
+    private static const String ARGUMENT= "(?:" ~ QUALIFIED_NAME ~ ")|(?:" ~ ARGUMENT_TEXT ~ ")"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+
+    /**
+     * Precompiled regex pattern for qualified names.
+     * @since 3.3
+     */
+    private static Pattern PARAM_PATTERN_;
+    private static Pattern PARAM_PATTERN(){
+        if( PARAM_PATTERN_ is null ){
+            synchronized( TemplateTranslator.classinfo ){
+                if( PARAM_PATTERN_ is null ){
+                    PARAM_PATTERN_ = Pattern.compile(ARGUMENT);
+                }
+            }
+        }
+        return PARAM_PATTERN_;
+    }
+    /**
+     * Precompiled regex pattern for valid dollar escapes (dollar literals and variables) and
+     * (invalid) single dollars.
+     * @since 3.3
+     */
+    private static Pattern ESCAPE_PATTERN_;
+    private static Pattern ESCAPE_PATTERN(){
+        if( ESCAPE_PATTERN_ is null ){
+            synchronized( TemplateTranslator.classinfo ){
+                if( ESCAPE_PATTERN_ is null ){
+                    ESCAPE_PATTERN_ = Pattern.compile(
+                        "\\$\\$|\\$\\{\\s*+" ~ // $$|${                                                         //$NON-NLS-1$
+                        "(\\w*+)" ~ // variable id group (1)                                                    //$NON-NLS-1$
+                        "\\s*+(?::\\s*+" ~ // :                                                                 //$NON-NLS-1$
+                        "(" ~ QUALIFIED_NAME ~ ")" ~ // variable type group (2)                                 //$NON-NLS-1$ //$NON-NLS-2$
+                        "\\s*+(?:\\(\\s*+" ~ // (                                                               //$NON-NLS-1$
+                        "((?:(?:" ~ ARGUMENT ~ ")\\s*+,\\s*+)*(?:" ~ ARGUMENT ~ "))" ~ // arguments group (3)   //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+                        "\\s*+\\))?\\s*+)?\\}|\\$"); // )}|$                                                    //$NON-NLS-1$
+                }
+            }
+        }
+        return ESCAPE_PATTERN_;
+    }
+    /**
+     * @since 3.3
+     */
+    private final class VariableDescription {
+        const List fOffsets;
+        const String fName;
+        TemplateVariableType fType;
+
+        this(String name, TemplateVariableType type) {
+            fOffsets= new ArrayList(5);
+            fName= name;
+            fType= type;
+        }
+
+        void mergeType(TemplateVariableType type)  {
+            if (type is null)
+                return;
+            if (fType is null)
+                fType= type;
+            if (!type.equals(fType))
+                fail(TextTemplateMessages.getFormattedString("TemplateTranslator.error.incompatible.type", stringcast(fName))); //$NON-NLS-1$
+        }
+    }
+
+    /** Last translation error. */
+    private String fErrorMessage;
+    /**
+     * Used to ensure compatibility with subclasses overriding
+     * {@link #createVariable(String, String, int[])}.
+     * @since 3.3
+     */
+    private TemplateVariableType fCurrentType;
+
+    /**
+     * Returns an error message if an error occurred for the last translation, <code>null</code>
+     * otherwise.
+     *
+     * @return the error message if an error occurred during the most recent translation,
+     *         <code>null</code> otherwise
+     */
+    public String getErrorMessage() {
+        return fErrorMessage;
+    }
+
+    /**
+     * Translates a template to a <code>TemplateBuffer</code>. <code>null</code> is returned if
+     * there was an error. <code>getErrorMessage()</code> retrieves the associated error message.
+     *
+     * @param template the template to translate.
+     * @return returns the template buffer corresponding to the string
+     * @see #getErrorMessage()
+     * @throws TemplateException if translation failed
+     */
+    public TemplateBuffer translate(Template template_)  {
+        return parse(template_.getPattern());
+    }
+
+    /**
+     * Translates a template string to <code>TemplateBuffer</code>. <code>null</code> is
+     * returned if there was an error. <code>getErrorMessage()</code> retrieves the associated
+     * error message.
+     *
+     * @param string the string to translate.
+     * @return returns the template buffer corresponding to the string
+     * @see #getErrorMessage()
+     * @throws TemplateException if translation failed
+     */
+    public TemplateBuffer translate(String string)  {
+        return parse(string);
+    }
+
+    /**
+     * Internal parser.
+     *
+     * @param string the string to parse
+     * @return the parsed <code>TemplateBuffer</code>
+     * @throws TemplateException if the string does not conform to the template format
+     */
+    private TemplateBuffer parse(String string)  {
+
+        fErrorMessage= null;
+        final StringBuffer buffer= new StringBuffer(string.length());
+        final Matcher matcher= ESCAPE_PATTERN.matcher(string);
+        final Map variables= new LinkedHashMap();
+
+        int complete= 0;
+        while (matcher.find()) {
+            // append any verbatim text
+            buffer.append(string.substring(complete, matcher.start()));
+
+            // check the escaped sequence
+            if ("$".equals(matcher.group())) { //$NON-NLS-1$
+                fail(TextTemplateMessages.getString("TemplateTranslator.error.incomplete.variable")); //$NON-NLS-1$
+            } else if ("$$".equals(matcher.group())) { //$NON-NLS-1$
+                // escaped $
+                buffer.append('$');
+            } else {
+                // parse variable
+                String name= matcher.group(1);
+                String typeName= matcher.group(2);
+                String params= matcher.group(3);
+                TemplateVariableType type= createType(typeName, params);
+
+                updateOrCreateVariable(variables, name, type, buffer.length());
+
+                buffer.append(name);
+            }
+            complete= matcher.end();
+        }
+        // append remaining verbatim text
+        buffer.append(string.substring(complete));
+
+        TemplateVariable[] vars= createVariables(variables);
+        return new TemplateBuffer(buffer.toString(), vars);
+    }
+
+    private TemplateVariableType createType(String typeName, String paramString) {
+        if (typeName is null)
+            return null;
+
+        if (paramString is null)
+            return new TemplateVariableType(typeName);
+
+        final Matcher matcher= PARAM_PATTERN.matcher(paramString);
+        List params= new ArrayList(5);
+        while (matcher.find()) {
+            String argument= matcher.group();
+            if (argument.charAt(0) is '\'') {
+                // argumentText
+                argument= argument.substring(1, argument.length() - 1).replaceAll("''", "'"); //$NON-NLS-1$ //$NON-NLS-2$
+            }
+
+            params.add(argument);
+        }
+
+        return new TemplateVariableType(typeName, stringcast( params.toArray()));
+    }
+
+    private void fail(String message)  {
+        fErrorMessage= message;
+        throw new TemplateException(message);
+    }
+
+    /**
+     * If there is no variable named <code>name</code>, a new variable with the given type, name
+     * and offset is created. If one exists, the offset is added to the variable and the type is
+     * merged with the existing type.
+     *
+     * @param variables the variables by variable name
+     * @param name the name of the variable
+     * @param type the variable type, <code>null</code> for not defined
+     * @param offset the buffer offset of the variable
+     * @throws TemplateException if merging the type fails
+     * @since 3.3
+     */
+    private void updateOrCreateVariable(Map variables, String name, TemplateVariableType type, int offset)  {
+        VariableDescription varDesc= cast(VariableDescription) variables.get(name);
+        if (varDesc is null) {
+            varDesc= new VariableDescription(name, type);
+            variables.put(name, varDesc);
+        } else {
+            varDesc.mergeType(type);
+        }
+        varDesc.fOffsets.add(new Integer(offset));
+    }
+
+    /**
+     * Creates proper {@link TemplateVariable}s from the variable descriptions.
+     *
+     * @param variables the variable descriptions by variable name
+     * @return the corresponding variables
+     * @since 3.3
+     */
+    private TemplateVariable[] createVariables(Map variables) {
+        TemplateVariable[] result= new TemplateVariable[variables.size()];
+        int idx= 0;
+        for (Iterator it= variables.values().iterator(); it.hasNext(); idx++) {
+            VariableDescription desc= cast(VariableDescription) it.next();
+            TemplateVariableType type= desc.fType is null ? new TemplateVariableType(desc.fName) : desc.fType;
+            int[] offsets= new int[desc.fOffsets.size()];
+            int i= 0;
+            for (Iterator intIt= desc.fOffsets.iterator(); intIt.hasNext(); i++) {
+                Integer offset= cast(Integer) intIt.next();
+                offsets[i]= offset.intValue();
+            }
+            fCurrentType= type;
+            /*
+             * Call the deprecated version of createVariable. When not overridden, it will delegate
+             * to the new version using fCurrentType.
+             */
+            TemplateVariable var= createVariable(type.getName(), desc.fName, offsets);
+            result[idx]= var;
+        }
+        fCurrentType= null; // avoid dangling reference
+        return result;
+    }
+
+    /**
+     * Hook method to create new variables. Subclasses may override to supply their custom variable
+     * type.
+     * <p>
+     * Clients may replace this method.
+     * </p>
+     *
+     * @param type the type of the new variable.
+     * @param name the name of the new variable.
+     * @param offsets the offsets where the variable occurs in the template
+     * @return a new instance of <code>TemplateVariable</code>
+     * @deprecated as of 3.3 use {@link #createVariable(TemplateVariableType, String, int[])} instead
+     */
+    protected TemplateVariable createVariable(String type, String name, int[] offsets) {
+        return createVariable(fCurrentType, name, offsets);
+    }
+
+    /**
+     * Hook method to create new variables. Subclasses may override to supply their custom variable
+     * type.
+     * <p>
+     * Clients may replace this method.
+     * </p>
+     *
+     * @param type the type of the new variable.
+     * @param name the name of the new variable.
+     * @param offsets the offsets where the variable occurs in the template
+     * @return a new instance of <code>TemplateVariable</code>
+     * @since 3.3
+     */
+    protected TemplateVariable createVariable(TemplateVariableType type, String name, int[] offsets) {
+        return new TemplateVariable(type, name, name, offsets);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/TemplateVariable.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,309 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.TemplateVariable;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.TextUtilities;
+
+/**
+ * A <code>TemplateVariable</code> represents a set of positions into a
+ * <code>TemplateBuffer</code> with identical content each. <code>TemplateVariableResolver</code>s
+ * can be used to resolve a template variable to a symbol available from the
+ * <code>TemplateContext</code>. A resolved variable may have one or more possible
+ * {@link #getValues() values} which may be presented to the user as choices. If there is no user
+ * interaction the {@link #getDefaultValue() default value} is chosen as textual representation of
+ * the variable.
+ * <p>
+ * Clients may instantiate and extend this class.
+ * </p>
+ *
+ * @see TemplateVariableResolver
+ * @see TemplateBuffer
+ * @since 3.0
+ */
+public class TemplateVariable {
+
+    /** The type name of the variable */
+    private const TemplateVariableType fType;
+    /** The name of the variable. */
+    private const String fName;
+    /** The initial length in the template pattern. */
+    private const int fInitialLength;
+    /** The offsets of the variable. */
+    private int[] fOffsets;
+    /** Flag indicating if the variable has been resolved unambiguously. */
+    private bool fIsUnambiguous;
+    /** Flag indicating if the variable has been resolved by a resolver. */
+    private bool fIsResolved;
+    /**
+     * The proposal strings available for this variable. The first string is
+     * the default value.
+     */
+    private String[] fValues;
+
+    /**
+     * Creates a template variable. The type is used as the name of the
+     * variable.
+     *
+     * @param type the type of the variable
+     * @param defaultValue the default value of the variable
+     * @param offsets the array of offsets of the variable
+     */
+    public this(String type, String defaultValue, int[] offsets) {
+        this(type, [ defaultValue ], offsets);
+    }
+
+    /**
+     * Creates a template variable.
+     *
+     * @param type the type of the variable
+     * @param name the name of the variable
+     * @param defaultValue the default value of the variable
+     * @param offsets the array of offsets of the variable
+     */
+    public this(String type, String name, String defaultValue, int[] offsets) {
+        this(type, name, [ defaultValue ], offsets);
+    }
+
+    /**
+     * Creates a template variable.
+     *
+     * @param type the type of the variable
+     * @param name the name of the variable
+     * @param defaultValue the default value of the variable
+     * @param offsets the array of offsets of the variable
+     * @since 3.3
+     */
+    public this(TemplateVariableType type, String name, String defaultValue, int[] offsets) {
+        this(type, name, [ defaultValue ], offsets);
+    }
+
+    /**
+     * Creates a template variable with multiple possible values. The type is
+     * used as the name of the template.
+     *
+     * @param type the type of the template variable
+     * @param values the values available at this variable, non-empty
+     * @param offsets the array of offsets of the variable
+     */
+    public this(String type, String[] values, int[] offsets) {
+        this(type, type, values, offsets);
+    }
+
+    /**
+     * Creates a template variable with multiple possible values.
+     *
+     * @param type the type of the variable
+     * @param name the name of the variable
+     * @param values the values available at this variable, non-empty
+     * @param offsets the array of offsets of the variable
+     */
+    public this(String type, String name, String[] values, int[] offsets) {
+        this(new TemplateVariableType(type), name, values, offsets);
+    }
+
+    /**
+     * Creates a template variable with multiple possible values.
+     *
+     * @param type the type of the variable
+     * @param name the name of the variable
+     * @param values the values available at this variable, non-empty
+     * @param offsets the array of offsets of the variable
+     * @since 3.3
+     */
+    this(TemplateVariableType type, String name, String[] values, int[] offsets) {
+        Assert.isNotNull(type);
+        Assert.isNotNull(name);
+        fType= type;
+        fName= name;
+        setValues(values);
+        setOffsets(offsets);
+        setUnambiguous(false);
+        setResolved(false);
+        fInitialLength= values[0].length();
+    }
+
+    /**
+     * Returns the type name of the variable.
+     *
+     * @return the type name of the variable
+     */
+    public String getType() {
+        return fType.getName();
+    }
+
+    /**
+     * Returns the type of the variable.
+     *
+     * @return the type of the variable
+     * @since 3.3
+     */
+    public TemplateVariableType getVariableType() {
+        return fType;
+    }
+
+    /**
+     * Returns the name of the variable.
+     *
+     * @return the name of the variable
+     */
+    public String getName() {
+        return fName;
+    }
+
+    /**
+     * Returns the default value of the variable. Typically, this is the first of
+     * the possible values (see {@link #getValues()}.
+     *
+     * @return the default value of the variable
+     */
+    public String getDefaultValue() {
+        return getValues()[0];
+    }
+
+    /**
+     * Returns the possible values for this variable. The returned array is owned by this variable
+     * and must not be modified. The array is not empty.
+     *
+     * @return the possible values for this variable
+     */
+    public String[] getValues() {
+        return fValues;
+    }
+
+    /**
+     * Returns the length of the variable's default value.
+     *
+     * @return the length of the variable
+     */
+    public int getLength() {
+        return getDefaultValue().length();
+    }
+
+    /**
+     * Returns the initial length of the variable. The initial length is the lenght as it occurred
+     * in the template pattern and is used when resolving a template to update the pattern with the
+     * resolved values of the variable.
+     *
+     * @return the initial length of the variable
+     * @since 3.3
+     */
+    final int getInitialLength() {
+        return fInitialLength;
+    }
+
+    /**
+     * Sets the offsets of the variable.
+     *
+     * @param offsets the new offsets of the variable
+     */
+    public void setOffsets(int[] offsets) {
+        fOffsets= TextUtilities.copy(offsets);
+    }
+
+    /**
+     * Returns the offsets of the variable. The returned array is
+     * owned by this variable and must not be modified.
+     *
+     * @return the length of the variable
+     */
+    public int[] getOffsets() {
+        return fOffsets;
+    }
+
+    /**
+     * Resolves the variable to a single value. This is a shortcut for
+     * <code>setValues(new String[] { value })</code>.
+     *
+     * @param value the new default value
+     */
+    public final void setValue(String value) {
+        setValues([ value ]);
+    }
+
+    /**
+     * Resolves the variable to several possible values for this variable, with the first being the
+     * default value.
+     *
+     * @param values a non-empty array of values
+     */
+    public void setValues(String[] values) {
+        Assert.isTrue(values.length > 0);
+        fValues= TextUtilities.copy(values);
+        setResolved(true);
+    }
+
+    /**
+     * Sets the <em>isUnambiguous</em> flag of the variable.
+     *
+     * @param unambiguous the new unambiguous state of the variable
+     */
+    public void setUnambiguous(bool unambiguous) {
+        fIsUnambiguous= unambiguous;
+        if (unambiguous)
+            setResolved(true);
+    }
+
+    /**
+     * Returns <code>true</code> if the variable is unambiguously resolved, <code>false</code> otherwise.
+     *
+     * @return <code>true</code> if the variable is unambiguously resolved, <code>false</code> otherwise
+     */
+    public bool isUnambiguous() {
+        return fIsUnambiguous;
+    }
+
+    /**
+     * Sets the <em>resolved</em> flag of the variable.
+     *
+     * @param resolved the new <em>resolved</em> state
+     * @since 3.3
+     */
+    public void setResolved(bool resolved) {
+        fIsResolved= resolved;
+    }
+
+    /**
+     * Returns <code>true</code> if the variable has been resolved, <code>false</code>
+     * otherwise.
+     *
+     * @return <code>true</code> if the variable has been resolved, <code>false</code> otherwise
+     * @since 3.3
+     */
+    public bool isResolved() {
+        return fIsResolved;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/TemplateVariableResolver.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,196 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.TemplateVariableResolver;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+/**
+ * A <code>TemplateVariableResolver</code> resolves <code>TemplateVariables</code>
+ * of a certain type inside a <code>TemplateContext</code>.
+ * <p>
+ * Clients may instantiate and extend this class.
+ * </p>
+ *
+ * @see TemplateVariable
+ * @since 3.0
+ */
+public class TemplateVariableResolver {
+
+    /** Type of this resolver. */
+    private String fType= null;
+
+    /** Description of the type resolved by this resolver. */
+    private String fDescription= null;
+
+    /**
+     * Creates an instance of <code>TemplateVariableResolver</code>.
+     *
+     * @param type the name of the type
+     * @param description the description for the type
+     */
+    /+protected+/ this(String type, String description) {
+        setType(type);
+        setDescription(description);
+    }
+
+    /**
+     * Creates an empty instance.
+     * <p>
+     * This is a framework-only constructor that exists only so that resolvers
+     * can be contributed via an extension point and that should not be called
+     * in client code except for subclass constructors; use
+     * {@link #TemplateVariableResolver(String, String)} instead.
+     * </p>
+     */
+    public this() {
+    }
+
+    /**
+     * Returns the type of this resolver.
+     *
+     * @return the type
+     */
+    public String getType() {
+        return fType;
+    }
+
+    /**
+     * Returns the description for the resolver.
+     *
+     * @return the description for the resolver
+     */
+    public String getDescription() {
+        return fDescription;
+    }
+
+    /**
+     * Returns an instance of the type resolved by the receiver available in <code>context</code>.
+     * To resolve means to provide a binding to a concrete text object (a
+     * <code>String</code>) in the given context.
+     * <p>
+     * The default implementation looks up the type in the context.</p>
+     *
+     * @param context the context in which to resolve the type
+     * @return the name of the text object of this type, or <code>null</code> if it cannot be determined
+     */
+    protected String resolve(TemplateContext context) {
+        return context.getVariable(getType());
+    }
+
+    /**
+     * Returns all possible bindings available in <code>context</code>. The default
+     * implementation simply returns an array which contains the result of
+     * {@link #resolve(TemplateContext)}, or an empty array if that call returns
+     * <code>null</code>.
+     *
+     * @param context the context in which to resolve the type
+     * @return an array of possible bindings of this type in <code>context</code>
+     */
+    protected String[] resolveAll(TemplateContext context) {
+        String binding= resolve(context);
+        if (binding is null)
+            return new String[0];
+        return [ binding ];
+    }
+
+    /**
+     * Resolves <code>variable</code> in <code>context</code>. To resolve
+     * means to find a valid binding of the receiver's type in the given <code>TemplateContext</code>.
+     * If the variable can be successfully resolved, its value is set using
+     * {@link TemplateVariable#setValues(String[])}.
+     *
+     * @param context the context in which variable is resolved
+     * @param variable the variable to resolve
+     */
+    public void resolve(TemplateVariable variable, TemplateContext context) {
+        String[] bindings= resolveAll(context);
+        if (bindings.length !is 0)
+            variable.setValues(bindings);
+        if (bindings.length > 1)
+            variable.setUnambiguous(false);
+        else
+            variable.setUnambiguous(isUnambiguous(context));
+        variable.setResolved(true);
+    }
+
+    /**
+     * Returns whether this resolver is able to resolve unambiguously. When
+     * resolving a <code>TemplateVariable</code>, its <code>isUmambiguous</code>
+     * state is set to the one of this resolver. By default, this method
+     * returns <code>false</code>. Clients can overwrite this method to give
+     * a hint about whether there should be e.g. prompting for input values for
+     * ambiguous variables.
+     *
+     * @param context the context in which the resolved check should be
+     *        evaluated
+     * @return <code>true</code> if the receiver is unambiguously resolvable
+     *         in <code>context</code>, <code>false</code> otherwise
+     */
+    protected bool isUnambiguous(TemplateContext context) {
+        return false;
+    }
+
+    /**
+     * Sets the description.
+     * <p>
+     * This is a framework-only method that exists only so that resolvers
+     * can be contributed via an extension point and that should not be called
+     * in client code; use {@link #TemplateVariableResolver(String, String)} instead.
+     * </p>
+     *
+     * @param description the description of this resolver
+     */
+    public final void setDescription(String description) {
+        Assert.isNotNull(description);
+        Assert.isTrue(fDescription is null); // may only be called once when initialized
+        fDescription= description;
+    }
+
+    /**
+     * Sets the type name.
+     * <p>
+     * This is a framework-only method that exists only so that resolvers
+     * can be contributed via an extension point and that should not be called
+     * in client code; use {@link #TemplateVariableResolver(String, String)} instead.
+     * </p>
+     *
+     * @param type the type name of this resolver
+     */
+    public final void setType(String type) {
+        Assert.isNotNull(type);
+        Assert.isTrue(fType is null); // may only be called once when initialized
+        fType= type;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/TemplateVariableType.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.TemplateVariableType;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Value object that represents the type of a template variable. A type is defined by its name and
+ * may have parameters.
+ *
+ * @since 3.3
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class TemplateVariableType {
+
+    /** The name of the type. */
+    private const String fName;
+    /** The parameter list. */
+    private const List fParams;
+
+    this(String name) {
+        this(name, new String[0]);
+    }
+
+    this(String name, String[] params) {
+        Assert.isLegal(name !is null);
+        Assert.isLegal(params !is null);
+        fName= name;
+        fParams= Collections.unmodifiableList(new ArrayList(Arrays.asList(stringcast(params))));
+    }
+
+    /**
+     * Returns the type name of this variable type.
+     *
+     * @return the type name of this variable type
+     */
+    public String getName() {
+        return fName;
+    }
+
+    /**
+     * Returns the unmodifiable and possibly empty list of parameters (element type: {@link String})
+     *
+     * @return the list of parameters
+     */
+    public List getParams() {
+        return fParams;
+    }
+
+    /*
+     * @see java.lang.Object#equals(java.lang.Object)
+     */
+    public override int opEquals(Object obj) {
+        if ( cast(TemplateVariableType)obj ) {
+            TemplateVariableType other= cast(TemplateVariableType) obj;
+            return other.fName.equals(fName) && other.fParams.opEquals(cast(Object)fParams);
+        }
+        return false;
+    }
+
+    /*
+     * @see java.lang.Object#hashCode()
+     */
+    public override hash_t toHash() {
+        alias .toHash toHash;
+        return fName.toHash() + fParams.toHash();
+    }
+    /*
+     * @see java.lang.Object#toString()
+     * @since 3.3
+     */
+    public override String toString() {
+        return fName ~ (cast(Object)fParams).toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/TextTemplateMessages.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.TextTemplateMessages;
+
+import dwtx.jface.text.templates.SimpleTemplateVariableResolver; // packageimport
+import dwtx.jface.text.templates.TemplateBuffer; // packageimport
+import dwtx.jface.text.templates.TemplateContext; // packageimport
+import dwtx.jface.text.templates.TemplateContextType; // packageimport
+import dwtx.jface.text.templates.Template; // packageimport
+import dwtx.jface.text.templates.TemplateVariable; // packageimport
+import dwtx.jface.text.templates.PositionBasedCompletionProposal; // packageimport
+import dwtx.jface.text.templates.TemplateException; // packageimport
+import dwtx.jface.text.templates.TemplateTranslator; // packageimport
+import dwtx.jface.text.templates.DocumentTemplateContext; // packageimport
+import dwtx.jface.text.templates.GlobalTemplateVariables; // packageimport
+import dwtx.jface.text.templates.InclusivePositionUpdater; // packageimport
+import dwtx.jface.text.templates.TemplateProposal; // packageimport
+import dwtx.jface.text.templates.ContextTypeRegistry; // packageimport
+import dwtx.jface.text.templates.JFaceTextTemplateMessages; // packageimport
+import dwtx.jface.text.templates.TemplateCompletionProcessor; // packageimport
+import dwtx.jface.text.templates.TemplateVariableType; // packageimport
+import dwtx.jface.text.templates.TemplateVariableResolver; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.dwthelper.ResourceBundle;
+import dwtx.dwtxhelper.MessageFormat;
+
+/*
+ * @since 3.0
+ */
+class TextTemplateMessages {
+
+//     private static const String RESOURCE_BUNDLE= TextTemplateMessages.classinfo.getName();
+    private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+    static this() {
+        fgResourceBundle = ResourceBundle.getBundle(
+            getImportData!("dwtx.jface.text.templates.TextTemplateMessages.properties"));
+    }
+
+    private this() {
+    }
+
+    public static String getString(String key) {
+        try {
+            return fgResourceBundle.getString(key);
+        } catch (MissingResourceException e) {
+            return '!' ~ key ~ '!';
+        }
+    }
+
+    public static String getFormattedString(String key, Object[] args... ) {
+        return MessageFormat.format(getString(key), args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/persistence/TemplatePersistenceData.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,189 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.persistence.TemplatePersistenceData;
+
+import dwtx.jface.text.templates.persistence.TemplateReaderWriter; // packageimport
+import dwtx.jface.text.templates.persistence.TemplatePersistenceMessages; // packageimport
+import dwtx.jface.text.templates.persistence.TemplateStore; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.templates.Template;
+
+
+/**
+ * TemplatePersistenceData stores information about a template. It uniquely
+ * references contributed templates via their id. Contributed templates may be
+ * deleted or modified. All template may be enabled or not.
+ * <p>
+ * Clients may use this class, although this is not usually needed except when
+ * implementing a custom template preference page or template store. This class
+ * is not intended to be subclassed.
+ * </p>
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class TemplatePersistenceData {
+    private const Template fOriginalTemplate;
+    private const String fId;
+    private const bool fOriginalIsEnabled;
+
+    private Template fCustomTemplate= null;
+    private bool fIsDeleted= false;
+    private bool fCustomIsEnabled= true;
+
+    /**
+     * Creates a new, user-added instance that is not linked to a contributed
+     * template.
+     *
+     * @param template the template which is stored by the new instance
+     * @param enabled whether the template is enabled
+     */
+    public this(Template template_, bool enabled) {
+        this(template_, enabled, null);
+    }
+
+    /**
+     * Creates a new instance. If <code>id</code> is not <code>null</code>,
+     * the instance is represents a template that is contributed and can be
+     * identified via its id.
+     *
+     * @param template the template which is stored by the new instance
+     * @param enabled whether the template is enabled
+     * @param id the id of the template, or <code>null</code> if a user-added
+     *        instance should be created
+     */
+    public this(Template template_, bool enabled, String id) {
+        Assert.isNotNull(template_);
+        fOriginalTemplate= template_;
+        fCustomTemplate= template_;
+        fOriginalIsEnabled= enabled;
+        fCustomIsEnabled= enabled;
+        fId= id;
+    }
+
+    /**
+     * Returns the id of this template store, or <code>null</code> if there is none.
+     *
+     * @return the id of this template store
+     */
+    public String getId() {
+        return fId;
+    }
+
+    /**
+     * Returns the deletion state of the stored template. This is only relevant
+     * of contributed templates.
+     *
+     * @return the deletion state of the stored template
+     */
+    public bool isDeleted() {
+        return fIsDeleted;
+    }
+
+    /**
+     * Sets the deletion state of the stored template.
+     *
+     * @param isDeleted the deletion state of the stored template
+     */
+    public void setDeleted(bool isDeleted) {
+        fIsDeleted= isDeleted;
+    }
+
+    /**
+     * Returns the template encapsulated by the receiver.
+     *
+     * @return the template encapsulated by the receiver
+     */
+    public Template getTemplate() {
+        return fCustomTemplate;
+    }
+
+
+    /**
+     * Sets the template encapsulated by the receiver.
+     *
+     * @param template the new template
+     */
+    public void setTemplate(Template template_) {
+        fCustomTemplate= template_;
+    }
+
+    /**
+     * Returns whether the receiver represents a custom template, i.e. is either
+     * a user-added template or a contributed template that has been modified.
+     *
+     * @return <code>true</code> if the contained template is a custom
+     *         template and cannot be reconstructed from the contributed
+     *         templates
+     */
+    public bool isCustom() {
+        return fId is null
+                || fIsDeleted
+                || fOriginalIsEnabled !is fCustomIsEnabled
+                || !fOriginalTemplate.equals(fCustomTemplate);
+    }
+
+    /**
+     * Returns whether the receiver represents a modified template, i.e. a
+     * contributed template that has been changed.
+     *
+     * @return <code>true</code> if the contained template is contributed but has been modified, <code>false</code> otherwise
+     */
+    public bool isModified() {
+        return isCustom() && !isUserAdded();
+    }
+
+    /**
+     * Returns <code>true</code> if the contained template was added by a
+     * user, i.e. does not reference a contributed template.
+     *
+     * @return <code>true</code> if the contained template was added by a user, <code>false</code> otherwise
+     */
+    public bool isUserAdded() {
+        return fId is null;
+    }
+
+
+    /**
+     * Reverts the template to its original setting.
+     */
+    public void revert() {
+        fCustomTemplate= fOriginalTemplate;
+        fCustomIsEnabled= fOriginalIsEnabled;
+        fIsDeleted= false;
+    }
+
+
+    /**
+     * Returns the enablement state of the contained template.
+     *
+     * @return the enablement state of the contained template
+     */
+    public bool isEnabled() {
+        return fCustomIsEnabled;
+    }
+
+    /**
+     * Sets the enablement state of the contained template.
+     *
+     * @param isEnabled the new enablement state of the contained template
+     */
+    public void setEnabled(bool isEnabled) {
+        fCustomIsEnabled= isEnabled;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/persistence/TemplatePersistenceMessages.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.persistence.TemplatePersistenceMessages;
+
+import dwtx.jface.text.templates.persistence.TemplatePersistenceData; // packageimport
+import dwtx.jface.text.templates.persistence.TemplateReaderWriter; // packageimport
+import dwtx.jface.text.templates.persistence.TemplateStore; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.dwthelper.ResourceBundle;
+import dwtx.dwtxhelper.MessageFormat;
+
+/**
+ * @since 3.0
+ */
+class TemplatePersistenceMessages {
+
+//     private static const String RESOURCE_BUNDLE= TemplatePersistenceMessages.classinfo.getName();
+    private static ResourceBundle fgResourceBundle;//= ResourceBundle.getBundle(RESOURCE_BUNDLE);
+
+    static this() {
+        fgResourceBundle = ResourceBundle.getBundle(
+            getImportData!("dwtx.jface.text.templates.persistence.TemplatePersistenceMessages.properties"));
+    }
+
+    private this() {
+    }
+
+    public static String getString(String key) {
+        try {
+            return fgResourceBundle.getString(key);
+        } catch (MissingResourceException e) {
+            return '!' ~ key ~ '!';
+        }
+    }
+
+    public static String getFormattedString(String key, Object[] args...) {
+        return MessageFormat.format(getString(key), args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/persistence/TemplatePersistenceMessages.properties	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2000, 2005 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+TemplateReaderWriter.duplicate.id= Duplicate template id
+TemplateReaderWriter.error.missing_attribute= Missing required attribute
+TemplateReaderWriter.error.illegal_boolean_attribute= Illegal boolean attribute, must be "true" or "false".
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/persistence/TemplateReaderWriter.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,390 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.persistence.TemplateReaderWriter;
+
+import dwtx.jface.text.templates.persistence.TemplatePersistenceData; // packageimport
+import dwtx.jface.text.templates.persistence.TemplatePersistenceMessages; // packageimport
+import dwtx.jface.text.templates.persistence.TemplateStore; // packageimport
+
+
+import dwt.dwthelper.utils;
+import dwt.dwthelper.InputStream;
+import dwtx.dwtxhelper.Collection;
+import dwt.dwthelper.ResourceBundle;
+
+/+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
++/
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.templates.Template;
+
+/**
+ * Serializes templates as character or byte stream and reads the same format
+ * back.
+ * <p>
+ * Clients may instantiate this class, it is not intended to be
+ * subclassed.</p>
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class TemplateReaderWriter {
+
+    private static const String TEMPLATE_ROOT = "templates"; //$NON-NLS-1$
+    private static const String TEMPLATE_ELEMENT = "template"; //$NON-NLS-1$
+    private static const String NAME_ATTRIBUTE= "name"; //$NON-NLS-1$
+    private static const String ID_ATTRIBUTE= "id"; //$NON-NLS-1$
+    private static const String DESCRIPTION_ATTRIBUTE= "description"; //$NON-NLS-1$
+    private static const String CONTEXT_ATTRIBUTE= "context"; //$NON-NLS-1$
+    private static const String ENABLED_ATTRIBUTE= "enabled"; //$NON-NLS-1$
+    private static const String DELETED_ATTRIBUTE= "deleted"; //$NON-NLS-1$
+    /**
+     * @since 3.1
+     */
+    private static const String AUTO_INSERTABLE_ATTRIBUTE= "autoinsert"; //$NON-NLS-1$
+
+    /**
+     * Create a new instance.
+     */
+    public this() {
+    }
+
+    /**
+     * Reads templates from a reader and returns them. The reader must present
+     * a serialized form as produced by the <code>save</code> method.
+     *
+     * @param reader the reader to read templates from
+     * @return the read templates, encapsulated in instances of <code>TemplatePersistenceData</code>
+     * @throws IOException if reading from the stream fails
+     */
+    public TemplatePersistenceData[] read(Reader reader)  {
+        return read(reader, null);
+    }
+
+    /**
+     * Reads the template with identifier <code>id</code> from a reader and
+     * returns it. The reader must present a serialized form as produced by the
+     * <code>save</code> method.
+     *
+     * @param reader the reader to read templates from
+     * @param id the id of the template to return
+     * @return the read template, encapsulated in an instances of
+     *         <code>TemplatePersistenceData</code>
+     * @throws IOException if reading from the stream fails
+     * @since 3.1
+     */
+    public TemplatePersistenceData readSingle(Reader reader, String id)  {
+        TemplatePersistenceData[] datas= read(new InputSource(reader), null, id);
+        if (datas.length > 0)
+            return datas[0];
+        return null;
+    }
+
+    /**
+     * Reads templates from a stream and adds them to the templates.
+     *
+     * @param reader the reader to read templates from
+     * @param bundle a resource bundle to use for translating the read templates, or <code>null</code> if no translation should occur
+     * @return the read templates, encapsulated in instances of <code>TemplatePersistenceData</code>
+     * @throws IOException if reading from the stream fails
+     */
+    public TemplatePersistenceData[] read(Reader reader, ResourceBundle bundle)  {
+        return read(new InputSource(reader), bundle, null);
+    }
+
+    /**
+     * Reads templates from a stream and adds them to the templates.
+     *
+     * @param stream the byte stream to read templates from
+     * @param bundle a resource bundle to use for translating the read templates, or <code>null</code> if no translation should occur
+     * @return the read templates, encapsulated in instances of <code>TemplatePersistenceData</code>
+     * @throws IOException if reading from the stream fails
+     */
+    public TemplatePersistenceData[] read(InputStream stream, ResourceBundle bundle)  {
+        return read(new InputSource(stream), bundle, null);
+    }
+
+    /**
+     * Reads templates from an <code>InputSource</code> and adds them to the templates.
+     *
+     * @param source the input source
+     * @param bundle a resource bundle to use for translating the read templates, or <code>null</code> if no translation should occur
+     * @param singleId the template id to extract, or <code>null</code> to read in all templates
+     * @return the read templates, encapsulated in instances of <code>TemplatePersistenceData</code>
+     * @throws IOException if reading from the stream fails
+     */
+    private TemplatePersistenceData[] read(InputSource source, ResourceBundle bundle, String singleId)  {
+        try {
+            Collection templates= new ArrayList();
+            Set ids= new HashSet();
+
+            DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+            DocumentBuilder parser= factory.newDocumentBuilder();
+            Document document= parser.parse(source);
+
+            NodeList elements= document.getElementsByTagName(TEMPLATE_ELEMENT);
+
+            int count= elements.getLength();
+            for (int i= 0; i !is count; i++) {
+                Node node= elements.item(i);
+                NamedNodeMap attributes= node.getAttributes();
+
+                if (attributes is null)
+                    continue;
+
+                String id= getStringValue(attributes, ID_ATTRIBUTE, null);
+                if (id !is null && ids.contains(id))
+                    throw new IOException(TemplatePersistenceMessages.getString("TemplateReaderWriter.duplicate.id")); //$NON-NLS-1$
+
+                if (singleId !is null && !singleId.equals(id))
+                    continue;
+
+                bool deleted = getBooleanValue(attributes, DELETED_ATTRIBUTE, false);
+
+                String name= getStringValue(attributes, NAME_ATTRIBUTE);
+                name= translateString(name, bundle);
+
+                String description= getStringValue(attributes, DESCRIPTION_ATTRIBUTE, ""); //$NON-NLS-1$
+                description= translateString(description, bundle);
+
+                String context= getStringValue(attributes, CONTEXT_ATTRIBUTE);
+
+                if (name is null || context is null)
+                    throw new IOException(TemplatePersistenceMessages.getString("TemplateReaderWriter.error.missing_attribute")); //$NON-NLS-1$
+
+                bool enabled = getBooleanValue(attributes, ENABLED_ATTRIBUTE, true);
+                bool autoInsertable= getBooleanValue(attributes, AUTO_INSERTABLE_ATTRIBUTE, true);
+
+                StringBuffer buffer= new StringBuffer();
+                NodeList children= node.getChildNodes();
+                for (int j= 0; j !is children.getLength(); j++) {
+                    String value= children.item(j).getNodeValue();
+                    if (value !is null)
+                        buffer.append(value);
+                }
+                String pattern= buffer.toString();
+                pattern= translateString(pattern, bundle);
+
+                Template template_= new Template(name, description, context, pattern, autoInsertable);
+                TemplatePersistenceData data= new TemplatePersistenceData(template_, enabled, id);
+                data.setDeleted(deleted);
+
+                templates.add(data);
+
+                if (singleId !is null && singleId.equals(id))
+                    break;
+            }
+
+            return arraycast!(TemplatePersistenceData)( templates.toArray());
+
+        } catch (ParserConfigurationException e) {
+            Assert.isTrue(false);
+        } catch (SAXException e) {
+            Throwable t= e.getCause();
+            if ( cast(IOException)t )
+                throw cast(IOException) t;
+            else if (t !is null)
+                throw new IOException(t.getMessage());
+            else
+                throw new IOException(e.getMessage());
+        }
+
+        return null; // dummy
+    }
+
+    /**
+     * Saves the templates as XML, encoded as UTF-8 onto the given byte stream.
+     *
+     * @param templates the templates to save
+     * @param stream the byte output to write the templates to in XML
+     * @throws IOException if writing the templates fails
+     */
+    public void save(TemplatePersistenceData[] templates, OutputStream stream)  {
+        save(templates, new StreamResult(stream));
+    }
+
+    /**
+     * Saves the templates as XML.
+     *
+     * @param templates the templates to save
+     * @param writer the writer to write the templates to in XML
+     * @throws IOException if writing the templates fails
+     */
+    public void save(TemplatePersistenceData[] templates, Writer writer)  {
+        save(templates, new StreamResult(writer));
+    }
+
+    /**
+     * Saves the templates as XML.
+     *
+     * @param templates the templates to save
+     * @param result the stream result to write to
+     * @throws IOException if writing the templates fails
+     */
+    private void save(TemplatePersistenceData[] templates, StreamResult result)  {
+        try {
+            DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance();
+            DocumentBuilder builder= factory.newDocumentBuilder();
+            Document document= builder.newDocument();
+
+            Node root= document.createElement(TEMPLATE_ROOT);
+            document.appendChild(root);
+
+            for (int i= 0; i < templates.length; i++) {
+                TemplatePersistenceData data= templates[i];
+                Template template_= data.getTemplate();
+
+                Node node= document.createElement(TEMPLATE_ELEMENT);
+                root.appendChild(node);
+
+                NamedNodeMap attributes= node.getAttributes();
+
+                String id= data.getId();
+                if (id !is null) {
+                    Attr idAttr= document.createAttribute(ID_ATTRIBUTE);
+                    idAttr.setValue(id);
+                    attributes.setNamedItem(idAttr);
+                }
+
+                if (template_ !is null) {
+                    Attr name= document.createAttribute(NAME_ATTRIBUTE);
+                    name.setValue(template_.getName());
+                    attributes.setNamedItem(name);
+                }
+
+                if (template_ !is null) {
+                    Attr description= document.createAttribute(DESCRIPTION_ATTRIBUTE);
+                    description.setValue(template_.getDescription());
+                    attributes.setNamedItem(description);
+                }
+
+                if (template_ !is null) {
+                    Attr context= document.createAttribute(CONTEXT_ATTRIBUTE);
+                    context.setValue(template_.getContextTypeId());
+                    attributes.setNamedItem(context);
+                }
+
+                Attr enabled= document.createAttribute(ENABLED_ATTRIBUTE);
+                enabled.setValue(data.isEnabled() ? Boolean.toString(true) : Boolean.toString(false));
+                attributes.setNamedItem(enabled);
+
+                Attr deleted= document.createAttribute(DELETED_ATTRIBUTE);
+                deleted.setValue(data.isDeleted() ? Boolean.toString(true) : Boolean.toString(false));
+                attributes.setNamedItem(deleted);
+
+                if (template_ !is null) {
+                    Attr autoInsertable= document.createAttribute(AUTO_INSERTABLE_ATTRIBUTE);
+                    autoInsertable.setValue(template_.isAutoInsertable() ? Boolean.toString(true) : Boolean.toString(false));
+                    attributes.setNamedItem(autoInsertable);
+                }
+
+                if (template_ !is null) {
+                    Text pattern= document.createTextNode(template_.getPattern());
+                    node.appendChild(pattern);
+                }
+            }
+
+
+            Transformer transformer=TransformerFactory.newInstance().newTransformer();
+            transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
+            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); //$NON-NLS-1$
+            DOMSource source = new DOMSource(document);
+
+            transformer.transform(source, result);
+
+        } catch (ParserConfigurationException e) {
+            Assert.isTrue(false);
+        } catch (TransformerException e) {
+            if (cast(IOException)e.getException() )
+                throw cast(IOException) e.getException();
+            Assert.isTrue(false);
+        }
+    }
+
+    private bool getBooleanValue(NamedNodeMap attributes, String attribute, bool defaultValue)  {
+        Node enabledNode= attributes.getNamedItem(attribute);
+        if (enabledNode is null)
+            return defaultValue;
+        else if (enabledNode.getNodeValue().equals(Boolean.toString(true)))
+            return true;
+        else if (enabledNode.getNodeValue().equals(Boolean.toString(false)))
+            return false;
+        else
+            throw new SAXException(TemplatePersistenceMessages.getString("TemplateReaderWriter.error.illegal_boolean_attribute")); //$NON-NLS-1$
+    }
+
+    private String getStringValue(NamedNodeMap attributes, String name)  {
+        String val= getStringValue(attributes, name, null);
+        if (val is null)
+            throw new SAXException(TemplatePersistenceMessages.getString("TemplateReaderWriter.error.missing_attribute")); //$NON-NLS-1$
+        return val;
+    }
+
+    private String getStringValue(NamedNodeMap attributes, String name, String defaultValue) {
+        Node node= attributes.getNamedItem(name);
+        return node is null ? defaultValue : node.getNodeValue();
+    }
+
+    private String translateString(String str, ResourceBundle bundle) {
+        if (bundle is null)
+            return str;
+
+        int idx= str.indexOf('%');
+        if (idx is -1) {
+            return str;
+        }
+        StringBuffer buf= new StringBuffer();
+        int k= 0;
+        while (idx !is -1) {
+            buf.append(str.substring(k, idx));
+            for (k= idx + 1; k < str.length() && !Character.isWhitespace(str.charAt(k)); k++) {
+                // loop
+            }
+            String key= str.substring(idx + 1, k);
+            buf.append(getBundleString(key, bundle));
+            idx= str.indexOf('%', k);
+        }
+        buf.append(str.substring(k));
+        return buf.toString();
+    }
+
+    private String getBundleString(String key, ResourceBundle bundle) {
+        if (bundle !is null) {
+            try {
+                return bundle.getString(key);
+            } catch (MissingResourceException e) {
+                return '!' + key + '!';
+            }
+        }
+        return TemplatePersistenceMessages.getString(key); // default messages
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/jface/text/templates/persistence/TemplateStore.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,463 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.jface.text.templates.persistence.TemplateStore;
+
+import dwtx.jface.text.templates.persistence.TemplatePersistenceData; // packageimport
+import dwtx.jface.text.templates.persistence.TemplateReaderWriter; // packageimport
+import dwtx.jface.text.templates.persistence.TemplatePersistenceMessages; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.preference.IPersistentPreferenceStore;
+import dwtx.jface.preference.IPreferenceStore;
+import dwtx.jface.text.templates.ContextTypeRegistry;
+import dwtx.jface.text.templates.Template;
+import dwtx.jface.text.templates.TemplateException;
+import dwtx.jface.util.IPropertyChangeListener;
+import dwtx.jface.util.PropertyChangeEvent;
+
+/**
+ * A collection of templates. Clients may instantiate this class. In order to
+ * load templates contributed using the <code>dwtx.ui.editors.templates</code>
+ * extension point, use a <code>ContributionTemplateStore</code>.
+ *
+ * @since 3.0
+ */
+public class TemplateStore {
+    /** The stored templates. */
+    private const List fTemplates= new ArrayList();
+    /** The preference store. */
+    private IPreferenceStore fPreferenceStore;
+    /**
+     * The key into <code>fPreferenceStore</code> the value of which holds custom templates
+     * encoded as XML.
+     */
+    private String fKey;
+    /**
+     * The context type registry, or <code>null</code> if all templates regardless
+     * of context type should be loaded.
+     */
+    private ContextTypeRegistry fRegistry;
+    /**
+     * Set to <code>true</code> if property change events should be ignored (e.g. during writing
+     * to the preference store).
+     *
+     * @since 3.2
+     */
+    private bool fIgnorePreferenceStoreChanges= false;
+    /**
+     * The property listener, if any is registered, <code>null</code> otherwise.
+     *
+     * @since 3.2
+     */
+    private IPropertyChangeListener fPropertyListener;
+
+
+    /**
+     * Creates a new template store.
+     *
+     * @param store the preference store in which to store custom templates
+     *        under <code>key</code>
+     * @param key the key into <code>store</code> where to store custom
+     *        templates
+     */
+    public this(IPreferenceStore store, String key) {
+        Assert.isNotNull(store);
+        Assert.isNotNull(key);
+        fPreferenceStore= store;
+        fKey= key;
+    }
+
+    /**
+     * Creates a new template store with a context type registry. Only templates
+     * that specify a context type contained in the registry will be loaded by
+     * this store if the registry is not <code>null</code>.
+     *
+     * @param registry a context type registry, or <code>null</code> if all
+     *        templates should be loaded
+     * @param store the preference store in which to store custom templates
+     *        under <code>key</code>
+     * @param key the key into <code>store</code> where to store custom
+     *        templates
+     */
+    public this(ContextTypeRegistry registry, IPreferenceStore store, String key) {
+        this(store, key);
+        fRegistry= registry;
+    }
+
+    /**
+     * Loads the templates from contributions and preferences.
+     *
+     * @throws IOException if loading fails.
+     */
+    public void load()  {
+        fTemplates.clear();
+        loadContributedTemplates();
+        loadCustomTemplates();
+    }
+
+    /**
+     * Starts listening for property changes on the preference store. If the configured preference
+     * key changes, the template store is {@link #load() reloaded}. Call
+     * {@link #stopListeningForPreferenceChanges()} to remove any listener and stop the
+     * auto-updating behavior.
+     *
+     * @since 3.2
+     */
+    public final void startListeningForPreferenceChanges() {
+        if (fPropertyListener is null) {
+            fPropertyListener= new class()  IPropertyChangeListener {
+                public void propertyChange(PropertyChangeEvent event) {
+                    /*
+                     * Don't load if we are in the process of saving ourselves. We are in sync anyway after the
+                     * save operation, and clients may trigger reloading by listening to preference store
+                     * updates.
+                     */
+                    if (!fIgnorePreferenceStoreChanges && fKey.equals(event.getProperty()))
+                        try {
+                            load();
+                        } catch (IOException x) {
+                            handleException(x);
+                        }
+                }
+            };
+            fPreferenceStore.addPropertyChangeListener(fPropertyListener);
+        }
+
+    }
+
+    /**
+     * Stops the auto-updating behavior started by calling
+     * {@link #startListeningForPreferenceChanges()}.
+     *
+     * @since 3.2
+     */
+    public final void stopListeningForPreferenceChanges() {
+        if (fPropertyListener !is null) {
+            fPreferenceStore.removePropertyChangeListener(fPropertyListener);
+            fPropertyListener= null;
+        }
+    }
+
+    /**
+     * Handles an {@link IOException} thrown during reloading the preferences due to a preference
+     * store update. The default is to write to stderr.
+     *
+     * @param x the exception
+     * @since 3.2
+     */
+    protected void handleException(IOException x) {
+        x.printStackTrace();
+    }
+
+    /**
+     * Hook method to load contributed templates. Contributed templates are superseded
+     * by customized versions of user added templates stored in the preferences.
+     * <p>
+     * The default implementation does nothing.</p>
+     *
+     * @throws IOException if loading fails
+     */
+    protected void loadContributedTemplates()  {
+    }
+
+    /**
+     * Adds a template to the internal store. The added templates must have
+     * a unique id.
+     *
+     * @param data the template data to add
+     */
+    protected void internalAdd(TemplatePersistenceData data) {
+        if (!data.isCustom()) {
+            // check if the added template is not a duplicate id
+            String id= data.getId();
+            for (Iterator it= fTemplates.iterator(); it.hasNext();) {
+                TemplatePersistenceData d2= cast(TemplatePersistenceData) it.next();
+                if (d2.getId() !is null && d2.getId().equals(id))
+                    return;
+            }
+            fTemplates.add(data);
+        }
+    }
+
+    /**
+     * Saves the templates to the preferences.
+     *
+     * @throws IOException if the templates cannot be written
+     */
+    public void save()  {
+        ArrayList custom= new ArrayList();
+        for (Iterator it= fTemplates.iterator(); it.hasNext();) {
+            TemplatePersistenceData data= cast(TemplatePersistenceData) it.next();
+            if (data.isCustom() && !(data.isUserAdded() && data.isDeleted())) // don't save deleted user-added templates
+                custom.add(data);
+        }
+
+        StringWriter output= new StringWriter();
+        TemplateReaderWriter writer= new TemplateReaderWriter();
+        writer.save(arraycast!(TemplatePersistenceData)( custom.toArray()), output);
+
+        fIgnorePreferenceStoreChanges= true;
+        try {
+            fPreferenceStore.setValue(fKey, output.toString());
+            if ( cast(IPersistentPreferenceStore)fPreferenceStore )
+                (cast(IPersistentPreferenceStore)fPreferenceStore).save();
+        } finally {
+            fIgnorePreferenceStoreChanges= false;
+        }
+    }
+
+    /**
+     * Adds a template encapsulated in its persistent form.
+     *
+     * @param data the template to add
+     */
+    public void add(TemplatePersistenceData data) {
+
+        if (!validateTemplate(data.getTemplate()))
+            return;
+
+        if (data.isUserAdded()) {
+            fTemplates.add(data);
+        } else {
+            for (Iterator it= fTemplates.iterator(); it.hasNext();) {
+                TemplatePersistenceData d2= cast(TemplatePersistenceData) it.next();
+                if (d2.getId() !is null && d2.getId().equals(data.getId())) {
+                    d2.setTemplate(data.getTemplate());
+                    d2.setDeleted(data.isDeleted());
+                    d2.setEnabled(data.isEnabled());
+                    return;
+                }
+            }
+
+            // add an id which is not contributed as add-on
+            if (data.getTemplate() !is null) {
+                TemplatePersistenceData newData= new TemplatePersistenceData(data.getTemplate(), data.isEnabled());
+                fTemplates.add(newData);
+            }
+        }
+    }
+
+    /**
+     * Removes a template from the store.
+     *
+     * @param data the template to remove
+     */
+    public void delete_(TemplatePersistenceData data) {
+        if (data.isUserAdded())
+            fTemplates.remove(data);
+        else
+            data.setDeleted(true);
+    }
+
+    /**
+     * Restores all contributed templates that have been deleted.
+     */
+    public void restoreDeleted() {
+        for (Iterator it= fTemplates.iterator(); it.hasNext();) {
+            TemplatePersistenceData data= cast(TemplatePersistenceData) it.next();
+            if (data.isDeleted())
+                data.setDeleted(false);
+        }
+    }
+
+    /**
+     * Deletes all user-added templates and reverts all contributed templates.
+     */
+    public void restoreDefaults() {
+        try {
+            fIgnorePreferenceStoreChanges= true;
+            fPreferenceStore.setToDefault(fKey);
+        } finally {
+            fIgnorePreferenceStoreChanges= false;
+        }
+        try {
+            load();
+        } catch (IOException x) {
+            // can't log from jface-text
+            x.printStackTrace();
+        }
+    }
+
+    /**
+     * Returns all enabled templates.
+     *
+     * @return all enabled templates
+     */
+    public Template[] getTemplates() {
+        return getTemplates(null);
+    }
+
+    /**
+     * Returns all enabled templates for the given context type.
+     *
+     * @param contextTypeId the id of the context type of the requested templates, or <code>null</code> if all templates should be returned
+     * @return all enabled templates for the given context type
+     */
+    public Template[] getTemplates(String contextTypeId) {
+        List templates= new ArrayList();
+        for (Iterator it= fTemplates.iterator(); it.hasNext();) {
+            TemplatePersistenceData data= cast(TemplatePersistenceData) it.next();
+            if (data.isEnabled() && !data.isDeleted() && (contextTypeId is null || contextTypeId.equals(data.getTemplate().getContextTypeId())))
+                templates.add(data.getTemplate());
+        }
+
+        return arraycast!(Template)( templates.toArray());
+    }
+
+    /**
+     * Returns the first enabled template that matches the name.
+     *
+     * @param name the name of the template searched for
+     * @return the first enabled template that matches both name and context type id, or <code>null</code> if none is found
+     */
+    public Template findTemplate(String name) {
+        return findTemplate(name, null);
+    }
+
+    /**
+     * Returns the first enabled template that matches both name and context type id.
+     *
+     * @param name the name of the template searched for
+     * @param contextTypeId the context type id to clip unwanted templates, or <code>null</code> if any context type is OK
+     * @return the first enabled template that matches both name and context type id, or <code>null</code> if none is found
+     */
+    public Template findTemplate(String name, String contextTypeId) {
+        Assert.isNotNull(name);
+
+        for (Iterator it= fTemplates.iterator(); it.hasNext();) {
+            TemplatePersistenceData data= cast(TemplatePersistenceData) it.next();
+            Template template_= data.getTemplate();
+            if (data.isEnabled() && !data.isDeleted()
+                    && (contextTypeId is null || contextTypeId.equals(template_.getContextTypeId()))
+                    && name.equals(template_.getName()))
+                return template_;
+        }
+
+        return null;
+    }
+
+    /**
+     * Returns the first enabled template that matches the given template id.
+     *
+     * @param id the id of the template searched for
+     * @return the first enabled template that matches id, or <code>null</code> if none is found
+     * @since 3.1
+     */
+    public Template findTemplateById(String id) {
+        TemplatePersistenceData data= getTemplateData(id);
+        if (data !is null && !data.isDeleted())
+            return data.getTemplate();
+
+        return null;
+    }
+
+    /**
+     * Returns all template data.
+     *
+     * @param includeDeleted whether to include deleted data
+     * @return all template data, whether enabled or not
+     */
+    public TemplatePersistenceData[] getTemplateData(bool includeDeleted) {
+        List datas= new ArrayList();
+        for (Iterator it= fTemplates.iterator(); it.hasNext();) {
+            TemplatePersistenceData data= cast(TemplatePersistenceData) it.next();
+            if (includeDeleted || !data.isDeleted())
+                datas.add(data);
+        }
+
+        return arraycast!(TemplatePersistenceData)( datas.toArray());
+    }
+
+    /**
+     * Returns the template data of the template with id <code>id</code> or
+     * <code>null</code> if no such template can be found.
+     *
+     * @param id the id of the template data
+     * @return the template data of the template with id <code>id</code> or <code>null</code>
+     * @since 3.1
+     */
+    public TemplatePersistenceData getTemplateData(String id) {
+        Assert.isNotNull(id);
+        for (Iterator it= fTemplates.iterator(); it.hasNext();) {
+            TemplatePersistenceData data= cast(TemplatePersistenceData) it.next();
+            if (id.equals(data.getId()))
+                return data;
+        }
+
+        return null;
+    }
+
+    private void loadCustomTemplates()  {
+        String pref= fPreferenceStore.getString(fKey);
+        if (pref !is null && pref.trim().length() > 0) {
+            Reader input= new StringReader(pref);
+            TemplateReaderWriter reader= new TemplateReaderWriter();
+            TemplatePersistenceData[] datas= reader.read(input);
+            for (int i= 0; i < datas.length; i++) {
+                TemplatePersistenceData data= datas[i];
+                add(data);
+            }
+        }
+    }
+
+    /**
+     * Validates a template against the context type registered in the context
+     * type registry. Returns always <code>true</code> if no registry is
+     * present.
+     *
+     * @param template the template to validate
+     * @return <code>true</code> if validation is successful or no context
+     *         type registry is specified, <code>false</code> if validation
+     *         fails
+     */
+    private bool validateTemplate(Template template_) {
+        String contextTypeId= template_.getContextTypeId();
+        if (contextExists(contextTypeId)) {
+            if (fRegistry !is null)
+                try {
+                    fRegistry.getContextType(contextTypeId).validate(template_.getPattern());
+                } catch (TemplateException e) {
+                    return false;
+                }
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Returns <code>true</code> if a context type id specifies a valid context type
+     * or if no context type registry is present.
+     *
+     * @param contextTypeId the context type id to look for
+     * @return <code>true</code> if the context type specified by the id
+     *         is present in the context type registry, or if no registry is
+     *         specified
+     */
+    private bool contextExists(String contextTypeId) {
+        return contextTypeId !is null && (fRegistry is null || fRegistry.getContextType(contextTypeId) !is null);
+    }
+
+    /**
+     * Returns the registry.
+     *
+     * @return Returns the registry
+     */
+    protected final ContextTypeRegistry getRegistry() {
+        return fRegistry;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/org/osgi/framework/Bundle.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1122 @@
+/*
+ * $Header: /cvshome/build/org.osgi.framework/src/org/osgi/framework/Bundle.java,v 1.54 2007/02/21 16:49:05 hargrave Exp $
+ *
+ * Copyright (c) OSGi Alliance (2000, 2007). All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+module dwtx.org.osgi.framework.Bundle;
+
+import dwt.dwthelper.utils;
+
+// import java.io.IOException;
+// import java.io.InputStream;
+// import java.net.URL;
+// import java.util.Dictionary;
+// import java.util.Enumeration;
+
+/**
+ * An installed bundle in the Framework.
+ *
+ * <p>
+ * A <code>Bundle</code> object is the access point to define the lifecycle of
+ * an installed bundle. Each bundle installed in the OSGi environment must have
+ * an associated <code>Bundle</code> object.
+ *
+ * <p>
+ * A bundle must have a unique identity, a <code>long</code>, chosen by the
+ * Framework. This identity must not change during the lifecycle of a bundle,
+ * even when the bundle is updated. Uninstalling and then reinstalling the
+ * bundle must create a new unique identity.
+ *
+ * <p>
+ * A bundle can be in one of six states:
+ * <ul>
+ * <li>{@link #UNINSTALLED}
+ * <li>{@link #INSTALLED}
+ * <li>{@link #RESOLVED}
+ * <li>{@link #STARTING}
+ * <li>{@link #STOPPING}
+ * <li>{@link #ACTIVE}
+ * </ul>
+ * <p>
+ * Values assigned to these states have no specified ordering; they represent
+ * bit values that may be ORed together to determine if a bundle is in one of
+ * the valid states.
+ *
+ * <p>
+ * A bundle should only execute code when its state is one of
+ * <code>STARTING</code>,<code>ACTIVE</code>, or <code>STOPPING</code>.
+ * An <code>UNINSTALLED</code> bundle can not be set to another state; it is a
+ * zombie and can only be reached because references are kept somewhere.
+ *
+ * <p>
+ * The Framework is the only entity that is allowed to create
+ * <code>Bundle</code> objects, and these objects are only valid within the
+ * Framework that created them.
+ *
+ * @ThreadSafe
+ * @version $Revision: 1.54 $
+ */
+public interface Bundle {
+    /**
+     * The bundle is uninstalled and may not be used.
+     *
+     * <p>
+     * The <code>UNINSTALLED</code> state is only visible after a bundle is
+     * uninstalled; the bundle is in an unusable state but references to the
+     * <code>Bundle</code> object may still be available and used for
+     * introspection.
+     * <p>
+     * The value of <code>UNINSTALLED</code> is 0x00000001.
+     */
+    public static const int UNINSTALLED             = 0x00000001;
+
+    /**
+     * The bundle is installed but not yet resolved.
+     *
+     * <p>
+     * A bundle is in the <code>INSTALLED</code> state when it has been
+     * installed in the Framework but is not or cannot be resolved.
+     * <p>
+     * This state is visible if the bundle's code dependencies are not resolved.
+     * The Framework may attempt to resolve an <code>INSTALLED</code> bundle's
+     * code dependencies and move the bundle to the <code>RESOLVED</code>
+     * state.
+     * <p>
+     * The value of <code>INSTALLED</code> is 0x00000002.
+     */
+    public static const int INSTALLED               = 0x00000002;
+
+    /**
+     * The bundle is resolved and is able to be started.
+     *
+     * <p>
+     * A bundle is in the <code>RESOLVED</code> state when the Framework has
+     * successfully resolved the bundle's code dependencies. These dependencies
+     * include:
+     * <ul>
+     * <li>The bundle's class path from its {@link Constants#BUNDLE_CLASSPATH}
+     * Manifest header.
+     * <li>The bundle's package dependencies from its
+     * {@link Constants#EXPORT_PACKAGE} and {@link Constants#IMPORT_PACKAGE}
+     * Manifest headers.
+     * <li>The bundle's required bundle dependencies from its
+     * {@link Constants#REQUIRE_BUNDLE} Manifest header.
+     * <li>A fragment bundle's host dependency from its
+     * {@link Constants#FRAGMENT_HOST} Manifest header.
+     * </ul>
+     * <p>
+     * Note that the bundle is not active yet. A bundle must be put in the
+     * <code>RESOLVED</code> state before it can be started. The Framework may
+     * attempt to resolve a bundle at any time.
+     * <p>
+     * The value of <code>RESOLVED</code> is 0x00000004.
+     */
+    public static const int RESOLVED                = 0x00000004;
+
+    /**
+     * The bundle is in the process of starting.
+     *
+     * <p>
+     * A bundle is in the <code>STARTING</code> state when its
+     * {@link #start(int) start} method is active. A bundle must be in this
+     * state when the bundle's {@link BundleActivator#start} is called. If the
+     * <code>BundleActivator.start</code> method completes without exception,
+     * then the bundle has successfully started and must move to the
+     * <code>ACTIVE</code> state.
+     * <p>
+     * If the bundle has a
+     * {@link Constants#ACTIVATION_LAZY lazy activation policy}, then the
+     * bundle may remain in this state for some time until the activation is
+     * triggered.
+     * <p>
+     * The value of <code>STARTING</code> is 0x00000008.
+     */
+    public static const int STARTING                = 0x00000008;
+
+    /**
+     * The bundle is in the process of stopping.
+     *
+     * <p>
+     * A bundle is in the <code>STOPPING</code> state when its
+     * {@link #stop(int) stop} method is active. A bundle must be in this state
+     * when the bundle's {@link BundleActivator#stop} method is called. When the
+     * <code>BundleActivator.stop</code> method completes the bundle is
+     * stopped and must move to the <code>RESOLVED</code> state.
+     * <p>
+     * The value of <code>STOPPING</code> is 0x00000010.
+     */
+    public static const int STOPPING                = 0x00000010;
+
+    /**
+     * The bundle is now running.
+     *
+     * <p>
+     * A bundle is in the <code>ACTIVE</code> state when it has been
+     * successfully started and activated.
+     * <p>
+     * The value of <code>ACTIVE</code> is 0x00000020.
+     */
+    public static const int ACTIVE                  = 0x00000020;
+
+    /**
+     * The bundle start operation is transient and the persistent autostart
+     * setting of the bundle is not modified.
+     *
+     * <p>
+     * This bit may be set when calling {@link #start(int)} to notify the
+     * framework that the autostart setting of the bundle must not be modified.
+     * If this bit is not set, then the autostart setting of the bundle is
+     * modified.
+     *
+     * @since 1.4
+     * @see #start(int)
+     */
+    public static const int START_TRANSIENT         = 0x00000001;
+
+    /**
+     * The bundle start operation must activate the bundle according to the
+     * bundle's declared
+     * {@link Constants#BUNDLE_ACTIVATIONPOLICY activation policy}.
+     *
+     * <p>
+     * This bit may be set when calling {@link #start(int)} to notify the
+     * framework that the bundle must be activated using the bundle's declared
+     * activation policy.
+     *
+     * @since 1.4
+     * @see Constants#BUNDLE_ACTIVATIONPOLICY
+     * @see #start(int)
+     */
+    public static const int START_ACTIVATION_POLICY = 0x00000002;
+
+    /**
+     * The bundle stop is transient and the persistent autostart setting of the
+     * bundle is not modified.
+     *
+     * <p>
+     * This bit may be set when calling {@link #stop(int)} to notify the
+     * framework that the autostart setting of the bundle must not be modified.
+     * If this bit is not set, then the autostart setting of the bundle is
+     * modified.
+     *
+     * @since 1.4
+     * @see #stop(int)
+     */
+    public static final int STOP_TRANSIENT          = 0x00000001;
+
+    /**
+     * Returns this bundle's current state.
+     *
+     * <p>
+     * A bundle can be in only one state at any time.
+     *
+     * @return An element of <code>UNINSTALLED</code>,<code>INSTALLED</code>,
+     *         <code>RESOLVED</code>,<code>STARTING</code>,
+     *         <code>STOPPING</code>,<code>ACTIVE</code>.
+     */
+    public int getState();
+
+    /**
+     * Starts this bundle.
+     *
+     * <p>
+     * If this bundle's state is <code>UNINSTALLED</code> then an
+     * <code>IllegalStateException</code> is thrown.
+     * <p>
+     * If the Framework implements the optional Start Level service and the
+     * current start level is less than this bundle's start level:
+     * <ul>
+     * <li>If the {@link #START_TRANSIENT} option is set, then a
+     * <code>BundleException</code> is thrown indicating this bundle cannot be
+     * started due to the Framework's current start level.
+     *
+     * <li>Otherwise, the Framework must set this bundle's persistent autostart
+     * setting to <em>Started with declared activation</em> if the
+     * {@link #START_ACTIVATION_POLICY} option is set or
+     * <em>Started with eager activation</em> if not set.
+     * </ul>
+     * <p>
+     * When the Framework's current start level becomes equal to or more than
+     * this bundle's start level, this bundle will be started.
+     * <p>
+     * Otherwise, the following steps are required to start this bundle:
+     * <ol>
+     * <li>If this bundle is in the process of being activated or deactivated
+     * then this method must wait for activation or deactivation to complete
+     * before continuing. If this does not occur in a reasonable time, a
+     * <code>BundleException</code> is thrown to indicate this bundle was
+     * unable to be started.
+     *
+     * <li>If this bundle's state is <code>ACTIVE</code> then this method
+     * returns immediately.
+     *
+     * <li>If the {@link #START_TRANSIENT} option is not set then set this
+     * bundle's autostart setting to <em>Started with declared activation</em>
+     * if the {@link #START_ACTIVATION_POLICY} option is set or
+     * <em>Started with eager activation</em> if not set. When the Framework
+     * is restarted and this bundle's autostart setting is not <em>Stopped</em>,
+     * this bundle must be automatically started.
+     *
+     * <li>If this bundle's state is not <code>RESOLVED</code>, an attempt
+     * is made to resolve this bundle. If the Framework cannot resolve this
+     * bundle, a <code>BundleException</code> is thrown.
+     *
+     * <li>If the {@link #START_ACTIVATION_POLICY} option is set and this
+     * bundle's declared activation policy is
+     * {@link Constants#ACTIVATION_LAZY lazy} then:
+     * <ul>
+     * <li>If this bundle's state is <code>STARTING</code> then this method
+     * returns immediately.
+     * <li>This bundle's state is set to <code>STARTING</code>.
+     * <li>A bundle event of type {@link BundleEvent#LAZY_ACTIVATION} is fired.
+     * <li>This method returns immediately and the remaining steps will be
+     * followed when this bundle's activation is later triggered.
+     * </ul>
+     * <i></i>
+     * <li>This bundle's state is set to <code>STARTING</code>.
+     *
+     * <li>A bundle event of type {@link BundleEvent#STARTING} is fired.
+     *
+     * <li>The {@link BundleActivator#start} method of this bundle's
+     * <code>BundleActivator</code>, if one is specified, is called. If the
+     * <code>BundleActivator</code> is invalid or throws an exception then:
+     * <ul>
+     * <li>This bundle's state is set to <code>STOPPING</code>.
+     * <li>A bundle event of type {@link BundleEvent#STOPPING} is fired.
+     * <li>Any services registered by this bundle must be unregistered.
+     * <li>Any services used by this bundle must be released.
+     * <li>Any listeners registered by this bundle must be removed.
+     * <li>This bundle's state is set to <code>RESOLVED</code>.
+     * <li>A bundle event of type {@link BundleEvent#STOPPED} is fired.
+     * <li>A <code>BundleException</code> is then thrown.
+     * </ul>
+     * <i></i>
+     * <li>If this bundle's state is <code>UNINSTALLED</code>, because this
+     * bundle was uninstalled while the <code>BundleActivator.start</code>
+     * method was running, a <code>BundleException</code> is thrown.
+     *
+     * <li>This bundle's state is set to <code>ACTIVE</code>.
+     *
+     * <li>A bundle event of type {@link BundleEvent#STARTED} is fired.
+     * </ol>
+     *
+     * <b>Preconditions </b>
+     * <ul>
+     * <li><code>getState()</code> in {<code>INSTALLED</code>,
+     * <code>RESOLVED</code>} or {<code>INSTALLED</code>,
+     * <code>RESOLVED</code>, <code>STARTING</code>} if this bundle has a
+     * lazy activation policy.
+     * </ul>
+     * <b>Postconditions, no exceptions thrown </b>
+     * <ul>
+     * <li>Bundle autostart setting is modified unless the
+     * {@link #START_TRANSIENT} option was set.
+     * <li><code>getState()</code> in {<code>ACTIVE</code>} unless the
+     * lazy activation policy was used.
+     * <li><code>BundleActivator.start()</code> has been called and did not
+     * throw an exception unless the lazy activation policy was used.
+     * </ul>
+     * <b>Postconditions, when an exception is thrown </b>
+     * <ul>
+     * <li>Depending on when the exception occurred, bundle autostart setting
+     * is modified unless the {@link #START_TRANSIENT} option was set.
+     * <li><code>getState()</code> not in {<code>STARTING</code>,
+     * <code>ACTIVE</code>}.
+     * </ul>
+     *
+     * @param options The options for starting this bundle. See
+     *        {@link #START_TRANSIENT} and {@link #START_ACTIVATION_POLICY}.
+     *        The Framework must ignore unrecognized options.
+     * @throws BundleException If this bundle could not be started. This could
+     *         be because a code dependency could not be resolved or the
+     *         specified <code>BundleActivator</code> could not be loaded or
+     *         threw an exception or this bundle is a fragment.
+     * @throws java.lang.IllegalStateException If this bundle has been
+     *         uninstalled or this bundle tries to change its own state.
+     * @throws java.lang.SecurityException If the caller does not have the
+     *         appropriate <code>AdminPermission[this,EXECUTE]</code>, and
+     *         the Java Runtime Environment supports permissions.
+     * @since 1.4
+     */
+    public void start(int options);
+
+    /**
+     * Starts this bundle with no options.
+     *
+     * <p>
+     * This method calls <code>start(0)</code>.
+     *
+     * @throws BundleException If this bundle could not be started. This could
+     *         be because a code dependency could not be resolved or the
+     *         specified <code>BundleActivator</code> could not be loaded or
+     *         threw an exception or this bundle is a fragment.
+     * @throws java.lang.IllegalStateException If this bundle has been
+     *         uninstalled or this bundle tries to change its own state.
+     * @throws java.lang.SecurityException If the caller does not have the
+     *         appropriate <code>AdminPermission[this,EXECUTE]</code>, and
+     *         the Java Runtime Environment supports permissions.
+     * @see #start(int)
+     */
+    public void start();
+
+    /**
+     * Stops this bundle.
+     *
+     * <p>
+     * The following steps are required to stop a bundle:
+     * <ol>
+     * <li>If this bundle's state is <code>UNINSTALLED</code> then an
+     * <code>IllegalStateException</code> is thrown.
+     *
+     * <li>If this bundle is in the process of being activated or deactivated
+     * then this method must wait for activation or deactivation to complete
+     * before continuing. If this does not occur in a reasonable time, a
+     * <code>BundleException</code> is thrown to indicate this bundle was
+     * unable to be stopped.
+     * <li>If the {@link #STOP_TRANSIENT} option is not set then then set this
+     * bundle's persistent autostart setting to to <em>Stopped</em>. When the
+     * Framework is restarted and this bundle's autostart setting is
+     * <em>Stopped</em>, this bundle must not be automatically started.
+     *
+     * <li>If this bundle's state is not <code>ACTIVE</code> then this method
+     * returns immediately.
+     *
+     * <li>This bundle's state is set to <code>STOPPING</code>.
+     *
+     * <li>A bundle event of type {@link BundleEvent#STOPPING} is fired.
+     *
+     * <li>The {@link BundleActivator#stop} method of this bundle's
+     * <code>BundleActivator</code>, if one is specified, is called. If that
+     * method throws an exception, this method must continue to stop this
+     * bundle. A <code>BundleException</code> must be thrown after completion
+     * of the remaining steps.
+     *
+     * <li>Any services registered by this bundle must be unregistered.
+     * <li>Any services used by this bundle must be released.
+     * <li>Any listeners registered by this bundle must be removed.
+     *
+     * <li>If this bundle's state is <code>UNINSTALLED</code>, because this
+     * bundle was uninstalled while the <code>BundleActivator.stop</code>
+     * method was running, a <code>BundleException</code> must be thrown.
+     *
+     * <li>This bundle's state is set to <code>RESOLVED</code>.
+     *
+     * <li>A bundle event of type {@link BundleEvent#STOPPED} is fired.
+     * </ol>
+     *
+     * <b>Preconditions </b>
+     * <ul>
+     * <li><code>getState()</code> in {<code>ACTIVE</code>}.
+     * </ul>
+     * <b>Postconditions, no exceptions thrown </b>
+     * <ul>
+     * <li>Bundle autostart setting is modified unless the
+     * {@link #STOP_TRANSIENT} option was set.
+     * <li><code>getState()</code> not in {<code>ACTIVE</code>,
+     * <code>STOPPING</code>}.
+     * <li><code>BundleActivator.stop</code> has been called and did not
+     * throw an exception.
+     * </ul>
+     * <b>Postconditions, when an exception is thrown </b>
+     * <ul>
+     * <li>Bundle autostart setting is modified unless the
+     * {@link #STOP_TRANSIENT} option was set.
+     * </ul>
+     *
+     * @param options The options for stoping this bundle. See
+     *        {@link #STOP_TRANSIENT}. The Framework must ignore unrecognized
+     *        options.
+     * @throws BundleException If this bundle's <code>BundleActivator</code>
+     *         threw an exception or this bundle is a fragment.
+     * @throws java.lang.IllegalStateException If this bundle has been
+     *         uninstalled or this bundle tries to change its own state.
+     * @throws java.lang.SecurityException If the caller does not have the
+     *         appropriate <code>AdminPermission[this,EXECUTE]</code>, and
+     *         the Java Runtime Environment supports permissions.
+     * @since 1.4
+     */
+    public void stop(int options);
+
+    /**
+     * Stops this bundle with no options.
+     *
+     * <p>
+     * This method calls <code>stop(0)</code>.
+     *
+     * @throws BundleException If this bundle's <code>BundleActivator</code>
+     *         threw an exception or this bundle is a fragment.
+     * @throws java.lang.IllegalStateException If this bundle has been
+     *         uninstalled or this bundle tries to change its own state.
+     * @throws java.lang.SecurityException If the caller does not have the
+     *         appropriate <code>AdminPermission[this,EXECUTE]</code>, and
+     *         the Java Runtime Environment supports permissions.
+     * @see #start(int)
+     */
+    public void stop();
+
+    /**
+     * Updates this bundle.
+     *
+     * <p>
+     * If this bundle's state is <code>ACTIVE</code>, it must be stopped
+     * before the update and started after the update successfully completes.
+     *
+     * <p>
+     * If this bundle has exported any packages, these packages must not be
+     * updated. Instead, the previous package version must remain exported until
+     * the <code>PackageAdmin.refreshPackages</code> method has been has been
+     * called or the Framework is relaunched.
+     *
+     * <p>
+     * The following steps are required to update a bundle:
+     * <ol>
+     * <li>If this bundle's state is <code>UNINSTALLED</code> then an
+     * <code>IllegalStateException</code> is thrown.
+     *
+     * <li>If this bundle's state is <code>ACTIVE</code>,
+     * <code>STARTING</code> or <code>STOPPING</code>, this bundle is
+     * stopped as described in the <code>Bundle.stop</code> method. If
+     * <code>Bundle.stop</code> throws an exception, the exception is rethrown
+     * terminating the update.
+     *
+     * <li>The download location of the new version of this bundle is
+     * determined from either this bundle's
+     * {@link Constants#BUNDLE_UPDATELOCATION} Manifest header (if available) or
+     * this bundle's original location.
+     *
+     * <li>The location is interpreted in an implementation dependent manner,
+     * typically as a URL, and the new version of this bundle is obtained from
+     * this location.
+     *
+     * <li>The new version of this bundle is installed. If the Framework is
+     * unable to install the new version of this bundle, the original version of
+     * this bundle must be restored and a <code>BundleException</code> must be
+     * thrown after completion of the remaining steps.
+     *
+     * <li>If this bundle has declared an Bundle-RequiredExecutionEnvironment
+     * header, then the listed execution environments must be verified against
+     * the installed execution environments. If they do not all match, the
+     * original version of this bundle must be restored and a
+     * <code>BundleException</code> must be thrown after completion of the
+     * remaining steps.
+     *
+     * <li>This bundle's state is set to <code>INSTALLED</code>.
+     *
+     * <li>If the new version of this bundle was successfully installed, a
+     * bundle event of type {@link BundleEvent#UPDATED} is fired.
+     *
+     * <li>If this bundle's state was originally <code>ACTIVE</code>, the
+     * updated bundle is started as described in the <code>Bundle.start</code>
+     * method. If <code>Bundle.start</code> throws an exception, a Framework
+     * event of type {@link FrameworkEvent#ERROR} is fired containing the
+     * exception.
+     * </ol>
+     *
+     * <b>Preconditions </b>
+     * <ul>
+     * <li><code>getState()</code> not in {<code>UNINSTALLED</code>}.
+     * </ul>
+     * <b>Postconditions, no exceptions thrown </b>
+     * <ul>
+     * <li><code>getState()</code> in {<code>INSTALLED</code>,
+     * <code>RESOLVED</code>,<code>ACTIVE</code>}.
+     * <li>This bundle has been updated.
+     * </ul>
+     * <b>Postconditions, when an exception is thrown </b>
+     * <ul>
+     * <li><code>getState()</code> in {<code>INSTALLED</code>,
+     * <code>RESOLVED</code>,<code>ACTIVE</code>}.
+     * <li>Original bundle is still used; no update occurred.
+     * </ul>
+     *
+     * @throws BundleException If the update fails.
+     * @throws java.lang.IllegalStateException If this bundle has been
+     *         uninstalled or this bundle tries to change its own state.
+     * @throws java.lang.SecurityException If the caller does not have the
+     *         appropriate <code>AdminPermission[this,LIFECYCLE]</code> for
+     *         both the current bundle and the updated bundle, and the Java
+     *         Runtime Environment supports permissions.
+     * @see #stop()
+     * @see #start()
+     */
+    public void update();
+
+//     /**
+//      * Updates this bundle from an <code>InputStream</code>.
+//      *
+//      * <p>
+//      * This method performs all the steps listed in <code>Bundle.update()</code>,
+//      * except the new version of this bundle must be read from the supplied
+//      * <code>InputStream</code>, rather than a <code>URL</code>.
+//      * <p>
+//      * This method must always close the <code>InputStream</code> when it is
+//      * done, even if an exception is thrown.
+//      *
+//      * @param in The <code>InputStream</code> from which to read the new
+//      *        bundle.
+//      * @throws BundleException If the provided stream cannot be read or the
+//      *         update fails.
+//      * @throws java.lang.IllegalStateException If this bundle has been
+//      *         uninstalled or this bundle tries to change its own state.
+//      * @throws java.lang.SecurityException If the caller does not have the
+//      *         appropriate <code>AdminPermission[this,LIFECYCLE]</code> for
+//      *         both the current bundle and the updated bundle, and the Java
+//      *         Runtime Environment supports permissions.
+//      * @see #update()
+//      */
+//     public void update(InputStream in_);
+//
+//     /**
+//      * Uninstalls this bundle.
+//      *
+//      * <p>
+//      * This method causes the Framework to notify other bundles that this bundle
+//      * is being uninstalled, and then puts this bundle into the
+//      * <code>UNINSTALLED</code> state. The Framework must remove any resources
+//      * related to this bundle that it is able to remove.
+//      *
+//      * <p>
+//      * If this bundle has exported any packages, the Framework must continue to
+//      * make these packages available to their importing bundles until the
+//      * <code>PackageAdmin.refreshPackages</code> method has been called or the
+//      * Framework is relaunched.
+//      *
+//      * <p>
+//      * The following steps are required to uninstall a bundle:
+//      * <ol>
+//      * <li>If this bundle's state is <code>UNINSTALLED</code> then an
+//      * <code>IllegalStateException</code> is thrown.
+//      *
+//      * <li>If this bundle's state is <code>ACTIVE</code>,
+//      * <code>STARTING</code> or <code>STOPPING</code>, this bundle is
+//      * stopped as described in the <code>Bundle.stop</code> method. If
+//      * <code>Bundle.stop</code> throws an exception, a Framework event of type
+//      * {@link FrameworkEvent#ERROR} is fired containing the exception.
+//      *
+//      * <li>This bundle's state is set to <code>UNINSTALLED</code>.
+//      *
+//      * <li>A bundle event of type {@link BundleEvent#UNINSTALLED} is fired.
+//      *
+//      * <li>This bundle and any persistent storage area provided for this bundle
+//      * by the Framework are removed.
+//      * </ol>
+//      *
+//      * <b>Preconditions </b>
+//      * <ul>
+//      * <li><code>getState()</code> not in {<code>UNINSTALLED</code>}.
+//      * </ul>
+//      * <b>Postconditions, no exceptions thrown </b>
+//      * <ul>
+//      * <li><code>getState()</code> in {<code>UNINSTALLED</code>}.
+//      * <li>This bundle has been uninstalled.
+//      * </ul>
+//      * <b>Postconditions, when an exception is thrown </b>
+//      * <ul>
+//      * <li><code>getState()</code> not in {<code>UNINSTALLED</code>}.
+//      * <li>This Bundle has not been uninstalled.
+//      * </ul>
+//      *
+//      * @throws BundleException If the uninstall failed. This can occur if
+//      *         another thread is attempting to change this bundle's state and
+//      *         does not complete in a timely manner.
+//      * @throws java.lang.IllegalStateException If this bundle has been
+//      *         uninstalled or this bundle tries to change its own state.
+//      * @throws java.lang.SecurityException If the caller does not have the
+//      *         appropriate <code>AdminPermission[this,LIFECYCLE]</code>, and
+//      *         the Java Runtime Environment supports permissions.
+//      * @see #stop()
+//      */
+//     public void uninstall();
+//
+//     /**
+//      * Returns this bundle's Manifest headers and values. This method returns
+//      * all the Manifest headers and values from the main section of this
+//      * bundle's Manifest file; that is, all lines prior to the first blank line.
+//      *
+//      * <p>
+//      * Manifest header names are case-insensitive. The methods of the returned
+//      * <code>Dictionary</code> object must operate on header names in a
+//      * case-insensitive manner.
+//      *
+//      * If a Manifest header value starts with &quot;%&quot;, it must be
+//      * localized according to the default locale.
+//      *
+//      * <p>
+//      * For example, the following Manifest headers and values are included if
+//      * they are present in the Manifest file:
+//      *
+//      * <pre>
+//      *     Bundle-Name
+//      *     Bundle-Vendor
+//      *     Bundle-Version
+//      *     Bundle-Description
+//      *     Bundle-DocURL
+//      *     Bundle-ContactAddress
+//      * </pre>
+//      *
+//      * <p>
+//      * This method must continue to return Manifest header information while
+//      * this bundle is in the <code>UNINSTALLED</code> state.
+//      *
+//      * @return A <code>Dictionary</code> object containing this bundle's
+//      *         Manifest headers and values.
+//      *
+//      * @throws java.lang.SecurityException If the caller does not have the
+//      *         appropriate <code>AdminPermission[this,METADATA]</code>, and
+//      *         the Java Runtime Environment supports permissions.
+//      *
+//      * @see Constants#BUNDLE_LOCALIZATION
+//      */
+//     public Dictionary getHeaders();
+//
+//     /**
+//      * Returns this bundle's unique identifier. This bundle is assigned a unique
+//      * identifier by the Framework when it was installed in the OSGi
+//      * environment.
+//      *
+//      * <p>
+//      * A bundle's unique identifier has the following attributes:
+//      * <ul>
+//      * <li>Is unique and persistent.
+//      * <li>Is a <code>long</code>.
+//      * <li>Its value is not reused for another bundle, even after a bundle is
+//      * uninstalled.
+//      * <li>Does not change while a bundle remains installed.
+//      * <li>Does not change when a bundle is updated.
+//      * </ul>
+//      *
+//      * <p>
+//      * This method must continue to return this bundle's unique identifier while
+//      * this bundle is in the <code>UNINSTALLED</code> state.
+//      *
+//      * @return The unique identifier of this bundle.
+//      */
+//     public long getBundleId();
+//
+//     /**
+//      * Returns this bundle's location identifier.
+//      *
+//      * <p>
+//      * The location identifier is the location passed to
+//      * <code>BundleContext.installBundle</code> when a bundle is installed.
+//      * The location identifier does not change while this bundle remains
+//      * installed, even if this bundle is updated.
+//      *
+//      * <p>
+//      * This method must continue to return this bundle's location identifier
+//      * while this bundle is in the <code>UNINSTALLED</code> state.
+//      *
+//      * @return The string representation of this bundle's location identifier.
+//      * @throws java.lang.SecurityException If the caller does not have the
+//      *         appropriate <code>AdminPermission[this,METADATA]</code>, and
+//      *         the Java Runtime Environment supports permissions.
+//      */
+//     public String getLocation();
+//
+//     /**
+//      * Returns this bundle's <code>ServiceReference</code> list for all
+//      * services it has registered or <code>null</code> if this bundle has no
+//      * registered services.
+//      *
+//      * <p>
+//      * If the Java runtime supports permissions, a <code>ServiceReference</code>
+//      * object to a service is included in the returned list only if the caller
+//      * has the <code>ServicePermission</code> to get the service using at
+//      * least one of the named classes the service was registered under.
+//      *
+//      * <p>
+//      * The list is valid at the time of the call to this method, however, as the
+//      * Framework is a very dynamic environment, services can be modified or
+//      * unregistered at anytime.
+//      *
+//      * @return An array of <code>ServiceReference</code> objects or
+//      *         <code>null</code>.
+//      * @throws java.lang.IllegalStateException If this bundle has been
+//      *         uninstalled.
+//      * @see ServiceRegistration
+//      * @see ServiceReference
+//      * @see ServicePermission
+//      */
+//     public ServiceReference[] getRegisteredServices();
+//
+//     /**
+//      * Returns this bundle's <code>ServiceReference</code> list for all
+//      * services it is using or returns <code>null</code> if this bundle is not
+//      * using any services. A bundle is considered to be using a service if its
+//      * use count for that service is greater than zero.
+//      *
+//      * <p>
+//      * If the Java Runtime Environment supports permissions, a
+//      * <code>ServiceReference</code> object to a service is included in the
+//      * returned list only if the caller has the <code>ServicePermission</code>
+//      * to get the service using at least one of the named classes the service
+//      * was registered under.
+//      * <p>
+//      * The list is valid at the time of the call to this method, however, as the
+//      * Framework is a very dynamic environment, services can be modified or
+//      * unregistered at anytime.
+//      *
+//      * @return An array of <code>ServiceReference</code> objects or
+//      *         <code>null</code>.
+//      * @throws java.lang.IllegalStateException If this bundle has been
+//      *         uninstalled.
+//      * @see ServiceReference
+//      * @see ServicePermission
+//      */
+//     public ServiceReference[] getServicesInUse();
+//
+//     /**
+//      * Determines if this bundle has the specified permissions.
+//      *
+//      * <p>
+//      * If the Java Runtime Environment does not support permissions, this method
+//      * always returns <code>true</code>.
+//      * <p>
+//      * <code>permission</code> is of type <code>Object</code> to avoid
+//      * referencing the <code>java.security.Permission</code> class directly.
+//      * This is to allow the Framework to be implemented in Java environments
+//      * which do not support permissions.
+//      *
+//      * <p>
+//      * If the Java Runtime Environment does support permissions, this bundle and
+//      * all its resources including embedded JAR files, belong to the same
+//      * <code>java.security.ProtectionDomain</code>; that is, they must share
+//      * the same set of permissions.
+//      *
+//      * @param permission The permission to verify.
+//      *
+//      * @return <code>true</code> if this bundle has the specified permission
+//      *         or the permissions possessed by this bundle imply the specified
+//      *         permission; <code>false</code> if this bundle does not have the
+//      *         specified permission or <code>permission</code> is not an
+//      *         <code>instanceof</code> <code>java.security.Permission</code>.
+//      *
+//      * @throws java.lang.IllegalStateException If this bundle has been
+//      *         uninstalled.
+//      */
+//     public bool hasPermission(Object permission);
+//
+//     /**
+//      * Find the specified resource from this bundle.
+//      *
+//      * This bundle's class loader is called to search for the specified
+//      * resource. If this bundle's state is <code>INSTALLED</code>, this
+//      * method must attempt to resolve this bundle before attempting to get the
+//      * specified resource. If this bundle cannot be resolved, then only this
+//      * bundle must be searched for the specified resource. Imported packages
+//      * cannot be searched when this bundle has not been resolved. If this bundle
+//      * is a fragment bundle then <code>null</code> is returned.
+//      *
+//      * @param name The name of the resource. See
+//      *        <code>java.lang.ClassLoader.getResource</code> for a description
+//      *        of the format of a resource name.
+//      * @return A URL to the named resource, or <code>null</code> if the
+//      *         resource could not be found or if this bundle is a fragment
+//      *         bundle or if the caller does not have the appropriate
+//      *         <code>AdminPermission[this,RESOURCE]</code>, and the Java
+//      *         Runtime Environment supports permissions.
+//      *
+//      * @since 1.1
+//      * @throws java.lang.IllegalStateException If this bundle has been
+//      *         uninstalled.
+//      * @see #getEntry
+//      * @see #findEntries
+//      */
+//     public URL getResource(String name);
+//
+//     /**
+//      * Returns this bundle's Manifest headers and values localized to the
+//      * specified locale.
+//      *
+//      * <p>
+//      * This method performs the same function as
+//      * <code>Bundle.getHeaders()</code> except the manifest header values are
+//      * localized to the specified locale.
+//      *
+//      * <p>
+//      * If a Manifest header value starts with &quot;%&quot;, it must be
+//      * localized according to the specified locale. If a locale is specified and
+//      * cannot be found, then the header values must be returned using the
+//      * default locale. Localizations are searched for in the following order:
+//      *
+//      * <pre>
+//      *   bn + "_" + Ls + "_" + Cs + "_" + Vs
+//      *   bn + "_" + Ls + "_" + Cs
+//      *   bn + "_" + Ls
+//      *   bn + "_" + Ld + "_" + Cd + "_" + Vd
+//      *   bn + "_" + Ld + "_" + Cd
+//      *   bn + "_" + Ld
+//      *     bn
+//      * </pre>
+//      *
+//      * Where <code>bn</code> is this bundle's localization basename,
+//      * <code>Ls</code>, <code>Cs</code> and <code>Vs</code> are the
+//      * specified locale (language, country, variant) and <code>Ld</code>,
+//      * <code>Cd</code> and <code>Vd</code> are the default locale (language,
+//      * country, variant).
+//      *
+//      * If <code>null</code> is specified as the locale string, the header
+//      * values must be localized using the default locale. If the empty string
+//      * (&quot;&quot;) is specified as the locale string, the header values must
+//      * not be localized and the raw (unlocalized) header values, including any
+//      * leading &quot;%&quot;, must be returned.
+//      *
+//      * <p>
+//      * This method must continue to return Manifest header information while
+//      * this bundle is in the <code>UNINSTALLED</code> state, however the
+//      * header values must only be available in the raw and default locale
+//      * values.
+//      *
+//      * @param locale The locale name into which the header values are to be
+//      *        localized. If the specified locale is <code>null</code> then the
+//      *        locale returned by <code>java.util.Locale.getDefault</code> is
+//      *        used. If the specified locale is the empty string, this method
+//      *        will return the raw (unlocalized) manifest headers including any
+//      *        leading &quot;%&quot;.
+//      * @return A <code>Dictionary</code> object containing this bundle's
+//      *         Manifest headers and values.
+//      *
+//      * @throws java.lang.SecurityException If the caller does not have the
+//      *         appropriate <code>AdminPermission[this,METADATA]</code>, and
+//      *         the Java Runtime Environment supports permissions.
+//      *
+//      * @see #getHeaders()
+//      * @see Constants#BUNDLE_LOCALIZATION
+//      * @since 1.3
+//      */
+//     public Dictionary getHeaders(String locale);
+//
+//     /**
+//      * Returns the symbolic name of this bundle as specified by its
+//      * <code>Bundle-SymbolicName</code> manifest header. The name must be
+//      * unique, it is recommended to use a reverse domain name naming convention
+//      * like that used for java packages. If this bundle does not have a
+//      * specified symbolic name then <code>null</code> is returned.
+//      *
+//      * <p>
+//      * This method must continue to return this bundle's symbolic name while
+//      * this bundle is in the <code>UNINSTALLED</code> state.
+//      *
+//      * @return The symbolic name of this bundle.
+//      * @since 1.3
+//      */
+//     public String getSymbolicName();
+//
+//     /**
+//      * Loads the specified class using this bundle's classloader.
+//      *
+//      * <p>
+//      * If this bundle is a fragment bundle then this method must throw a
+//      * <code>ClassNotFoundException</code>.
+//      *
+//      * <p>
+//      * If this bundle's state is <code>INSTALLED</code>, this method must
+//      * attempt to resolve this bundle before attempting to load the class.
+//      *
+//      * <p>
+//      * If this bundle cannot be resolved, a Framework event of type
+//      * {@link FrameworkEvent#ERROR} is fired containing a
+//      * <code>BundleException</code> with details of the reason this bundle
+//      * could not be resolved. This method must then throw a
+//      * <code>ClassNotFoundException</code>.
+//      *
+//      * <p>
+//      * If this bundle's state is <code>UNINSTALLED</code>, then an
+//      * <code>IllegalStateException</code> is thrown.
+//      *
+//      * @param name The name of the class to load.
+//      * @return The Class object for the requested class.
+//      * @throws java.lang.ClassNotFoundException If no such class can be found or
+//      *         if this bundle is a fragment bundle or if the caller does not
+//      *         have the appropriate <code>AdminPermission[this,CLASS]</code>,
+//      *         and the Java Runtime Environment supports permissions.
+//      * @throws java.lang.IllegalStateException If this bundle has been
+//      *         uninstalled.
+//      * @since 1.3
+//      */
+//     public Class loadClass(String name) throws ClassNotFoundException;
+//
+//     /**
+//      * Find the specified resources from this bundle.
+//      *
+//      * This bundle's class loader is called to search for the specified
+//      * resources. If this bundle's state is <code>INSTALLED</code>, this
+//      * method must attempt to resolve this bundle before attempting to get the
+//      * specified resources. If this bundle cannot be resolved, then only this
+//      * bundle must be searched for the specified resources. Imported packages
+//      * cannot be searched when a bundle has not been resolved. If this bundle is
+//      * a fragment bundle then <code>null</code> is returned.
+//      *
+//      * @param name The name of the resource. See
+//      *        <code>java.lang.ClassLoader.getResources</code> for a
+//      *        description of the format of a resource name.
+//      * @return An enumeration of URLs to the named resources, or
+//      *         <code>null</code> if the resource could not be found or if this
+//      *         bundle is a fragment bundle or if the caller does not have the
+//      *         appropriate <code>AdminPermission[this,RESOURCE]</code>, and
+//      *         the Java Runtime Environment supports permissions.
+//      *
+//      * @since 1.3
+//      * @throws java.lang.IllegalStateException If this bundle has been
+//      *         uninstalled.
+//      * @throws java.io.IOException If there is an I/O error.
+//      */
+//     public Enumeration getResources(String name) throws IOException;
+//
+//     /**
+//      * Returns an Enumeration of all the paths (<code>String</code> objects)
+//      * to entries within this bundle whose longest sub-path matches the
+//      * specified path. This bundle's classloader is not used to search for
+//      * entries. Only the contents of this bundle are searched.
+//      * <p>
+//      * The specified path is always relative to the root of this bundle and may
+//      * begin with a &quot;/&quot;. A path value of &quot;/&quot; indicates the
+//      * root of this bundle.
+//      * <p>
+//      * Returned paths indicating subdirectory paths end with a &quot;/&quot;.
+//      * The returned paths are all relative to the root of this bundle and must
+//      * not begin with &quot;/&quot;.
+//      *
+//      * @param path The path name for which to return entry paths.
+//      * @return An Enumeration of the entry paths (<code>String</code>
+//      *         objects) or <code>null</code> if no entry could be found or if
+//      *         the caller does not have the appropriate
+//      *         <code>AdminPermission[this,RESOURCE]</code> and the Java
+//      *         Runtime Environment supports permissions.
+//      * @throws java.lang.IllegalStateException If this bundle has been
+//      *         uninstalled.
+//      * @since 1.3
+//      */
+//     public Enumeration getEntryPaths(String path);
+//
+//     /**
+//      * Returns a URL to the entry at the specified path in this bundle. This
+//      * bundle's classloader is not used to search for the entry. Only the
+//      * contents of this bundle are searched for the entry.
+//      * <p>
+//      * The specified path is always relative to the root of this bundle and may
+//      * begin with &quot;/&quot;. A path value of &quot;/&quot; indicates the
+//      * root of this bundle.
+//      *
+//      * @param path The path name of the entry.
+//      * @return A URL to the entry, or <code>null</code> if no entry could be
+//      *         found or if the caller does not have the appropriate
+//      *         <code>AdminPermission[this,RESOURCE]</code> and the Java
+//      *         Runtime Environment supports permissions.
+//      *
+//      * @throws java.lang.IllegalStateException If this bundle has been
+//      *         uninstalled.
+//      * @since 1.3
+//      */
+//     public URL getEntry(String path);
+//
+//     /**
+//      * Returns the time when this bundle was last modified. A bundle is
+//      * considered to be modified when it is installed, updated or uninstalled.
+//      *
+//      * <p>
+//      * The time value is the number of milliseconds since January 1, 1970,
+//      * 00:00:00 GMT.
+//      *
+//      * @return The time when this bundle was last modified.
+//      * @since 1.3
+//      */
+//     public long getLastModified();
+//
+//     /**
+//      * Returns entries in this bundle and its attached fragments. This bundle's
+//      * classloader is not used to search for entries. Only the contents of this
+//      * bundle and its attached fragments are searched for the specified entries.
+//      *
+//      * If this bundle's state is <code>INSTALLED</code>, this method must
+//      * attempt to resolve this bundle before attempting to find entries.
+//      *
+//      * <p>
+//      * This method is intended to be used to obtain configuration, setup,
+//      * localization and other information from this bundle. This method takes
+//      * into account that the &quot;contents&quot; of this bundle can be extended
+//      * with fragments. This &quot;bundle space&quot; is not a namespace with
+//      * unique members; the same entry name can be present multiple times. This
+//      * method therefore returns an enumeration of URL objects. These URLs can
+//      * come from different JARs but have the same path name. This method can
+//      * either return only entries in the specified path or recurse into
+//      * subdirectories returning entries in the directory tree beginning at the
+//      * specified path. Fragments can be attached after this bundle is resolved,
+//      * possibly changing the set of URLs returned by this method. If this bundle
+//      * is not resolved, only the entries in the JAR file of this bundle are
+//      * returned.
+//      * <p>
+//      * Examples:
+//      *
+//      * <pre>
+//      * // List all XML files in the OSGI-INF directory and below
+//      * Enumeration e = b.findEntries(&quot;OSGI-INF&quot;, &quot;*.xml&quot;, true);
+//      *
+//      * // Find a specific localization file
+//      * Enumeration e = b.findEntries(&quot;OSGI-INF/l10n&quot;,
+//      *                               &quot;bundle_nl_DU.properties&quot;,
+//      *                               false);
+//      * if (e.hasMoreElements())
+//      *  return (URL) e.nextElement();
+//      * </pre>
+//      *
+//      * @param path The path name in which to look. The path is always relative
+//      *        to the root of this bundle and may begin with &quot;/&quot;. A
+//      *        path value of &quot;/&quot; indicates the root of this bundle.
+//      * @param filePattern The file name pattern for selecting entries in the
+//      *        specified path. The pattern is only matched against the last
+//      *        element of the entry path and it supports substring matching, as
+//      *        specified in the Filter specification, using the wildcard
+//      *        character (&quot;*&quot;). If null is specified, this is
+//      *        equivalent to &quot;*&quot; and matches all files.
+//      * @param recurse If <code>true</code>, recurse into subdirectories.
+//      *        Otherwise only return entries from the specified path.
+//      * @return An enumeration of URL objects for each matching entry, or
+//      *         <code>null</code> if an entry could not be found or if the
+//      *         caller does not have the appropriate
+//      *         <code>AdminPermission[this,RESOURCE]</code>, and the Java
+//      *         Runtime Environment supports permissions. The URLs are sorted
+//      *         such that entries from this bundle are returned first followed by
+//      *         the entries from attached fragments in ascending bundle id order.
+//      *         If this bundle is a fragment, then only matching entries in this
+//      *         fragment are returned.
+//      * @since 1.3
+//      */
+//     public Enumeration findEntries(String path, String filePattern,
+//             bool recurse);
+//
+//     /**
+//      * Returns this bundle's {@link BundleContext}. The returned
+//      * <code>BundleContext</code> can be used by the caller to act on behalf
+//      * of this bundle.
+//      *
+//      * <p>
+//      * If this bundle is not in the {@link #STARTING}, {@link #ACTIVE}, or
+//      * {@link #STOPPING} states or this bundle is a fragment bundle, then this
+//      * bundle has no valid <code>BundleContext</code>. This method will
+//      * return <code>null</code> if this bundle has no valid
+//      * <code>BundleContext</code>.
+//      *
+//      * @return A <code>BundleContext</code> for this bundle or
+//      *         <code>null</code> if this bundle has no valid
+//      *         <code>BundleContext</code>.
+//      * @throws java.lang.SecurityException If the caller does not have the
+//      *         appropriate <code>AdminPermission[this,CONTEXT]</code>, and
+//      *         the Java Runtime Environment supports permissions.
+//      * @since 1.4
+//      */
+//     public BundleContext getBundleContext();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/CopySourceEdit.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,336 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.CopySourceEdit;
+
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+
+/**
+ * A copy source edit denotes the source of a copy operation. Copy
+ * source edits are only valid inside an edit tree if they have a
+ * corresponding target edit. Furthermore the corresponding
+ * target edit can't be a direct or indirect child of the source
+ * edit. Violating one of two requirements will result in a <code>
+ * MalformedTreeException</code> when executing the edit tree.
+ * <p>
+ * A copy source edit can manage an optional source modifier. A
+ * source modifier can provide a set of replace edits which will
+ * to applied to the source before it gets inserted at the target
+ * position.
+ *
+ * @see dwtx.text.edits.CopyTargetEdit
+ *
+ * @since 3.0
+ */
+public final class CopySourceEdit : TextEdit {
+
+    private CopyTargetEdit fTarget;
+    private ISourceModifier fModifier;
+
+    private String fSourceContent;
+    private TextEdit fSourceRoot;
+
+    private static class PartialCopier : TextEditVisitor {
+        TextEdit fResult;
+        List fParents;
+        TextEdit fCurrentParent;
+        public this(){
+            fParents= new ArrayList();
+        }
+        public static TextEdit perform(TextEdit source) {
+            PartialCopier copier= new PartialCopier();
+            source.accept(copier);
+            return copier.fResult;
+        }
+        private void manageCopy(TextEdit copy) {
+            if (fResult is null)
+                fResult= copy;
+            if (fCurrentParent !is null) {
+                fCurrentParent.addChild(copy);
+            }
+            fParents.add(fCurrentParent);
+            fCurrentParent= copy;
+        }
+        public void postVisit(TextEdit edit) {
+            fCurrentParent= cast(TextEdit)fParents.remove(fParents.size() - 1);
+        }
+        public bool visitNode(TextEdit edit) {
+            manageCopy(edit.doCopy_package());
+            return true;
+        }
+        public bool visit(CopySourceEdit edit) {
+            manageCopy(new RangeMarker(edit.getOffset(), edit.getLength()));
+            return true;
+        }
+        public bool visit(CopyTargetEdit edit) {
+            manageCopy(new InsertEdit(edit.getOffset(), edit.getSourceEdit().getContent()));
+            return true;
+        }
+        public bool visit(MoveSourceEdit edit) {
+            manageCopy(new DeleteEdit(edit.getOffset(), edit.getLength()));
+            return true;
+        }
+        public bool visit(MoveTargetEdit edit) {
+            manageCopy(new InsertEdit(edit.getOffset(), edit.getSourceEdit().getContent()));
+            return true;
+        }
+    }
+
+    /**
+     * Constructs a new copy source edit.
+     *
+     * @param offset the edit's offset
+     * @param length the edit's length
+     */
+    public this(int offset, int length) {
+        super(offset, length);
+    }
+
+    /**
+     * Constructs a new copy source edit.
+     *
+     * @param offset the edit's offset
+     * @param length the edit's length
+     * @param target the edit's target
+     */
+    public this(int offset, int length, CopyTargetEdit target) {
+        this(offset, length);
+        setTargetEdit(target);
+    }
+
+    /*
+     * Copy Constructor
+     */
+    private this(CopySourceEdit other) {
+        super(other);
+        if (other.fModifier !is null)
+            fModifier= other.fModifier.copy();
+    }
+
+    /**
+     * Returns the associated target edit or <code>null</code>
+     * if no target edit is associated yet.
+     *
+     * @return the target edit or <code>null</code>
+     */
+    public CopyTargetEdit getTargetEdit() {
+        return fTarget;
+    }
+
+    /**
+     * Sets the target edit.
+     *
+     * @param edit the new target edit.
+     *
+     * @exception MalformedTreeException is thrown if the target edit
+     *  is a direct or indirect child of the source edit
+     */
+    public void setTargetEdit(CopyTargetEdit edit)  {
+        Assert.isNotNull(edit);
+        if (fTarget !is edit) {
+            fTarget= edit;
+            fTarget.setSourceEdit(this);
+        }
+    }
+
+    /**
+     * Returns the current source modifier or <code>null</code>
+     * if no source modifier is set.
+     *
+     * @return the source modifier
+     */
+    public ISourceModifier getSourceModifier() {
+        return fModifier;
+    }
+
+    /**
+     * Sets the optional source modifier.
+     *
+     * @param modifier the source modifier or <code>null</code>
+     *  if no source modification is need.
+     */
+    public void setSourceModifier(ISourceModifier modifier) {
+        fModifier= modifier;
+    }
+
+    /*
+     * @see TextEdit#doCopy
+     */
+    protected TextEdit doCopy() {
+        return new CopySourceEdit(this);
+    }
+
+    /*
+     * @see TextEdit#accept0
+     */
+    protected void accept0(TextEditVisitor visitor) {
+        bool visitChildren= visitor.visit(this);
+        if (visitChildren) {
+            acceptChildren(visitor);
+        }
+    }
+
+    //---- API for CopyTargetEdit ------------------------------------------------
+
+    String getContent() {
+        // The source content can be null if the edit wasn't executed
+        // due to an exclusion list of the text edit processor. Return
+        // the empty string which can be moved without any harm.
+        if (fSourceContent is null)
+            return ""; //$NON-NLS-1$
+        return fSourceContent;
+    }
+
+    void clearContent() {
+        fSourceContent= null;
+    }
+
+    /*
+     * @see TextEdit#postProcessCopy
+     */
+    protected void postProcessCopy(TextEditCopier copier) {
+        if (fTarget !is null) {
+            CopySourceEdit source= cast(CopySourceEdit)copier.getCopy(this);
+            CopyTargetEdit target= cast(CopyTargetEdit)copier.getCopy(fTarget);
+            if (source !is null && target !is null)
+                source.setTargetEdit(target);
+        }
+    }
+
+    //---- consistency check ----------------------------------------------------
+
+    int traverseConsistencyCheck(TextEditProcessor processor, IDocument document, List sourceEdits) {
+        int result= super.traverseConsistencyCheck(processor, document, sourceEdits);
+        // Since source computation takes place in a recursive fashion (see
+        // performSourceComputation) we only do something if we don't have a
+        // computed source already.
+        if (fSourceContent is null) {
+            if (sourceEdits.size() <= result) {
+                List list= new ArrayList();
+                list.add(this);
+                for (int i= sourceEdits.size(); i < result; i++)
+                    sourceEdits.add(cast(Object)null);
+                sourceEdits.add(cast(Object)list);
+            } else {
+                List list= cast(List)sourceEdits.get(result);
+                if (list is null) {
+                    list= new ArrayList();
+                    sourceEdits.add(result, cast(Object)list);
+                }
+                list.add(this);
+            }
+        }
+        return result;
+    }
+
+    void performConsistencyCheck(TextEditProcessor processor, IDocument document)  {
+        if (fTarget is null)
+            throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("CopySourceEdit.no_target")); //$NON-NLS-1$
+        if (fTarget.getSourceEdit() !is this)
+            throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("CopySourceEdit.different_source")); //$NON-NLS-1$
+        /* causes ASTRewrite to fail
+        if (getRoot() !is fTarget.getRoot())
+            throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("CopySourceEdit.different_tree")); //$NON-NLS-1$
+        */
+    }
+
+    //---- source computation -------------------------------------------------------
+
+    void traverseSourceComputation(TextEditProcessor processor, IDocument document) {
+        // always perform source computation independent of processor.considerEdit
+        // The target might need the source and the source is computed in a
+        // temporary buffer.
+        performSourceComputation(processor, document);
+    }
+
+    void performSourceComputation(TextEditProcessor processor, IDocument document) {
+        try {
+            MultiTextEdit root= new MultiTextEdit(getOffset(), getLength());
+            root.internalSetChildren(internalGetChildren());
+            fSourceContent= document.get(getOffset(), getLength());
+            fSourceRoot= PartialCopier.perform(root);
+            fSourceRoot.internalMoveTree(-getOffset());
+            if (fSourceRoot.hasChildren()) {
+                EditDocument subDocument= new EditDocument(fSourceContent);
+                TextEditProcessor subProcessor= TextEditProcessor.createSourceComputationProcessor(subDocument, fSourceRoot, TextEdit.NONE);
+                subProcessor.performEdits();
+                if (needsTransformation())
+                    applyTransformation(subDocument);
+                fSourceContent= subDocument.get();
+                fSourceRoot= null;
+            } else {
+                if (needsTransformation()) {
+                    EditDocument subDocument= new EditDocument(fSourceContent);
+                    applyTransformation(subDocument);
+                    fSourceContent= subDocument.get();
+                }
+            }
+        } catch (BadLocationException cannotHappen) {
+            Assert.isTrue(false);
+        }
+    }
+
+    private bool needsTransformation() {
+        return fModifier !is null;
+    }
+
+    private void applyTransformation(IDocument document)  {
+        TextEdit newEdit= new MultiTextEdit(0, document.getLength());
+        ReplaceEdit[] replaces= fModifier.getModifications(document.get());
+        for (int i= 0; i < replaces.length; i++) {
+            newEdit.addChild(replaces[i]);
+        }
+        try {
+            newEdit.apply(document, TextEdit.NONE);
+        } catch (BadLocationException cannotHappen) {
+            Assert.isTrue(false);
+        }
+    }
+
+    //---- document updating ----------------------------------------------------------------
+
+    int performDocumentUpdating(IDocument document)  {
+        fDelta= 0;
+        return fDelta;
+    }
+
+    //---- region updating ----------------------------------------------------------------
+
+    /*
+     * @see TextEdit#deleteChildren
+     */
+    bool deleteChildren() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/CopyTargetEdit.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,188 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.CopyTargetEdit;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+
+/**
+ * A copy target edit denotes the target of a copy operation. Copy
+ * target edits are only valid inside an edit tree if they have a
+ * corresponding source edit. Furthermore a target edit can't
+ * can't be a direct or indirect child of the associated source edit.
+ * Violating one of two requirements will result in a <code>
+ * MalformedTreeException</code> when executing the edit tree.
+ * <p>
+ * Copy target edits can't be used as a parent for other edits.
+ * Trying to add an edit to a copy target edit results in a <code>
+ * MalformedTreeException</code> as well.
+ *
+ * @see dwtx.text.edits.CopySourceEdit
+ *
+ * @since 3.0
+ */
+public final class CopyTargetEdit : TextEdit {
+
+    private CopySourceEdit fSource;
+
+    /**
+     * Constructs a new copy target edit
+     *
+     * @param offset the edit's offset
+     */
+    public this(int offset) {
+        super(offset, 0);
+    }
+
+    /**
+     * Constructs an new copy target edit
+     *
+     * @param offset the edit's offset
+     * @param source the corresponding source edit
+     */
+    public this(int offset, CopySourceEdit source) {
+        this(offset);
+        setSourceEdit(source);
+    }
+
+    /*
+     * Copy constructor
+     */
+    private this(CopyTargetEdit other) {
+        super(other);
+    }
+
+    /**
+     * Returns the associated source edit or <code>null</code>
+     * if no source edit is associated yet.
+     *
+     * @return the source edit or <code>null</code>
+     */
+    public CopySourceEdit getSourceEdit() {
+        return fSource;
+    }
+
+    /**
+     * Sets the source edit.
+     *
+     * @param edit the source edit
+     *
+     * @exception MalformedTreeException is thrown if the target edit
+     *  is a direct or indirect child of the source edit
+     */
+    public void setSourceEdit(CopySourceEdit edit)  {
+        Assert.isNotNull(edit);
+        if (fSource !is edit) {
+            fSource= edit;
+            fSource.setTargetEdit(this);
+            TextEdit parent= getParent();
+            while (parent !is null) {
+                if (parent is fSource)
+                    throw new MalformedTreeException(parent, this, TextEditMessages.getString("CopyTargetEdit.wrong_parent")); //$NON-NLS-1$
+                parent= parent.getParent();
+            }
+        }
+    }
+
+    /*
+     * @see TextEdit#doCopy
+     */
+    protected TextEdit doCopy() {
+        return new CopyTargetEdit(this);
+    }
+
+    /*
+     * @see TextEdit#postProcessCopy
+     */
+    protected void postProcessCopy(TextEditCopier copier) {
+        if (fSource !is null) {
+            CopyTargetEdit target= cast(CopyTargetEdit)copier.getCopy(this);
+            CopySourceEdit source= cast(CopySourceEdit)copier.getCopy(fSource);
+            if (target !is null && source !is null)
+                target.setSourceEdit(source);
+        }
+    }
+
+    /*
+     * @see TextEdit#accept0
+     */
+    protected void accept0(TextEditVisitor visitor) {
+        bool visitChildren= visitor.visit(this);
+        if (visitChildren) {
+            acceptChildren(visitor);
+        }
+    }
+
+    /*
+     * @see TextEdit#traverseConsistencyCheck
+     */
+    int traverseConsistencyCheck(TextEditProcessor processor, IDocument document, List sourceEdits) {
+        return super.traverseConsistencyCheck(processor, document, sourceEdits) + 1;
+    }
+
+    /*
+     * @see TextEdit#performConsistencyCheck
+     */
+    void performConsistencyCheck(TextEditProcessor processor, IDocument document)  {
+        if (fSource is null)
+            throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("CopyTargetEdit.no_source")); //$NON-NLS-1$
+        if (fSource.getTargetEdit() !is this)
+            throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("CopyTargetEdit.different_target")); //$NON-NLS-1$
+    }
+
+    /*
+     * @see TextEdit#performDocumentUpdating
+     */
+    int performDocumentUpdating(IDocument document)  {
+        String source= fSource.getContent();
+        document.replace(getOffset(), getLength(), source);
+        fDelta= source.length() - getLength();
+        fSource.clearContent();
+        return fDelta;
+    }
+
+    /*
+     * @see TextEdit#deleteChildren
+     */
+    bool deleteChildren() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/CopyingRangeMarker.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.CopyingRangeMarker;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+
+/**
+ * A <code>CopyingRangeMarker</code> can be used to track positions when executing
+ * text edits. Additionally a copying range marker stores a local copy of the
+ * text it captures when it gets executed.
+ *
+ * @since 3.0
+ */
+public final class CopyingRangeMarker : TextEdit {
+
+    private String fText;
+
+    /**
+     * Creates a new <tt>CopyRangeMarker</tt> for the given
+     * offset and length.
+     *
+     * @param offset the marker's offset
+     * @param length the marker's length
+     */
+    public this(int offset, int length) {
+        super(offset, length);
+    }
+
+    /*
+     * Copy constructor
+     */
+    private this(CopyingRangeMarker other) {
+        super(other);
+        fText= other.fText;
+    }
+
+    /*
+     * @see TextEdit#doCopy
+     */
+    protected TextEdit doCopy() {
+        return new CopyingRangeMarker(this);
+    }
+
+    /*
+     * @see TextEdit#accept0
+     */
+    protected void accept0(TextEditVisitor visitor) {
+        bool visitChildren= visitor.visit(this);
+        if (visitChildren) {
+            acceptChildren(visitor);
+        }
+    }
+
+    /*
+     * @see TextEdit#performDocumentUpdating
+     */
+    int performDocumentUpdating(IDocument document)  {
+        fText= document.get(getOffset(), getLength());
+        fDelta= 0;
+        return fDelta;
+    }
+
+    /*
+     * @see TextEdit#deleteChildren
+     */
+    bool deleteChildren() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/DeleteEdit.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.DeleteEdit;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+
+/**
+ * Text edit to delete a range in a document.
+ * <p>
+ * A delete edit is equivalent to <code>ReplaceEdit(
+ * offset, length, "")</code>.
+ *
+ * @since 3.0
+ */
+public final class DeleteEdit : TextEdit {
+
+    /**
+     * Constructs a new delete edit.
+     *
+     * @param offset the offset of the range to replace
+     * @param length the length of the range to replace
+     */
+    public this(int offset, int length) {
+        super(offset, length);
+    }
+
+    /*
+     * Copy constructor
+     */
+    private this(DeleteEdit other) {
+        super(other);
+    }
+
+    /*
+     * @see TextEdit#doCopy
+     */
+    protected TextEdit doCopy() {
+        return new DeleteEdit(this);
+    }
+
+    /*
+     * @see TextEdit#accept0
+     */
+    protected void accept0(TextEditVisitor visitor) {
+        bool visitChildren= visitor.visit(this);
+        if (visitChildren) {
+            acceptChildren(visitor);
+        }
+    }
+
+    /*
+     * @see TextEdit#performDocumentUpdating
+     */
+    int performDocumentUpdating(IDocument document)  {
+        document.replace(getOffset(), getLength(), ""); //$NON-NLS-1$
+        fDelta= -getLength();
+        return fDelta;
+    }
+
+    /*
+     * @see TextEdit#deleteChildren
+     */
+    bool deleteChildren() {
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/EditDocument.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,235 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.EditDocument;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.BadPositionCategoryException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentListener;
+import dwtx.jface.text.IDocumentPartitioner;
+import dwtx.jface.text.IDocumentPartitioningListener;
+import dwtx.jface.text.IPositionUpdater;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.ITypedRegion;
+import dwtx.jface.text.Position;
+
+class EditDocument : IDocument {
+
+    private StringBuffer fBuffer;
+
+    public this(String content) {
+        fBuffer= new StringBuffer(content);
+    }
+
+    public void addDocumentListener(IDocumentListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void addDocumentPartitioningListener(IDocumentPartitioningListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void addPosition(Position position)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public void addPosition(String category, Position position)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public void addPositionCategory(String category) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void addPositionUpdater(IPositionUpdater updater) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void addPrenotifiedDocumentListener(IDocumentListener documentAdapter) {
+        throw new UnsupportedOperationException();
+    }
+
+    public int computeIndexInCategory(String category, int offset)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public int computeNumberOfLines(String text) {
+        throw new UnsupportedOperationException();
+    }
+
+    public ITypedRegion[] computePartitioning(int offset, int length)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public bool containsPosition(String category, int offset, int length) {
+        throw new UnsupportedOperationException();
+    }
+
+    public bool containsPositionCategory(String category) {
+        throw new UnsupportedOperationException();
+    }
+
+    public String get() {
+        return fBuffer.toString();
+    }
+
+    public String get(int offset, int length_)  {
+        return fBuffer.slice()[offset .. offset + length_ ];
+    }
+
+    public char getChar(int offset)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public String getContentType(int offset)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public IDocumentPartitioner getDocumentPartitioner() {
+        throw new UnsupportedOperationException();
+    }
+
+    public String[] getLegalContentTypes() {
+        throw new UnsupportedOperationException();
+    }
+
+    public String[] getLegalLineDelimiters() {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getLength() {
+        return fBuffer.length();
+    }
+
+    public String getLineDelimiter(int line)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public IRegion getLineInformation(int line)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public IRegion getLineInformationOfOffset(int offset)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getLineLength(int line)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getLineOffset(int line)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getLineOfOffset(int offset)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getNumberOfLines() {
+        throw new UnsupportedOperationException();
+    }
+
+    public int getNumberOfLines(int offset, int length)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public ITypedRegion getPartition(int offset)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public String[] getPositionCategories() {
+        throw new UnsupportedOperationException();
+    }
+
+    public Position[] getPositions(String category)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public IPositionUpdater[] getPositionUpdaters() {
+        throw new UnsupportedOperationException();
+    }
+
+    public void insertPositionUpdater(IPositionUpdater updater, int index) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void removeDocumentListener(IDocumentListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void removeDocumentPartitioningListener(IDocumentPartitioningListener listener) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void removePosition(Position position) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void removePosition(String category, Position position)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public void removePositionCategory(String category)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public void removePositionUpdater(IPositionUpdater updater) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void removePrenotifiedDocumentListener(IDocumentListener documentAdapter) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void replace(int offset, int length, String text)  {
+        fBuffer.select(offset, length );
+        fBuffer.replace(text);
+    }
+
+    public int search(int startOffset, String findString, bool forwardSearch, bool caseSensitive, bool wholeWord)  {
+        throw new UnsupportedOperationException();
+    }
+
+    public void set(String text) {
+        throw new UnsupportedOperationException();
+    }
+
+    public void setDocumentPartitioner(IDocumentPartitioner partitioner) {
+        throw new UnsupportedOperationException();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/ISourceModifier.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.ISourceModifier;
+
+import dwtx.text.edits.ReplaceEdit; // packageimport
+
+import dwt.dwthelper.utils;
+
+/**
+ * A source modifier can be used to modify the source of
+ * a move or copy edit before it gets inserted at the target
+ * position. This is useful if the text to be  copied has to
+ * be modified before it is inserted without changing the
+ * original source.
+ *
+ * @since 3.0
+ */
+public interface ISourceModifier {
+    /**
+     * Returns the modification to be done to the passed
+     * string in form of replace edits. The set of returned
+     * replace edits must modify disjoint text regions.
+     * Violating this requirement will result in a <code>
+     * BadLocationException</code> while executing the
+     * associated move or copy edit.
+     * <p>
+     * The caller of this method is responsible to apply
+     * the returned edits to the passed source.
+     *
+     * @param source the source to be copied or moved
+     * @return an array of <code>ReplaceEdits</code>
+     *  describing the modifications.
+     */
+    public ReplaceEdit[] getModifications(String source);
+
+    /**
+     * Creates a copy of this source modifier object. The copy will
+     * be used in a different text edit object. So it should be
+     * created in a way that is doesn't conflict with other text edits
+     * referring to this source modifier.
+     *
+     * @return the copy of the source modifier
+     */
+    public ISourceModifier copy();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/InsertEdit.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.InsertEdit;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+
+/**
+ * Text edit to insert a text at a given position in a
+ * document.
+ * <p>
+ * An insert edit is equivalent to <code>ReplaceEdit(offset, 0, text)
+ * </code>
+ *
+ * @since 3.0
+ */
+public final class InsertEdit : TextEdit {
+
+    private String fText;
+
+    /**
+     * Constructs a new insert edit.
+     *
+     * @param offset the insertion offset
+     * @param text the text to insert
+     */
+    public this(int offset, String text) {
+        super(offset, 0);
+        Assert.isNotNull(text);
+        fText= text;
+    }
+
+    /*
+     * Copy constructor
+     */
+    private this(InsertEdit other) {
+        super(other);
+        fText= other.fText;
+    }
+
+    /**
+     * Returns the text to be inserted.
+     *
+     * @return the edit's text.
+     */
+    public String getText() {
+        return fText;
+    }
+
+    /*
+     * @see TextEdit#doCopy
+     */
+    protected TextEdit doCopy() {
+        return new InsertEdit(this);
+    }
+
+    /*
+     * @see TextEdit#accept0
+     */
+    protected void accept0(TextEditVisitor visitor) {
+        bool visitChildren= visitor.visit(this);
+        if (visitChildren) {
+            acceptChildren(visitor);
+        }
+    }
+
+    /*
+     * @see TextEdit#performDocumentUpdating
+     */
+    int performDocumentUpdating(IDocument document)  {
+        document.replace(getOffset(), getLength(), fText);
+        fDelta= fText.length() - getLength();
+        return fDelta;
+    }
+
+    /*
+     * @see TextEdit#deleteChildren
+     */
+    bool deleteChildren() {
+        return false;
+    }
+
+    /*
+     * @see dwtx.text.edits.TextEdit#internalToString(java.lang.StringBuffer, int)
+     * @since 3.3
+     */
+    void internalToString(StringBuffer buffer, int indent) {
+        super.internalToString(buffer, indent);
+        buffer.append(" <<").append(fText); //$NON-NLS-1$
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/MalformedTreeException.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.MalformedTreeException;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * Thrown to indicate that an edit got added to a parent edit
+ * but the child edit somehow conflicts with the parent or
+ * one of it siblings.
+ * <p>
+ * This class is not intended to be serialized.
+ * </p>
+ *
+ * @see TextEdit#addChild(TextEdit)
+ * @see TextEdit#addChildren(TextEdit[])
+ *
+ * @since 3.0
+ */
+public class MalformedTreeException : RuntimeException {
+
+    // Not intended to be serialized
+    private static const long serialVersionUID= 1L;
+
+    private TextEdit fParent;
+    private TextEdit fChild;
+
+    /**
+     * Constructs a new malformed tree exception.
+     *
+     * @param parent the parent edit
+     * @param child the child edit
+     * @param message the detail message
+     */
+    public this(TextEdit parent, TextEdit child, String message) {
+        super(message);
+        fParent= parent;
+        fChild= child;
+    }
+
+    /**
+     * Returns the parent edit that caused the exception.
+     *
+     * @return the parent edit
+     */
+    public TextEdit getParent() {
+        return fParent;
+    }
+
+    /**
+     * Returns the child edit that caused the exception.
+     *
+     * @return the child edit
+     */
+    public TextEdit getChild() {
+        return fChild;
+    }
+
+    void setParent(TextEdit parent) {
+        fParent= parent;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/Messages.properties	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,35 @@
+###############################################################################
+# Copyright (c) 2000, 2005 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+TextEdit.range_outside= Range of child edit lies outside of parent edit
+TextEdit.overlapping= Overlapping text edits
+TextEdit.deleted_edit= Cannot add deleted edit
+
+CopySourceEdit.no_target= No target edit provided.
+CopySourceEdit.different_source= Target edit has different source edit.
+CopySourceEdit.different_tree= The source and target edits belong to a different text edit tree.
+
+CopyTargetEdit.no_source= No source edit provided.
+CopyTargetEdit.different_target= Source edit has different target edit.
+CopyTargetEdit.wrong_parent=Source edit must not be the parent of the target.
+
+MoveSourceEdit.no_target= No target edit provided.
+MoveSourceEdit.different_source= Target edit has different source edit.
+MoveSourceEdit.different_tree= The source and target edits belong to a different text edit tree.
+
+MoveTargetEdit.no_source= No source edit provided.
+MoveTargetEdit.different_target= Source edit has different target edit.
+MoveTargetEdit.wrong_parent=Source edit must not be the parent of the target.
+
+TextEditProcessor.invalid_length=End position lies outside document range
+
+UndoEdit.no_children=Cannot add children to an undo edit
+UndoEdit.can_not_be_added=Cannot add an undo edit to another edit
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/MoveSourceEdit.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,451 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.MoveSourceEdit;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.Region;
+
+/**
+ * A move source edit denotes the source of a move operation. Move
+ * source edits are only valid inside an edit tree if they have a
+ * corresponding target edit. Furthermore the corresponding target
+ * edit can't be a direct or indirect child of the source edit.
+ * Violating one of two requirements will result in a <code>
+ * MalformedTreeException</code> when executing the edit tree.
+ * <p>
+ * A move source edit can manage an optional source modifier. A
+ * source modifier can provide a set of replace edits which will
+ * to applied to the source before it gets inserted at the target
+ * position.
+ *
+ * @see dwtx.text.edits.MoveTargetEdit
+ * @see dwtx.text.edits.CopySourceEdit
+ *
+ * @since 3.0
+ */
+public final class MoveSourceEdit : TextEdit {
+
+    private MoveTargetEdit fTarget;
+    private ISourceModifier fModifier;
+
+    private String fSourceContent;
+    private MultiTextEdit fSourceRoot;
+
+    /**
+     * Constructs a new move source edit.
+     *
+     * @param offset the edit's offset
+     * @param length the edit's length
+     */
+    public this(int offset, int length) {
+        super(offset, length);
+    }
+
+    /**
+     * Constructs a new copy source edit.
+     *
+     * @param offset the edit's offset
+     * @param length the edit's length
+     * @param target the edit's target
+     */
+    public this(int offset, int length, MoveTargetEdit target) {
+        this(offset, length);
+        setTargetEdit(target);
+    }
+
+    /*
+     * Copy constructor
+     */
+    private this(MoveSourceEdit other) {
+        super(other);
+        if (other.fModifier !is null)
+            fModifier= other.fModifier.copy();
+    }
+
+    /**
+     * Returns the associated target edit or <code>null</code>
+     * if no target edit is associated yet.
+     *
+     * @return the target edit or <code>null</code>
+     */
+    public MoveTargetEdit getTargetEdit() {
+        return fTarget;
+    }
+
+    /**
+     * Sets the target edit.
+     *
+     * @param edit the new target edit.
+     *
+     * @exception MalformedTreeException is thrown if the target edit
+     *  is a direct or indirect child of the source edit
+     */
+    public void setTargetEdit(MoveTargetEdit edit) {
+        fTarget= edit;
+        fTarget.setSourceEdit(this);
+    }
+
+    /**
+     * Returns the current source modifier or <code>null</code>
+     * if no source modifier is set.
+     *
+     * @return the source modifier
+     */
+    public ISourceModifier getSourceModifier() {
+        return fModifier;
+    }
+
+    /**
+     * Sets the optional source modifier.
+     *
+     * @param modifier the source modifier or <code>null</code>
+     *  if no source modification is need.
+     */
+    public void setSourceModifier(ISourceModifier modifier) {
+        fModifier= modifier;
+    }
+
+    //---- API for MoveTargetEdit ---------------------------------------------
+
+    String getContent() {
+        // The source content can be null if the edit wasn't executed
+        // due to an exclusion list of the text edit processor. Return
+        // the empty string which can be moved without any harm.
+        if (fSourceContent is null)
+            return ""; //$NON-NLS-1$
+        return fSourceContent;
+    }
+
+    MultiTextEdit getSourceRoot() {
+        return fSourceRoot;
+    }
+
+    void clearContent() {
+        fSourceContent= null;
+        fSourceRoot= null;
+    }
+
+    //---- Copying -------------------------------------------------------------
+
+    /*
+     * @see TextEdit#doCopy
+     */
+    protected TextEdit doCopy() {
+        return new MoveSourceEdit(this);
+    }
+
+    /*
+     * @see TextEdit#postProcessCopy
+     */
+    protected void postProcessCopy(TextEditCopier copier) {
+        if (fTarget !is null) {
+            MoveSourceEdit source= cast(MoveSourceEdit)copier.getCopy(this);
+            MoveTargetEdit target= cast(MoveTargetEdit)copier.getCopy(fTarget);
+            if (source !is null && target !is null)
+                source.setTargetEdit(target);
+        }
+    }
+
+    //---- Visitor -------------------------------------------------------------
+
+    /*
+     * @see TextEdit#accept0
+     */
+    protected void accept0(TextEditVisitor visitor) {
+        bool visitChildren= visitor.visit(this);
+        if (visitChildren) {
+            acceptChildren(visitor);
+        }
+    }
+
+    //---- consistency check ----------------------------------------------------------------
+
+    int traverseConsistencyCheck(TextEditProcessor processor, IDocument document, List sourceEdits) {
+        int result= super.traverseConsistencyCheck(processor, document, sourceEdits);
+        // Since source computation takes place in a recursive fashion (see
+        // performSourceComputation) we only do something if we don't have a
+        // computed source already.
+        if (fSourceContent is null) {
+            if (sourceEdits.size() <= result) {
+                List list= new ArrayList();
+                list.add(this);
+                for (int i= sourceEdits.size(); i < result; i++)
+                    sourceEdits.add(cast(Object)null);
+                sourceEdits.add(cast(Object)list);
+            } else {
+                List list= cast(List)sourceEdits.get(result);
+                if (list is null) {
+                    list= new ArrayList();
+                    sourceEdits.add(result, cast(Object)list);
+                }
+                list.add(this);
+            }
+        }
+        return result;
+    }
+
+    void performConsistencyCheck(TextEditProcessor processor, IDocument document)  {
+        if (fTarget is null)
+            throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("MoveSourceEdit.no_target")); //$NON-NLS-1$
+        if (fTarget.getSourceEdit() !is this)
+            throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("MoveSourceEdit.different_source"));  //$NON-NLS-1$
+        /* Causes AST rewrite to fail
+        if (getRoot() !is fTarget.getRoot())
+            throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("MoveSourceEdit.different_tree")); //$NON-NLS-1$
+        */
+    }
+
+    //---- source computation --------------------------------------------------------------
+
+    void traverseSourceComputation(TextEditProcessor processor, IDocument document) {
+        // always perform source computation independent of processor.considerEdit
+        // The target might need the source and the source is computed in a
+        // temporary buffer.
+        performSourceComputation(processor, document);
+    }
+
+    void performSourceComputation(TextEditProcessor processor, IDocument document) {
+        try {
+            TextEdit[] children= removeChildren();
+            if (children.length > 0) {
+                String content= document.get(getOffset(), getLength());
+                EditDocument subDocument= new EditDocument(content);
+                fSourceRoot= new MultiTextEdit(getOffset(), getLength());
+                fSourceRoot.addChildren(children);
+                fSourceRoot.internalMoveTree(-getOffset());
+                int processingStyle= getStyle(processor);
+                TextEditProcessor subProcessor= TextEditProcessor.createSourceComputationProcessor(subDocument, fSourceRoot, processingStyle);
+                subProcessor.performEdits();
+                if (needsTransformation())
+                    applyTransformation(subDocument, processingStyle);
+                fSourceContent= subDocument.get();
+            } else {
+                fSourceContent= document.get(getOffset(), getLength());
+                if (needsTransformation()) {
+                    EditDocument subDocument= new EditDocument(fSourceContent);
+                    applyTransformation(subDocument, getStyle(processor));
+                    fSourceContent= subDocument.get();
+                }
+            }
+        } catch (BadLocationException cannotHappen) {
+            Assert.isTrue(false);
+        }
+    }
+
+    private int getStyle(TextEditProcessor processor) {
+        // we never need undo while performing local edits.
+        if ((processor.getStyle() & TextEdit.UPDATE_REGIONS) !is 0)
+            return TextEdit.UPDATE_REGIONS;
+        return TextEdit.NONE;
+    }
+
+    //---- document updating ----------------------------------------------------------------
+
+    int performDocumentUpdating(IDocument document)  {
+        document.replace(getOffset(), getLength(), ""); //$NON-NLS-1$
+        fDelta= -getLength();
+        return fDelta;
+    }
+
+    //---- region updating --------------------------------------------------------------
+
+    /*
+     * @see TextEdit#deleteChildren
+     */
+    bool deleteChildren() {
+        return false;
+    }
+
+    //---- content transformation --------------------------------------------------
+
+    private bool needsTransformation() {
+        return fModifier !is null;
+    }
+
+    private void applyTransformation(IDocument document, int style)  {
+        if ((style & TextEdit.UPDATE_REGIONS) !is 0 && fSourceRoot !is null) {
+            Map editMap= new HashMap();
+            TextEdit newEdit= createEdit(editMap);
+            List replaces= new ArrayList(Arrays.asList(fModifier.getModifications(document.get())));
+            insertEdits(newEdit, replaces);
+            try {
+                newEdit.apply(document, style);
+            } catch (BadLocationException cannotHappen) {
+                Assert.isTrue(false);
+            }
+            restorePositions(editMap);
+        } else {
+            MultiTextEdit newEdit= new MultiTextEdit(0, document.getLength());
+            TextEdit[] replaces= fModifier.getModifications(document.get());
+            for (int i= 0; i < replaces.length; i++) {
+                newEdit.addChild(replaces[i]);
+            }
+            try {
+                newEdit.apply(document, style);
+            } catch (BadLocationException cannotHappen) {
+                Assert.isTrue(false);
+            }
+        }
+    }
+
+    private TextEdit createEdit(Map editMap) {
+        MultiTextEdit result= new MultiTextEdit(0, fSourceRoot.getLength());
+        editMap.put(result, fSourceRoot);
+        createEdit(fSourceRoot, result, editMap);
+        return result;
+    }
+
+    private static void createEdit(TextEdit source, TextEdit target, Map editMap) {
+        TextEdit[] children= source.getChildren();
+        for (int i= 0; i < children.length; i++) {
+            TextEdit child= children[i];
+            // a deleted child remains deleted even if the temporary buffer
+            // gets modified.
+            if (child.isDeleted())
+                continue;
+            RangeMarker marker= new RangeMarker(child.getOffset(), child.getLength());
+            target.addChild(marker);
+            editMap.put(marker, child);
+            createEdit(child, marker, editMap);
+        }
+    }
+
+    private void insertEdits(TextEdit root, List edits) {
+        while(edits.size() > 0) {
+            ReplaceEdit edit= cast(ReplaceEdit)edits.remove(0);
+            insert(root, edit, edits);
+        }
+    }
+    private static void insert(TextEdit parent, ReplaceEdit edit, List edits) {
+        if (!parent.hasChildren()) {
+            parent.addChild(edit);
+            return;
+        }
+        TextEdit[] children= parent.getChildren();
+        // First dive down to find the right parent.
+        int removed= 0;
+        for (int i= 0; i < children.length; i++) {
+            TextEdit child= children[i];
+            if (child.covers(edit)) {
+                insert(child, edit, edits);
+                return;
+            } else if (edit.covers(child)) {
+                parent.removeChild(i - removed++);
+                edit.addChild(child);
+            } else {
+                IRegion intersect= intersect(edit, child);
+                if (intersect !is null) {
+                    ReplaceEdit[] splits= splitEdit(edit, intersect);
+                    insert(child, splits[0], edits);
+                    edits.add(splits[1]);
+                    return;
+                }
+            }
+        }
+        parent.addChild(edit);
+    }
+
+    public static IRegion intersect(TextEdit op1, TextEdit op2) {
+        int offset1= op1.getOffset();
+        int length1= op1.getLength();
+        int end1= offset1 + length1 - 1;
+        int offset2= op2.getOffset();
+        if (end1 < offset2)
+            return null;
+        int length2= op2.getLength();
+        int end2= offset2 + length2 - 1;
+        if (end2 < offset1)
+            return null;
+
+        int end= Math.min(end1, end2);
+        if (offset1 < offset2) {
+            return new Region(offset2, end - offset2 + 1);
+        }
+        return new Region(offset1, end - offset1 + 1);
+    }
+
+    private static ReplaceEdit[] splitEdit(ReplaceEdit edit, IRegion intersect) {
+        if (edit.getOffset() !is intersect.getOffset())
+            return splitIntersectRight(edit, intersect);
+        return splitIntersectLeft(edit, intersect);
+    }
+
+    private static ReplaceEdit[] splitIntersectRight(ReplaceEdit edit, IRegion intersect) {
+        ReplaceEdit[] result= new ReplaceEdit[2];
+        // this is the actual delete. We use replace to only deal with one type
+        result[0]= new ReplaceEdit(intersect.getOffset(), intersect.getLength(), ""); //$NON-NLS-1$
+        result[1]= new ReplaceEdit(
+                            edit.getOffset(),
+                            intersect.getOffset() - edit.getOffset(),
+                            edit.getText());
+        return result;
+    }
+
+    private static ReplaceEdit[] splitIntersectLeft(ReplaceEdit edit, IRegion intersect) {
+        ReplaceEdit[] result= new ReplaceEdit[2];
+        result[0]= new ReplaceEdit(intersect.getOffset(), intersect.getLength(), edit.getText());
+        result[1]= new ReplaceEdit( // this is the actual delete. We use replace to only deal with one type
+                            intersect.getOffset() + intersect.getLength(),
+                            edit.getLength() - intersect.getLength(),
+                            ""); //$NON-NLS-1$
+        return result;
+    }
+
+    private static void restorePositions(Map editMap) {
+        for (Iterator iter= editMap.keySet().iterator(); iter.hasNext();) {
+            TextEdit marker= cast(TextEdit)iter.next();
+            TextEdit edit= cast(TextEdit)editMap.get(marker);
+            if (marker.isDeleted()) {
+                edit.markAsDeleted();
+            } else {
+                edit.adjustOffset(marker.getOffset() - edit.getOffset());
+                edit.adjustLength(marker.getLength() - edit.getLength());
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/MoveTargetEdit.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.MoveTargetEdit;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+
+/**
+ * A move target edit denotes the target of a move operation. Move
+ * target edits are only valid inside an edit tree if they have a
+ * corresponding source edit. Furthermore a target edit can't
+ * can't be a direct or indirect child of its associated source edit.
+ * Violating one of two requirements will result in a <code>
+ * MalformedTreeException</code> when executing the edit tree.
+ * <p>
+ * Move target edits can't be used as a parent for other edits.
+ * Trying to add an edit to a move target edit results in a <code>
+ * MalformedTreeException</code> as well.
+ *
+ * @see dwtx.text.edits.MoveSourceEdit
+ * @see dwtx.text.edits.CopyTargetEdit
+ *
+ * @since 3.0
+ */
+public final class MoveTargetEdit : TextEdit {
+
+    private MoveSourceEdit fSource;
+
+    /**
+     * Constructs a new move target edit
+     *
+     * @param offset the edit's offset
+     */
+    public this(int offset) {
+        super(offset, 0);
+    }
+
+    /**
+     * Constructs an new move target edit
+     *
+     * @param offset the edit's offset
+     * @param source the corresponding source edit
+     */
+    public this(int offset, MoveSourceEdit source) {
+        this(offset);
+        setSourceEdit(source);
+    }
+
+    /*
+     * Copy constructor
+     */
+    private this(MoveTargetEdit other) {
+        super(other);
+    }
+
+    /**
+     * Returns the associated source edit or <code>null</code>
+     * if no source edit is associated yet.
+     *
+     * @return the source edit or <code>null</code>
+     */
+    public MoveSourceEdit getSourceEdit() {
+        return fSource;
+    }
+
+    /**
+     * Sets the source edit.
+     *
+     * @param edit the source edit
+     *
+     * @exception MalformedTreeException is thrown if the target edit
+     *  is a direct or indirect child of the source edit
+     */
+    public void setSourceEdit(MoveSourceEdit edit) {
+        if (fSource !is edit) {
+            fSource= edit;
+            fSource.setTargetEdit(this);
+            TextEdit parent= getParent();
+            while (parent !is null) {
+                if (parent is fSource)
+                    throw new MalformedTreeException(parent, this, TextEditMessages.getString("MoveTargetEdit.wrong_parent")); //$NON-NLS-1$
+                parent= parent.getParent();
+            }
+        }
+    }
+
+    /*
+     * @see TextEdit#doCopy
+     */
+    protected TextEdit doCopy() {
+        return new MoveTargetEdit(this);
+    }
+
+    /*
+     * @see TextEdit#postProcessCopy
+     */
+    protected void postProcessCopy(TextEditCopier copier) {
+        if (fSource !is null) {
+            MoveTargetEdit target= cast(MoveTargetEdit)copier.getCopy(this);
+            MoveSourceEdit source= cast(MoveSourceEdit)copier.getCopy(fSource);
+            if (target !is null && source !is null)
+                target.setSourceEdit(source);
+        }
+    }
+
+    /*
+     * @see TextEdit#accept0
+     */
+    protected void accept0(TextEditVisitor visitor) {
+        bool visitChildren= visitor.visit(this);
+        if (visitChildren) {
+            acceptChildren(visitor);
+        }
+    }
+
+    //---- consistency check ----------------------------------------------------------
+
+    /*
+     * @see TextEdit#traverseConsistencyCheck
+     */
+    int traverseConsistencyCheck(TextEditProcessor processor, IDocument document, List sourceEdits) {
+        return super.traverseConsistencyCheck(processor, document, sourceEdits) + 1;
+    }
+
+    /*
+     * @see TextEdit#performConsistencyCheck
+     */
+    void performConsistencyCheck(TextEditProcessor processor, IDocument document)  {
+        if (fSource is null)
+            throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("MoveTargetEdit.no_source")); //$NON-NLS-1$
+        if (fSource.getTargetEdit() !is this)
+            throw new MalformedTreeException(getParent(), this, TextEditMessages.getString("MoveTargetEdit.different_target")); //$NON-NLS-1$
+    }
+
+    //---- document updating ----------------------------------------------------------------
+
+    /*
+     * @see TextEdit#performDocumentUpdating
+     */
+    int performDocumentUpdating(IDocument document)  {
+        String source= fSource.getContent();
+        document.replace(getOffset(), getLength(), source);
+        fDelta= source.length() - getLength();
+
+        MultiTextEdit sourceRoot= fSource.getSourceRoot();
+        if (sourceRoot !is null) {
+            sourceRoot.internalMoveTree(getOffset());
+            TextEdit[] sourceChildren= sourceRoot.removeChildren();
+            List children= new ArrayList(sourceChildren.length);
+            for (int i= 0; i < sourceChildren.length; i++) {
+                TextEdit child= sourceChildren[i];
+                child.internalSetParent(this);
+                children.add(child);
+            }
+            internalSetChildren(children);
+        }
+        fSource.clearContent();
+        return fDelta;
+    }
+
+    //---- region updating --------------------------------------------------------------
+
+    /*
+     * @see dwtx.text.edits.TextEdit#traversePassThree
+     */
+    int traverseRegionUpdating(TextEditProcessor processor, IDocument document, int accumulatedDelta, bool delete_) {
+        // the children got already updated / normalized while they got removed
+        // from the source edit. So we only have to adjust the offset computed to
+        // far.
+        if (delete_) {
+            deleteTree();
+        } else {
+            internalMoveTree(accumulatedDelta);
+        }
+        return accumulatedDelta + fDelta;
+    }
+
+    bool deleteChildren() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/MultiTextEdit.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,254 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.MultiTextEdit;
+
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+
+/**
+ * A multi-text edit can be used to aggregate several edits into
+ * one edit. The edit itself doesn't modify a document.
+ * <p>
+ * Clients are allowed to implement subclasses of a multi-text
+ * edit.Subclasses must implement <code>doCopy()</code> to ensure
+ * the a copy of the right type is created. Not implementing
+ * <code>doCopy()</code> in subclasses will result in an assertion
+ * failure during copying.
+ *
+ * @since 3.0
+ */
+public class MultiTextEdit : TextEdit {
+
+    private bool fDefined;
+
+    /**
+     * Creates a new <code>MultiTextEdit</code>. The range
+     * of the edit is determined by the range of its children.
+     *
+     * Adding this edit to a parent edit sets its range to the
+     * range covered by its children. If the edit doesn't have
+     * any children its offset is set to the parent's offset
+     * and its length is set to 0.
+     */
+    public this() {
+        super(0, Integer.MAX_VALUE);
+        fDefined= false;
+    }
+
+    /**
+     * Creates a new </code>MultiTextEdit</code> for the given
+     * range. Adding a child to this edit which isn't covered
+     * by the given range will result in an exception.
+     *
+     * @param offset the edit's offset
+     * @param length the edit's length.
+     * @see TextEdit#addChild(TextEdit)
+     * @see TextEdit#addChildren(TextEdit[])
+     */
+    public this(int offset, int length) {
+        super(offset, length);
+        fDefined= true;
+    }
+
+    /*
+     * Copy constructor.
+     */
+    protected this(MultiTextEdit other) {
+        super(other);
+    }
+
+    /**
+     * Checks the edit's integrity.
+     * <p>
+     * Note that this method <b>should only be called</b> by the edit
+     * framework and not by normal clients.</p>
+     *<p>
+     * This default implementation does nothing. Subclasses may override
+     * if needed.</p>
+     *
+     * @exception MalformedTreeException if the edit isn't in a valid state
+     *  and can therefore not be executed
+     */
+    protected void checkIntegrity()  {
+        // does nothing
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    final bool isDefined() {
+        if (fDefined)
+            return true;
+        return hasChildren();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final int getOffset() {
+        if (fDefined)
+            return super.getOffset();
+
+        List/*<TextEdit>*/ children= internalGetChildren();
+        if (children is null || children.size() is 0)
+            return 0;
+        // the children are already sorted
+        return (cast(TextEdit)children.get(0)).getOffset();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final int getLength() {
+        if (fDefined)
+            return super.getLength();
+
+        List/*<TextEdit>*/ children= internalGetChildren();
+        if (children is null || children.size() is 0)
+            return 0;
+        // the children are already sorted
+        TextEdit first= cast(TextEdit)children.get(0);
+        TextEdit last= cast(TextEdit)children.get(children.size() - 1);
+        return last.getOffset() - first.getOffset() + last.getLength();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public final bool covers(TextEdit other) {
+        if (fDefined)
+            return super.covers(other);
+        // an undefined multiple text edit covers everything
+        return true;
+    }
+
+    /*
+     * @see dwtx.text.edits.TextEdit#canZeroLengthCover()
+     */
+    protected bool canZeroLengthCover() {
+        return true;
+    }
+
+    /*
+     * @see TextEdit#copy
+     */
+    protected TextEdit doCopy() {
+        Assert.isTrue(MultiTextEdit.classinfo is this.classinfo, "Subclasses must reimplement copy0"); //$NON-NLS-1$
+        return new MultiTextEdit(this);
+    }
+
+    /*
+     * @see TextEdit#accept0
+     */
+    protected void accept0(TextEditVisitor visitor) {
+        bool visitChildren= visitor.visit(this);
+        if (visitChildren) {
+            acceptChildren(visitor);
+        }
+    }
+
+    /*
+     * @see dwtx.text.edits.TextEdit#adjustOffset(int)
+     * @since 3.1
+     */
+    void adjustOffset(int delta) {
+        if (fDefined)
+            super.adjustOffset(delta);
+    }
+
+    /*
+     * @see dwtx.text.edits.TextEdit#adjustLength(int)
+     * @since 3.1
+     */
+    void adjustLength(int delta) {
+        if (fDefined)
+            super.adjustLength(delta);
+    }
+
+    /*
+     * @see TextEdit#performConsistencyCheck
+     */
+    void performConsistencyCheck(TextEditProcessor processor, IDocument document)  {
+        checkIntegrity();
+    }
+
+    /*
+     * @see TextEdit#performDocumentUpdating
+     */
+    int performDocumentUpdating(IDocument document)  {
+        fDelta= 0;
+        return fDelta;
+    }
+
+    /*
+     * @see TextEdit#deleteChildren
+     */
+    bool deleteChildren() {
+        return false;
+    }
+
+    void aboutToBeAdded(TextEdit parent) {
+        defineRegion(parent.getOffset());
+    }
+
+    void defineRegion(int parentOffset) {
+        if (fDefined)
+            return;
+        if (hasChildren()) {
+            IRegion region= getCoverage(getChildren());
+            internalSetOffset(region.getOffset());
+            internalSetLength(region.getLength());
+        } else {
+            internalSetOffset(parentOffset);
+            internalSetLength(0);
+        }
+        fDefined= true;
+    }
+
+    /*
+     * @see dwtx.text.edits.TextEdit#internalToString(java.lang.StringBuffer, int)
+     * @since 3.3
+     */
+    void internalToString(StringBuffer buffer, int indent) {
+        super.internalToString(buffer, indent);
+        if (! fDefined)
+            buffer.append(" [undefined]"); //$NON-NLS-1$
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/RangeMarker.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,99 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.RangeMarker;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+
+/**
+ * A range marker can be used to track positions when executing
+ * text edits.
+ *
+ * @since 3.0
+ */
+public final class RangeMarker : TextEdit {
+
+    /**
+     * Creates a new range marker for the given offset and length.
+     *
+     * @param offset the marker's offset
+     * @param length the marker's length
+     */
+    public this(int offset, int length) {
+        super(offset, length);
+    }
+
+    /*
+     * Copy constructor
+     */
+    private this(RangeMarker other) {
+        super(other);
+    }
+
+    /*
+     * @see TextEdit#copy
+     */
+    protected TextEdit doCopy() {
+        return new RangeMarker(this);
+    }
+
+    /*
+     * @see TextEdit#accept0
+     */
+    protected void accept0(TextEditVisitor visitor) {
+        bool visitChildren= visitor.visit(this);
+        if (visitChildren) {
+            acceptChildren(visitor);
+        }
+    }
+
+    /*
+     * @see TextEdit#performDocumentUpdating
+     */
+    int performDocumentUpdating(IDocument document)  {
+        fDelta= 0;
+        return fDelta;
+    }
+
+    /*
+     * @see TextEdit#deleteChildren
+     */
+    bool deleteChildren() {
+        return false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/ReplaceEdit.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.ReplaceEdit;
+
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+
+/**
+ * Text edit to replace a range in a document with a different
+ * string.
+ *
+ * @since 3.0
+ */
+public final class ReplaceEdit : TextEdit {
+
+    private String fText;
+
+    /**
+     * Constructs a new replace edit.
+     *
+     * @param offset the offset of the range to replace
+     * @param length the length of the range to replace
+     * @param text the new text
+     */
+    public this(int offset, int length, String text) {
+        super(offset, length);
+        Assert.isNotNull(text);
+        fText= text;
+    }
+
+    /*
+     * Copy constructor
+     *
+     * @param other the edit to copy from
+     */
+    private this(ReplaceEdit other) {
+        super(other);
+        fText= other.fText;
+    }
+
+    /**
+     * Returns the new text replacing the text denoted
+     * by the edit.
+     *
+     * @return the edit's text.
+     */
+    public String getText() {
+        return fText;
+    }
+
+    /*
+     * @see TextEdit#doCopy
+     */
+    protected TextEdit doCopy() {
+        return new ReplaceEdit(this);
+    }
+
+    /*
+     * @see TextEdit#accept0
+     */
+    protected void accept0(TextEditVisitor visitor) {
+        bool visitChildren= visitor.visit(this);
+        if (visitChildren) {
+            acceptChildren(visitor);
+        }
+    }
+
+    /*
+     * @see TextEdit#performDocumentUpdating
+     */
+    int performDocumentUpdating(IDocument document)  {
+        document.replace(getOffset(), getLength(), fText);
+        fDelta= fText.length() - getLength();
+        return fDelta;
+    }
+
+    /*
+     * @see TextEdit#deleteChildren
+     */
+    bool deleteChildren() {
+        return true;
+    }
+
+    /*
+     * @see dwtx.text.edits.TextEdit#internalToString(java.lang.StringBuffer, int)
+     * @since 3.3
+     */
+    void internalToString(StringBuffer buffer, int indent) {
+        super.internalToString(buffer, indent);
+        buffer.append(" <<").append(fText); //$NON-NLS-1$
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/TextEdit.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,991 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.TextEdit;
+
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+
+import dwt.dwthelper.utils;
+import dwtx.dwtxhelper.Collection;
+import tango.text.convert.Format;
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IRegion;
+import dwtx.jface.text.Region;
+
+
+/**
+ * A text edit describes an elementary text manipulation operation. Edits are
+ * executed by applying them to a document (e.g. an instance of <code>IDocument
+ * </code>).
+ * <p>
+ * Text edits form a tree. Clients can navigate the tree upwards, from child to
+ * parent, as well as downwards. Newly created edits are un-parented. New edits
+ * are added to the tree by calling one of the <code>add</code> methods on a parent
+ * edit.
+ * </p>
+ * <p>
+ * An edit tree is well formed in the following sense:
+ * <ul>
+ *   <li>a parent edit covers all its children</li>
+ *   <li>children don't overlap</li>
+ *   <li>an edit with length 0 can't have any children</li>
+ * </ul>
+ * Any manipulation of the tree that violates one of the above requirements results
+ * in a <code>MalformedTreeException</code>.
+ * </p>
+ * <p>
+ * Insert edits are represented by an edit of length 0. If more than one insert
+ * edit exists at the same offset then the edits are executed in the order in which
+ * they have been added to a parent. The following code example:
+ * <pre>
+ *    IDocument document= new Document("org");
+ *    MultiTextEdit edit= new MultiTextEdit();
+ *    edit.addChild(new InsertEdit(0, "www."));
+ *    edit.addChild(new InsertEdit(0, "eclipse."));
+ *    edit.apply(document);
+ * </pre>
+ * therefore results in string: "www.eclipse.org".
+ * </p>
+ * <p>
+ * Text edits can be executed in a mode where the edit's region is updated to
+ * reflect the edit's position in the changed document. Region updating is enabled
+ * by default or can be requested by passing <code>UPDATE_REGIONS</code> to the
+ * {@link #apply(IDocument, int) apply(IDocument, int)} method. In the above example
+ * the region of the <code>InsertEdit(0, "eclipse.")</code> edit after executing
+ * the root edit is <code>[3, 8]</code>. If the region of an edit got deleted during
+ * change execution the region is set to <code>[-1, -1]</code> and the method {@link
+ * #isDeleted() isDeleted} returns <code>true</code>.
+ * </p>
+ * This class isn't intended to be subclassed outside of the edit framework. Clients
+ * are only allowed to subclass <code>MultiTextEdit</code>.
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public abstract class TextEdit {
+
+    /**
+     * Flags indicating that neither <code>CREATE_UNDO</code> nor
+     * <code>UPDATE_REGIONS</code> is set.
+     */
+    public static const int NONE= 0;
+
+    /**
+     * Flags indicating that applying an edit tree to a document
+     * is supposed to create a corresponding undo edit. If not
+     * specified <code>null</code> is returned from method <code>
+     * apply</code>.
+     */
+    public static const int CREATE_UNDO= 1 << 0;
+
+    /**
+     * Flag indicating that the edit's region will be updated to
+     * reflect its position in the changed document. If not specified
+     * when applying an edit tree to a document the edit's region will
+     * be arbitrary. It is even not guaranteed that the tree is still
+     * well formed.
+     */
+    public static const int UPDATE_REGIONS= 1 << 1;
+
+    private static class InsertionComparator : Comparator {
+        public int compare(Object o1, Object o2)  {
+            TextEdit edit1= cast(TextEdit)o1;
+            TextEdit edit2= cast(TextEdit)o2;
+
+            int offset1= edit1.getOffset();
+            int length1= edit1.getLength();
+
+            int offset2= edit2.getOffset();
+            int length2= edit2.getLength();
+
+            if (offset1 is offset2 && length1 is 0 && length2 is 0) {
+                return 0;
+            }
+            if (offset1 + length1 <= offset2) {
+                return -1;
+            }
+            if (offset2 + length2 <= offset1) {
+                return 1;
+            }
+            throw new MalformedTreeException(
+                    null, edit1,
+                    TextEditMessages.getString("TextEdit.overlapping")); //$NON-NLS-1$
+        }
+    }
+
+    private static const TextEdit[] EMPTY_ARRAY;
+    private static /+const+/ InsertionComparator INSERTION_COMPARATOR;
+
+    private static const int DELETED_VALUE= -1;
+
+    private int fOffset;
+    private int fLength;
+
+    private TextEdit fParent;
+    private List fChildren;
+
+    int fDelta;
+
+    /**
+     * Create a new text edit. Parent is initialized to <code>
+     * null<code> and the edit doesn't have any children.
+     *
+     * @param offset the edit's offset
+     * @param length the edit's length
+     */
+    protected this(int offset, int length) {
+        if( INSERTION_COMPARATOR is null ) INSERTION_COMPARATOR= new InsertionComparator();
+        Assert.isTrue(offset >= 0 && length >= 0);
+        fOffset= offset;
+        fLength= length;
+        fDelta= 0;
+    }
+
+    /**
+     * Copy constructor
+     *
+     * @param source the source to copy form
+     */
+    protected this(TextEdit source) {
+        if( INSERTION_COMPARATOR is null ) INSERTION_COMPARATOR= new InsertionComparator();
+        fOffset= source.fOffset;
+        fLength= source.fLength;
+        fDelta= 0;
+    }
+
+    //---- Region management -----------------------------------------------
+
+    /**
+     * Returns the range that this edit is manipulating. The returned
+     * <code>IRegion</code> contains the edit's offset and length at
+     * the point in time when this call is made. Any subsequent changes
+     * to the edit's offset and length aren't reflected in the returned
+     * region object.
+     * <p>
+     * Creating a region for a deleted edit will result in an assertion
+     * failure.
+     *
+     * @return the manipulated region
+     */
+    public final IRegion getRegion() {
+        return new Region(getOffset(), getLength());
+    }
+
+    /**
+     * Returns the offset of the edit. An offset is a 0-based
+     * character index. Returns <code>-1</code> if the edit
+     * is marked as deleted.
+     *
+     * @return the offset of the edit
+     */
+    public int getOffset() {
+        return fOffset;
+    }
+
+    /**
+     * Returns the length of the edit. Returns <code>-1</code>
+     * if the edit is marked as deleted.
+     *
+     * @return the length of the edit
+     */
+    public int getLength() {
+        return fLength;
+    }
+
+    /**
+     * Returns the inclusive end position of this edit. The inclusive end
+     * position denotes the last character of the region manipulated by
+     * this edit. The returned value is the result of the following
+     * calculation:
+     * <pre>
+     *   getOffset() + getLength() - 1;
+     * <pre>
+     *
+     * @return the inclusive end position
+     */
+    public final int getInclusiveEnd() {
+        return getOffset() + getLength() - 1;
+    }
+
+    /**
+     * Returns the exclusive end position of this edit. The exclusive end
+     * position denotes the next character of the region manipulated by
+     * this edit. The returned value is the result of the following
+     * calculation:
+     * <pre>
+     *   getOffset() + getLength();
+     * </pre>
+     *
+     * @return the exclusive end position
+     */
+    public final int getExclusiveEnd() {
+        return getOffset() + getLength();
+    }
+
+    /**
+     * Returns whether this edit has been deleted or not.
+     *
+     * @return <code>true</code> if the edit has been
+     *  deleted; otherwise <code>false</code> is returned.
+     */
+    public final bool isDeleted() {
+        return fOffset is DELETED_VALUE && fLength is DELETED_VALUE;
+    }
+
+    /**
+     * Move all offsets in the tree by the given delta. This node must be a
+     * root node. The resulting offsets must be greater or equal to zero.
+     *
+     * @param delta the delta
+     * @since 3.1
+     */
+    public final void moveTree(int delta) {
+        Assert.isTrue(fParent is null);
+        Assert.isTrue(getOffset() + delta >= 0);
+        internalMoveTree(delta);
+    }
+
+    /**
+     * Returns <code>true</code> if the edit covers the given edit
+     * <code>other</code>. It is up to the concrete text edit to
+     * decide if a edit of length zero can cover another edit.
+     *
+     * @param other the other edit
+     * @return <code>true<code> if the edit covers the other edit;
+     *  otherwise <code>false</code> is returned.
+     */
+    public bool covers(TextEdit other) {
+        if (getLength() is 0 && !canZeroLengthCover())
+            return false;
+
+        if (!other.isDefined())
+            return true;
+
+        int thisOffset= getOffset();
+        int otherOffset= other.getOffset();
+        return thisOffset <= otherOffset && otherOffset + other.getLength() <= thisOffset + getLength();
+    }
+
+    /**
+     * Returns <code>true</code> if an edit with length zero can cover
+     * another edit. Returns <code>false</code> otherwise.
+     *
+     * @return whether an edit of length zero can cover another edit
+     */
+    protected bool canZeroLengthCover() {
+        return false;
+    }
+
+    /**
+     * Returns whether the region of this edit is defined or not.
+     *
+     * @return whether the region of this edit is defined or not
+     *
+     * @since 3.1
+     */
+    bool isDefined() {
+        return true;
+    }
+
+    //---- parent and children management -----------------------------
+
+    /**
+     * Returns the edit's parent. The method returns <code>null</code>
+     * if this edit hasn't been add to another edit.
+     *
+     * @return the edit's parent
+     */
+    public final TextEdit getParent() {
+        return fParent;
+    }
+
+    /**
+     * Returns the root edit of the edit tree.
+     *
+     * @return the root edit of the edit tree
+     * @since 3.1
+     */
+    public final TextEdit getRoot() {
+        TextEdit result= this;
+        while (result.fParent !is null) {
+            result= result.fParent;
+        }
+        return result;
+    }
+
+    /**
+     * Adds the given edit <code>child</code> to this edit.
+     *
+     * @param child the child edit to add
+     * @exception MalformedTreeException is thrown if the child
+     *  edit can't be added to this edit. This is the case if the child
+     *  overlaps with one of its siblings or if the child edit's region
+     *  isn't fully covered by this edit.
+     */
+    public final void addChild(TextEdit child)  {
+        internalAdd(child);
+    }
+
+    /**
+     * Adds all edits in <code>edits</code> to this edit.
+     *
+     * @param edits the text edits to add
+     * @exception MalformedTreeException is thrown if one of
+     *  the given edits can't be added to this edit.
+     *
+     * @see #addChild(TextEdit)
+     */
+    public final void addChildren(TextEdit[] edits)  {
+        for (int i= 0; i < edits.length; i++) {
+            internalAdd(edits[i]);
+        }
+    }
+
+    /**
+     * Removes the edit specified by the given index from the list
+     * of children. Returns the child edit that was removed from
+     * the list of children. The parent of the returned edit is
+     * set to <code>null</code>.
+     *
+     * @param index the index of the edit to remove
+     * @return the removed edit
+     * @exception IndexOutOfBoundsException if the index
+     *  is out of range
+     */
+    public final TextEdit removeChild(int index) {
+        if (fChildren is null)
+            throw new IndexOutOfBoundsException(Format("Index: {} Size: 0", index ));  //$NON-NLS-1$//$NON-NLS-2$
+        TextEdit result= cast(TextEdit)fChildren.remove(index);
+        result.internalSetParent(null);
+        if (fChildren.isEmpty())
+            fChildren= null;
+        return result;
+    }
+
+    /**
+     * Removes the first occurrence of the given child from the list
+     * of children.
+     *
+     * @param child the child to be removed
+     * @return <code>true</code> if the edit contained the given
+     *  child; otherwise <code>false</code> is returned
+     */
+    public final bool removeChild(TextEdit child) {
+        Assert.isNotNull(child);
+        if (fChildren is null)
+            return false;
+        bool result= fChildren.remove(child);
+        if (result) {
+            child.internalSetParent(null);
+            if (fChildren.isEmpty())
+                fChildren= null;
+        }
+        return result;
+    }
+
+    /**
+     * Removes all child edits from and returns them. The parent
+     * of the removed edits is set to <code>null</code>.
+     *
+     * @return an array of the removed edits
+     */
+    public final TextEdit[] removeChildren() {
+        if (fChildren is null)
+            return EMPTY_ARRAY;
+        int size= fChildren.size();
+        TextEdit[] result= new TextEdit[size];
+        for (int i= 0; i < size; i++) {
+            result[i]= cast(TextEdit)fChildren.get(i);
+            result[i].internalSetParent(null);
+        }
+        fChildren= null;
+        return result;
+    }
+
+    /**
+     * Returns <code>true</code> if this edit has children. Otherwise
+     * <code>false</code> is returned.
+     *
+     * @return <code>true</code> if this edit has children; otherwise
+     *  <code>false</code> is returned
+     */
+    public final bool hasChildren() {
+        return fChildren !is null && ! fChildren.isEmpty();
+    }
+
+    /**
+     * Returns the edit's children. If the edit doesn't have any
+     * children an empty array is returned.
+     *
+     * @return the edit's children
+     */
+    public final TextEdit[] getChildren() {
+        if (fChildren is null)
+            return EMPTY_ARRAY;
+        return arraycast!(TextEdit)(fChildren.toArray());
+    }
+
+    /**
+     * Returns the size of the managed children.
+     *
+     * @return the size of the children
+     */
+    public final int getChildrenSize() {
+        if (fChildren is null)
+            return 0;
+        return fChildren.size();
+    }
+
+    /**
+     * Returns the text range spawned by the given array of text edits.
+     * The method requires that the given array contains at least one
+     * edit. If all edits passed are deleted the method returns <code>
+     * null</code>.
+     *
+     * @param edits an array of edits
+     * @return the text range spawned by the given array of edits or
+     *  <code>null</code> if all edits are marked as deleted
+     */
+    public static IRegion getCoverage(TextEdit[] edits) {
+        Assert.isTrue(edits !is null && edits.length > 0);
+
+        int offset= Integer.MAX_VALUE;
+        int end= Integer.MIN_VALUE;
+        int deleted= 0;
+        for (int i= 0; i < edits.length; i++) {
+            TextEdit edit= edits[i];
+            if (edit.isDeleted()) {
+                deleted++;
+            } else {
+                offset= Math.min(offset, edit.getOffset());
+                end= Math.max(end, edit.getExclusiveEnd());
+            }
+        }
+        if (edits.length is deleted)
+            return null;
+
+        return new Region(offset, end - offset);
+    }
+
+    /*
+     * Hook called before this edit gets added to the passed
+     * parent.
+     */
+    void aboutToBeAdded(TextEdit parent) {
+    }
+
+    //---- Object methods ------------------------------------------------------
+
+    /**
+     * The <code>Edit</code> implementation of this <code>Object</code>
+     * method uses object identity (is).
+     *
+     * @param obj the other object
+     * @return <code>true</code> iff <code>this is obj</code>; otherwise
+     *  <code>false</code> is returned
+     *
+     * @see Object#equals(java.lang.Object)
+     */
+    public final bool equals(Object obj) {
+        return this is obj; // equivalent to Object.equals
+    }
+
+    /**
+     * The <code>Edit</code> implementation of this <code>Object</code>
+     * method calls uses <code>Object#hashCode()</code> to compute its
+     * hash code.
+     *
+     * @return the object's hash code value
+     *
+     * @see Object#hashCode()
+     */
+    public final override hash_t toHash() {
+        return super.toHash();
+    }
+
+    /*
+     * @see java.lang.Object#toString()
+     */
+    public override String toString() {
+        StringBuffer buffer= new StringBuffer();
+        toStringWithChildren(buffer, 0);
+        return buffer.toString();
+    }
+
+    /**
+     * Adds the string representation of this text edit without
+     * children information to the given string buffer.
+     *
+     * @param buffer    the string buffer
+     * @param indent    the indent level in number of spaces
+     * @since 3.3
+     */
+    void internalToString(StringBuffer buffer, int indent) {
+        for (int i= indent; i > 0; i--) {
+            buffer.append("  "); //$NON-NLS-1$
+        }
+        buffer.append("{"); //$NON-NLS-1$
+        String name= this.classinfo.name;
+        int index= name.lastIndexOf('.');
+        if (index !is -1) {
+            buffer.append(name.substring(index + 1));
+        } else {
+            buffer.append(name);
+        }
+        buffer.append("} "); //$NON-NLS-1$
+        if (isDeleted()) {
+            buffer.append("[deleted]"); //$NON-NLS-1$
+        } else {
+            buffer.append("["); //$NON-NLS-1$
+            buffer.append(getOffset());
+            buffer.append(","); //$NON-NLS-1$
+            buffer.append(getLength());
+            buffer.append("]"); //$NON-NLS-1$
+        }
+    }
+
+    /**
+     * Adds the string representation for this text edit
+     * and its children to the given string buffer.
+     *
+     * @param buffer    the string buffer
+     * @param indent    the indent level in number of spaces
+     * @since 3.3
+     */
+    private void toStringWithChildren(StringBuffer buffer, int indent) {
+        internalToString(buffer, indent);
+        if (fChildren !is null) {
+            for (Iterator iterator= fChildren.iterator(); iterator.hasNext();) {
+                TextEdit child= cast(TextEdit) iterator.next();
+                buffer.append('\n');
+                child.toStringWithChildren(buffer, indent + 1);
+            }
+        }
+    }
+
+    //---- Copying -------------------------------------------------------------
+
+    /**
+     * Creates a deep copy of the edit tree rooted at this
+     * edit.
+     *
+     * @return a deep copy of the edit tree
+     * @see #doCopy()
+     */
+    public final TextEdit copy() {
+        TextEditCopier copier= new TextEditCopier(this);
+        return copier.perform();
+    }
+
+    /**
+     * Creates and returns a copy of this edit. The copy method should be
+     * implemented in a way so that the copy can executed without causing
+     * any harm to the original edit. Implementors of this method are
+     * responsible for creating deep or shallow copies of referenced
+     * object to fulfill this requirement.
+     * <p>
+     * Implementers of this method should use the copy constructor <code>
+     * Edit#Edit(Edit source) to initialize the edit part of the copy.
+     * Implementors aren't responsible to actually copy the children or
+     * to set the right parent.
+     * <p>
+     * This method <b>should not be called</b> from outside the framework.
+     * Please use <code>copy</code> to create a copy of a edit tree.
+     *
+     * @return a copy of this edit.
+     * @see #copy()
+     * @see #postProcessCopy(TextEditCopier)
+     * @see TextEditCopier
+     */
+    protected abstract TextEdit doCopy();
+    package TextEdit doCopy_package(){
+        return doCopy();
+    }
+
+    /**
+     * This method is called on every edit of the copied tree to do some
+     * post-processing like connected an edit to a different edit in the tree.
+     * <p>
+     * This default implementation does nothing
+     *
+     * @param copier the copier that manages a map between original and
+     *  copied edit.
+     * @see TextEditCopier
+     */
+    protected void postProcessCopy(TextEditCopier copier) {
+    }
+    package void postProcessCopy_package(TextEditCopier copier) {
+        postProcessCopy(copier);
+    }
+
+    //---- Visitor support -------------------------------------------------
+
+    /**
+     * Accepts the given visitor on a visit of the current edit.
+     *
+     * @param visitor the visitor object
+     * @exception IllegalArgumentException if the visitor is null
+     */
+    public final void accept(TextEditVisitor visitor) {
+        Assert.isNotNull(visitor);
+        // begin with the generic pre-visit
+        visitor.preVisit(this);
+        // dynamic dispatch to internal method for type-specific visit/endVisit
+        accept0(visitor);
+        // end with the generic post-visit
+        visitor.postVisit(this);
+    }
+
+    /**
+     * Accepts the given visitor on a type-specific visit of the current edit.
+     * This method must be implemented in all concrete text edits.
+     * <p>
+     * General template for implementation on each concrete TextEdit class:
+     * <pre>
+     * <code>
+     * bool visitChildren= visitor.visit(this);
+     * if (visitChildren) {
+     *    acceptChildren(visitor);
+     * }
+     * </code>
+     * </pre>
+     * Note that the caller (<code>accept</code>) takes care of invoking
+     * <code>visitor.preVisit(this)</code> and <code>visitor.postVisit(this)</code>.
+     * </p>
+     *
+     * @param visitor the visitor object
+     */
+    protected abstract void accept0(TextEditVisitor visitor);
+
+
+    /**
+     * Accepts the given visitor on the edits children.
+     * <p>
+     * This method must be used by the concrete implementations of
+     * <code>accept</code> to traverse list-values properties; it
+     * encapsulates the proper handling of on-the-fly changes to the list.
+     * </p>
+     *
+     * @param visitor the visitor object
+     */
+    protected final void acceptChildren(TextEditVisitor visitor) {
+        if (fChildren is null)
+            return;
+        Iterator iterator= fChildren.iterator();
+        while (iterator.hasNext()) {
+            TextEdit curr= cast(TextEdit) iterator.next();
+            curr.accept(visitor);
+        }
+    }
+
+    //---- Execution -------------------------------------------------------
+
+    /**
+     * Applies the edit tree rooted by this edit to the given document. To check
+     * if the edit tree can be applied to the document either catch <code>
+     * MalformedTreeException</code> or use <code>TextEditProcessor</code> to
+     * execute an edit tree.
+     *
+     * @param document the document to be manipulated
+     * @param style flags controlling the execution of the edit tree. Valid
+     *  flags are: <code>CREATE_UNDO</code> and </code>UPDATE_REGIONS</code>.
+     * @return a undo edit, if <code>CREATE_UNDO</code> is specified. Otherwise
+     *  <code>null</code> is returned.
+     *
+     * @exception MalformedTreeException is thrown if the tree isn't
+     *  in a valid state. This exception is thrown before any edit
+     *  is executed. So the document is still in its original state.
+     * @exception BadLocationException is thrown if one of the edits
+     *  in the tree can't be executed. The state of the document is
+     *  undefined if this exception is thrown.
+     *
+     * @see TextEditProcessor#performEdits()
+     */
+    public final UndoEdit apply(IDocument document, int style)  {
+        try {
+            TextEditProcessor processor= new TextEditProcessor(document, this, style);
+            return processor.performEdits();
+        } finally {
+            // disconnect from text edit processor
+            fParent= null;
+        }
+    }
+
+    /**
+     * Applies the edit tree rooted by this edit to the given document. This
+     * method is a convenience method for <code>apply(document, CREATE_UNDO | UPDATE_REGIONS)
+     * </code>
+     *
+     * @param document the document to which to apply this edit
+     * @return a undo edit, if <code>CREATE_UNDO</code> is specified. Otherwise
+     *  <code>null</code> is returned.
+     * @exception MalformedTreeException is thrown if the tree isn't
+     *  in a valid state. This exception is thrown before any edit
+     *  is executed. So the document is still in its original state.
+     * @exception BadLocationException is thrown if one of the edits
+     *  in the tree can't be executed. The state of the document is
+     *  undefined if this exception is thrown.
+     * @see #apply(IDocument, int)
+     */
+    public final UndoEdit apply(IDocument document)  {
+        return apply(document, CREATE_UNDO | UPDATE_REGIONS);
+    }
+
+    UndoEdit dispatchPerformEdits(TextEditProcessor processor)  {
+        return processor.executeDo();
+    }
+
+    void dispatchCheckIntegrity(TextEditProcessor processor)  {
+        processor.checkIntegrityDo();
+    }
+
+    //---- internal state accessors ----------------------------------------------------------
+
+    void internalSetParent(TextEdit parent) {
+        if (parent !is null)
+            Assert.isTrue(fParent is null);
+        fParent= parent;
+    }
+
+    void internalSetOffset(int offset) {
+        Assert.isTrue(offset >= 0);
+        fOffset= offset;
+    }
+
+    void internalSetLength(int length) {
+        Assert.isTrue(length >= 0);
+        fLength= length;
+    }
+
+    List internalGetChildren() {
+        return fChildren;
+    }
+
+    void internalSetChildren(List children) {
+        fChildren= children;
+    }
+
+    void internalAdd(TextEdit child)  {
+        child.aboutToBeAdded(this);
+        if (child.isDeleted())
+            throw new MalformedTreeException(this, child, TextEditMessages.getString("TextEdit.deleted_edit")); //$NON-NLS-1$
+        if (!covers(child))
+            throw new MalformedTreeException(this, child, TextEditMessages.getString("TextEdit.range_outside")); //$NON-NLS-1$
+        if (fChildren is null) {
+            fChildren= new ArrayList(2);
+        }
+        int index= computeInsertionIndex(child);
+        fChildren.add(index, child);
+        child.internalSetParent(this);
+    }
+
+    private int computeInsertionIndex(TextEdit edit)  {
+        int size= fChildren.size();
+        if (size is 0)
+            return 0;
+        int lastIndex= size - 1;
+        TextEdit last= cast(TextEdit)fChildren.get(lastIndex);
+        if (last.getExclusiveEnd() <= edit.getOffset())
+            return size;
+        try {
+
+            int index= Collections.binarySearch(fChildren, edit, INSERTION_COMPARATOR);
+
+            if (index < 0)
+                // edit is not in fChildren
+                return -index - 1;
+
+            // edit is already in fChildren
+            // make sure that multiple insertion points at the same offset are inserted last.
+            while (index < lastIndex && INSERTION_COMPARATOR.compare(fChildren.get(index), fChildren.get(index + 1)) is 0)
+                index++;
+
+            return index + 1;
+
+        } catch(MalformedTreeException e) {
+            e.setParent(this);
+            throw e;
+        }
+    }
+
+    //---- Offset & Length updating -------------------------------------------------
+
+    /**
+     * Adjusts the edits offset according to the given
+     * delta. This method doesn't update any children.
+     *
+     * @param delta the delta of the text replace operation
+     */
+    void adjustOffset(int delta) {
+        if (isDeleted())
+            return;
+        fOffset+= delta;
+        Assert.isTrue(fOffset >= 0);
+    }
+
+    /**
+     * Adjusts the edits length according to the given
+     * delta. This method doesn't update any children.
+     *
+     * @param delta the delta of the text replace operation
+     */
+    void adjustLength(int delta) {
+        if (isDeleted())
+            return;
+        fLength+= delta;
+        Assert.isTrue(fLength >= 0);
+    }
+
+    /**
+     * Marks the edit as deleted. This method doesn't update
+     * any children.
+     */
+    void markAsDeleted() {
+        fOffset= DELETED_VALUE;
+        fLength= DELETED_VALUE;
+    }
+
+    //---- Edit processing ----------------------------------------------
+
+    /**
+     * Traverses the edit tree to perform the consistency check.
+     *
+     * @param processor the text edit processor
+     * @param document the document to be manipulated
+     * @param sourceEdits the list of source edits to be performed before
+     *  the actual tree is applied to the document
+     *
+     * @return the number of indirect move or copy target edit children
+     */
+    int traverseConsistencyCheck(TextEditProcessor processor, IDocument document, List sourceEdits) {
+        int result= 0;
+        if (fChildren !is null) {
+            for (int i= fChildren.size() - 1; i >= 0; i--) {
+                TextEdit child= cast(TextEdit)fChildren.get(i);
+                result= Math.max(result, child.traverseConsistencyCheck(processor, document, sourceEdits));
+            }
+        }
+        if (processor.considerEdit_package(this)) {
+            performConsistencyCheck(processor, document);
+        }
+        return result;
+    }
+
+    void performConsistencyCheck(TextEditProcessor processor, IDocument document) {
+    }
+
+    void traverseSourceComputation(TextEditProcessor processor, IDocument document) {
+    }
+
+    void performSourceComputation(TextEditProcessor processor, IDocument document) {
+    }
+
+    int traverseDocumentUpdating(TextEditProcessor processor, IDocument document)  {
+        int delta= 0;
+        if (fChildren !is null) {
+            for (int i= fChildren.size() - 1; i >= 0; i--) {
+                TextEdit child= cast(TextEdit)fChildren.get(i);
+                delta+= child.traverseDocumentUpdating(processor, document);
+                childDocumentUpdated();
+            }
+        }
+        if (processor.considerEdit_package(this)) {
+            if (delta !is 0)
+                adjustLength(delta);
+            int r= performDocumentUpdating(document);
+            if (r !is 0)
+                adjustLength(r);
+            delta+= r;
+        }
+        return delta;
+    }
+
+    /**
+     * Hook method called when the document updating of a child edit has been
+     * completed. When a client calls {@link #apply(IDocument)} or
+     * {@link #apply(IDocument, int)} this method is called
+     * {@link #getChildrenSize()} times.
+     * <p>
+     * May be overridden by subclasses of {@link MultiTextEdit}.
+     *
+     * @since 3.1
+     */
+    protected void childDocumentUpdated() {
+    }
+
+    abstract int performDocumentUpdating(IDocument document) ;
+
+    int traverseRegionUpdating(TextEditProcessor processor, IDocument document, int accumulatedDelta, bool delete_) {
+        performRegionUpdating(accumulatedDelta, delete_);
+        if (fChildren !is null) {
+            bool childDelete= delete_ || deleteChildren();
+            for (Iterator iter= fChildren.iterator(); iter.hasNext();) {
+                TextEdit child= cast(TextEdit)iter.next();
+                accumulatedDelta= child.traverseRegionUpdating(processor, document, accumulatedDelta, childDelete);
+                childRegionUpdated();
+            }
+        }
+        return accumulatedDelta + fDelta;
+    }
+
+    /**
+     * Hook method called when the region updating of a child edit has been
+     * completed. When a client calls {@link #apply(IDocument)} this method is
+     * called {@link #getChildrenSize()} times. When calling
+     * {@link #apply(IDocument, int)} this method is called
+     * {@link #getChildrenSize()} times, when the style parameter contains the
+     * {@link #UPDATE_REGIONS} flag.
+     * <p>
+     * May be overridden by subclasses of {@link MultiTextEdit}.
+     *
+     * @since 3.1
+     */
+    protected void childRegionUpdated() {
+    }
+
+    void performRegionUpdating(int accumulatedDelta, bool delete_) {
+        if (delete_)
+            markAsDeleted();
+        else
+            adjustOffset(accumulatedDelta);
+    }
+
+    abstract bool deleteChildren();
+
+    void internalMoveTree(int delta) {
+        adjustOffset(delta);
+        if (fChildren !is null) {
+            for (Iterator iter= fChildren.iterator(); iter.hasNext();) {
+                (cast(TextEdit)iter.next()).internalMoveTree(delta);
+            }
+        }
+    }
+
+    void deleteTree() {
+        markAsDeleted();
+        if (fChildren !is null) {
+            for (Iterator iter= fChildren.iterator(); iter.hasNext();) {
+                TextEdit child= cast(TextEdit)iter.next();
+                child.deleteTree();
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/TextEditCopier.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,127 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.TextEditCopier;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+
+
+import dwtx.core.runtime.Assert;
+
+
+/**
+ * Copies a tree of text edits. A text edit copier keeps a map
+ * between original and new text edits. It can be used to map
+ * a copy back to its original edit.
+ *
+ * @since 3.0
+ */
+public final class TextEditCopier {
+
+    private TextEdit fEdit;
+    private Map fCopies;
+
+    /**
+     * Constructs a new <code>TextEditCopier</code> for the
+     * given edit. The actual copy is done by calling <code>
+     * perform</code>.
+     *
+     * @param edit the edit to copy
+     *
+     * @see #perform()
+     */
+    public this(TextEdit edit) {
+//         super();
+        Assert.isNotNull(edit);
+        fEdit= edit;
+        fCopies= new HashMap();
+    }
+
+    /**
+     * Performs the actual copying.
+     *
+     * @return the copy
+     */
+    public TextEdit perform() {
+        TextEdit result= doCopy(fEdit);
+        if (result !is null) {
+            for (Iterator iter= fCopies.keySet().iterator(); iter.hasNext();) {
+                TextEdit edit= cast(TextEdit)iter.next();
+                edit.postProcessCopy_package(this);
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Returns the copy for the original text edit.
+     *
+     * @param original the original for which the copy
+     *  is requested
+     * @return the copy of the original edit or <code>null</code>
+     *  if the original isn't managed by this copier
+     */
+    public TextEdit getCopy(TextEdit original) {
+        Assert.isNotNull(original);
+        return cast(TextEdit)fCopies.get(original);
+    }
+
+    //---- helper methods --------------------------------------------
+
+    private TextEdit doCopy(TextEdit edit) {
+        TextEdit result= edit.doCopy_package();
+        List children= edit.internalGetChildren();
+        if (children !is null) {
+            List newChildren= new ArrayList(children.size());
+            for (Iterator iter= children.iterator(); iter.hasNext();) {
+                TextEdit childCopy= doCopy(cast(TextEdit)iter.next());
+                childCopy.internalSetParent(result);
+                newChildren.add(childCopy);
+            }
+            result.internalSetChildren(newChildren);
+        }
+        addCopy(edit, result);
+        return result;
+    }
+
+    private void addCopy(TextEdit original, TextEdit copy) {
+        fCopies.put(original, copy);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/TextEditGroup.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.TextEditGroup;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.IRegion;
+
+
+/**
+ * A text edit group combines a list of {@link TextEdit}s
+ * and a name into a single object. The name must be a human
+ * readable string use to present the text edit group in the
+ * user interface.
+ * <p>
+ * Clients may extend this class to add extra information to
+ * a text edit group.
+ * </p>
+ *
+ * @since 3.0
+ */
+public class TextEditGroup {
+
+    private String fDescription;
+    private List fEdits;
+
+    /**
+     * Creates a new text edit group with the given name.
+     *
+     * @param name the name of the text edit group. Must be
+     *  a human readable string
+     */
+    public this(String name) {
+//         super();
+        Assert.isNotNull(name);
+        fDescription= name;
+        fEdits= new ArrayList(3);
+    }
+
+    /**
+     * Creates a new text edit group with a name and a single
+     * {@link TextEdit}.
+     *
+     * @param name the name of the text edit group. Must be
+     *  a human readable string
+     * @param edit the edit to manage
+     */
+    public this(String name, TextEdit edit) {
+        Assert.isNotNull(name);
+        Assert.isNotNull(edit);
+        fDescription= name;
+        fEdits= new ArrayList(1);
+        fEdits.add(edit);
+    }
+
+    /**
+     * Creates a new text edit group with the given name and
+     * array of edits.
+     *
+     * @param name the name of the text edit group. Must be
+     *  a human readable string
+     * @param edits the array of edits
+     */
+    public this(String name, TextEdit[] edits) {
+//         super();
+        Assert.isNotNull(name);
+        Assert.isTrue(edits !is null);
+        fDescription= name;
+        fEdits= new ArrayList(Arrays.asList(edits));
+    }
+
+    /**
+     * Returns the edit group's name.
+     *
+     * @return the edit group's name
+     */
+    public String getName() {
+        return fDescription;
+    }
+
+    /**
+     * Adds the given {@link TextEdit} to this group.
+     *
+     * @param edit the edit to add
+     */
+    public void addTextEdit(TextEdit edit) {
+        fEdits.add(edit);
+    }
+
+    /**
+     * Removes the given {@link TextEdit} from this group.
+     *
+     * @param edit the edit to remove
+     * @return <code>true</code> if this group contained the specified edit.
+     * @since 3.3
+     */
+    public bool removeTextEdit(TextEdit edit) {
+      return fEdits.remove(edit);
+    }
+
+    /**
+     * Removes all text edits from this group.
+     *
+     * @since 3.3
+     */
+    public void clearTextEdits() {
+      fEdits.clear();
+    }
+
+
+
+    /**
+     * Returns <code>true</code> if the list of managed
+     * {@link TextEdit}s is empty; otherwise <code>false
+     * </code> is returned.
+     *
+     * @return whether the list of managed text edits is
+     *  empty or not
+     */
+    public bool isEmpty() {
+        return fEdits.isEmpty();
+    }
+
+    /**
+     * Returns an array of {@link TextEdit}s containing
+     * the edits managed by this group.
+     *
+     * @return the managed text edits
+     */
+    public TextEdit[] getTextEdits() {
+        return arraycast!(TextEdit)( fEdits.toArray());
+    }
+
+    /**
+     * Returns the text region covered by the edits managed via this
+     * edit group. If the group doesn't manage any edits <code>null
+     * </code> is returned.
+     *
+     * @return the text region covered by this edit group or <code>
+     *  null</code> if no edits are managed
+     */
+    public IRegion getRegion() {
+        int size= fEdits.size();
+        if (size is 0) {
+            return null;
+        } else if (size is 1) {
+            return (cast(TextEdit)fEdits.get(0)).getRegion();
+        } else {
+            return TextEdit.getCoverage(arraycast!(TextEdit)(fEdits.toArray()));
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/TextEditMessages.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.TextEditMessages;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.dwthelper.ResourceBundle;
+import dwtx.dwtxhelper.MessageFormat;
+
+class TextEditMessages {
+
+//     private static const String BUNDLE_NAME= "dwtx.text.edits.Messages"; //$NON-NLS-1$
+
+    private static const ResourceBundle RESOURCE_BUNDLE;//= ResourceBundle.getBundle(BUNDLE_NAME);
+
+    static this() {
+        RESOURCE_BUNDLE = ResourceBundle.getBundle(
+            getImportData!("dwtx.text.edits.TextEditMessages.properties"));
+    }
+
+    private this() {
+    }
+
+    public static String getString(String key) {
+        try {
+            return RESOURCE_BUNDLE.getString(key);
+        } catch (MissingResourceException e) {
+            return '!' ~ key ~ '!';
+        }
+    }
+
+    public static String getFormattedString(String key, Object[] args...) {
+        return MessageFormat.format(getString(key), args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/TextEditProcessor.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,262 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.TextEditProcessor;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+
+
+/**
+ * A <code>TextEditProcessor</code> manages a set of edits and applies
+ * them as a whole to an <code>IDocument</code>.
+ * <p>
+ * This class isn't intended to be subclassed.</p>
+ *
+ * @see dwtx.text.edits.TextEdit#apply(IDocument)
+ *
+ * @since 3.0
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class TextEditProcessor {
+
+    private IDocument fDocument;
+    private TextEdit fRoot;
+    private int fStyle;
+
+    private bool fChecked;
+    private MalformedTreeException fException;
+
+    private List fSourceEdits;
+
+    /**
+     * Constructs a new edit processor for the given
+     * document.
+     *
+     * @param document the document to manipulate
+     * @param root the root of the text edit tree describing
+     *  the modifications. By passing a text edit a a text edit
+     *  processor the ownership of the edit is transfered to the
+     *  text edit processors. Clients must not modify the edit
+     *  (e.g adding new children) any longer.
+     *
+     * @param style {@link TextEdit#NONE}, {@link TextEdit#CREATE_UNDO} or {@link TextEdit#UPDATE_REGIONS})
+     */
+    public this(IDocument document, TextEdit root, int style) {
+        this(document, root, style, false);
+    }
+
+    private this(IDocument document, TextEdit root, int style, bool secondary) {
+        Assert.isNotNull(cast(Object)document);
+        Assert.isNotNull(root);
+        fDocument= document;
+        fRoot= root;
+        if ( auto mte = cast(MultiTextEdit)fRoot )
+            mte.defineRegion(0);
+        fStyle= style;
+        if (secondary) {
+            fChecked= true;
+            fSourceEdits= new ArrayList();
+        }
+    }
+
+    /**
+     * Creates a special internal processor used to during source computation inside
+     * move source and copy source edits
+     *
+     * @param document the document to be manipulated
+     * @param root the edit tree
+     * @param style {@link TextEdit#NONE}, {@link TextEdit#CREATE_UNDO} or {@link TextEdit#UPDATE_REGIONS})
+     * @return a secondary text edit processor
+     * @since 3.1
+     */
+    static TextEditProcessor createSourceComputationProcessor(IDocument document, TextEdit root, int style) {
+        return new TextEditProcessor(document, root, style, true);
+    }
+
+    /**
+     * Returns the document to be manipulated.
+     *
+     * @return the document
+     */
+    public IDocument getDocument() {
+        return fDocument;
+    }
+
+    /**
+     * Returns the edit processor's root edit.
+     *
+     * @return the processor's root edit
+     */
+    public TextEdit getRoot() {
+        return fRoot;
+    }
+
+    /**
+     * Returns the style bits of the text edit processor
+     *
+     * @return the style bits
+     * @see TextEdit#CREATE_UNDO
+     * @see TextEdit#UPDATE_REGIONS
+     */
+    public int getStyle() {
+        return fStyle;
+    }
+
+    /**
+     * Checks if the processor can execute all its edits.
+     *
+     * @return <code>true</code> if the edits can be executed. Return  <code>false
+     *  </code>otherwise. One major reason why edits cannot be executed are wrong
+     *  offset or length values of edits. Calling perform in this case will very
+     *  likely end in a <code>BadLocationException</code>.
+     */
+    public bool canPerformEdits() {
+        try {
+            fRoot.dispatchCheckIntegrity(this);
+            fChecked= true;
+        } catch (MalformedTreeException e) {
+            fException= e;
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Executes the text edits.
+     *
+     * @return an object representing the undo of the executed edits
+     * @exception MalformedTreeException is thrown if the edit tree isn't
+     *  in a valid state. This exception is thrown before any edit is executed.
+     *  So the document is still in its original state.
+     * @exception BadLocationException is thrown if one of the edits in the
+     *  tree can't be executed. The state of the document is undefined if this
+     *  exception is thrown.
+     */
+    public UndoEdit performEdits()  {
+        if (!fChecked) {
+            fRoot.dispatchCheckIntegrity(this);
+        } else {
+            if (fException !is null)
+                throw fException;
+        }
+        return fRoot.dispatchPerformEdits(this);
+    }
+
+    /*
+     * Class isn't intended to be sub-lcassed
+     */
+    protected bool considerEdit(TextEdit edit) {
+        return true;
+    }
+    package bool considerEdit_package(TextEdit edit) {
+        return considerEdit(edit);
+    }
+
+
+    //---- checking --------------------------------------------------------------------
+
+    void checkIntegrityDo()  {
+        fSourceEdits= new ArrayList();
+        fRoot.traverseConsistencyCheck(this, fDocument, fSourceEdits);
+        if (fRoot.getExclusiveEnd() > fDocument.getLength())
+            throw new MalformedTreeException(null, fRoot, TextEditMessages.getString("TextEditProcessor.invalid_length")); //$NON-NLS-1$
+    }
+
+    void checkIntegrityUndo() {
+        if (fRoot.getExclusiveEnd() > fDocument.getLength())
+            throw new MalformedTreeException(null, fRoot, TextEditMessages.getString("TextEditProcessor.invalid_length")); //$NON-NLS-1$
+    }
+
+    //---- execution --------------------------------------------------------------------
+
+    UndoEdit executeDo()  {
+        UndoCollector collector= new UndoCollector(fRoot);
+        try {
+            if (createUndo())
+                collector.connect(fDocument);
+            computeSources();
+            fRoot.traverseDocumentUpdating(this, fDocument);
+            if (updateRegions()) {
+                fRoot.traverseRegionUpdating(this, fDocument, 0, false);
+            }
+        } finally {
+            collector.disconnect(fDocument);
+        }
+        return collector.undo_package;
+    }
+
+    private void computeSources() {
+        for (Iterator iter= fSourceEdits.iterator(); iter.hasNext();) {
+            List list= cast(List)iter.next();
+            if (list !is null) {
+                for (Iterator edits= list.iterator(); edits.hasNext();) {
+                    TextEdit edit= cast(TextEdit)edits.next();
+                    edit.traverseSourceComputation(this, fDocument);
+                }
+            }
+        }
+    }
+
+    UndoEdit executeUndo()  {
+        UndoCollector collector= new UndoCollector(fRoot);
+        try {
+            if (createUndo())
+                collector.connect(fDocument);
+            TextEdit[] edits= fRoot.getChildren();
+            for (int i= edits.length - 1; i >= 0; i--) {
+                edits[i].performDocumentUpdating(fDocument);
+            }
+        } finally {
+            collector.disconnect(fDocument);
+        }
+        return collector.undo_package;
+    }
+
+    private bool createUndo() {
+        return (fStyle & TextEdit.CREATE_UNDO) !is 0;
+    }
+
+    private bool updateRegions() {
+        return (fStyle & TextEdit.UPDATE_REGIONS) !is 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/TextEditVisitor.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,252 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.TextEditVisitor;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+/**
+ * A visitor for text edits.
+ * <p>
+ * For each different concrete text edit type <it>T</it> there is a method:
+ * <ul>
+ *   <li><code>public bool visit(<it>T</it> node)</code> - Visits the given edit to
+ *   perform some arbitrary operation. If <code>true </code> is returned, the given edit's
+ *   child edits will be visited next; however, if <code>false</code> is returned, the
+ *   given edit's child edits will not be visited. The default implementation provided by
+ *   this class calls a generic method <code>visitNode(<it>TextEdit</it> node)</code>.
+ *   Subclasses may reimplement these method as needed.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * In addition, there are methods for visiting text edits in the
+ * abstract, regardless of node type:
+ * <ul>
+ *   <li><code>public void preVisit(TextEdit edit)</code> - Visits
+ *   the given edit to perform some arbitrary operation.
+ *   This method is invoked prior to the appropriate type-specific
+ *   <code>visit</code> method.
+ *   The default implementation of this method does nothing.
+ *   Subclasses may reimplement this method as needed.</li>
+ *
+ *   <li><code>public void postVisit(TextEdit edit)</code> - Visits
+ *   the given edit to perform some arbitrary operation.
+ *   This method is invoked after the appropriate type-specific
+ *   <code>endVisit</code> method.
+ *   The default implementation of this method does nothing.
+ *   Subclasses may reimplement this method as needed.</li>
+ * </ul>
+ * </p>
+ * <p>
+ * For edits with children, the child nodes are visited in increasing order.
+ * </p>
+ *
+ * @see TextEdit#accept(TextEditVisitor)
+ * @since 3.0
+ */
+public class TextEditVisitor {
+
+    /**
+     * Visits the given text edit prior to the type-specific visit.
+     * (before <code>visit</code>).
+     * <p>
+     * The default implementation does nothing. Subclasses may reimplement.
+     * </p>
+     *
+     * @param edit the node to visit
+     */
+    public void preVisit(TextEdit edit) {
+        // default implementation: do nothing
+    }
+
+    /**
+     * Visits the given text edit following the type-specific visit
+     * (after <code>endVisit</code>).
+     * <p>
+     * The default implementation does nothing. Subclasses may reimplement.
+     * </p>
+     *
+     * @param edit the node to visit
+     */
+    public void postVisit(TextEdit edit) {
+        // default implementation: do nothing
+    }
+
+    /**
+     * Visits the given text edit. This method is called by default from
+     * type-specific visits. It is not called by an edit's accept method.
+     * The default implementation returns <code>true</code>.
+     *
+     * @param edit the node to visit
+     * @return If <code>true</code> is returned, the given node's child
+     *  nodes will be visited next; however, if <code>false</code> is
+     *  returned, the given node's child nodes will not be visited.
+     */
+    public bool visitNode(TextEdit edit) {
+        return true;
+    }
+
+    /**
+     * Visits a <code>CopySourceEdit</code> instance.
+     *
+     * @param edit the node to visit
+     * @return If <code>true</code> is returned, the given node's child
+     *  nodes will be visited next; however, if <code>false</code> is
+     *  returned, the given node's child nodes will not be visited.
+     */
+    public bool visit(CopySourceEdit edit) {
+        return visitNode(edit);
+    }
+
+    /**
+     * Visits a <code>CopyTargetEdit</code> instance.
+     *
+     * @param edit the node to visit
+     * @return If <code>true</code> is returned, the given node's child
+     *  nodes will be visited next; however, if <code>false</code> is
+     *  returned, the given node's child nodes will not be visited.
+     */
+    public bool visit(CopyTargetEdit edit) {
+        return visitNode(edit);
+    }
+
+    /**
+     * Visits a <code>MoveSourceEdit</code> instance.
+     *
+     * @param edit the node to visit
+     * @return If <code>true</code> is returned, the given node's child
+     *  nodes will be visited next; however, if <code>false</code> is
+     *  returned, the given node's child nodes will not be visited.
+     */
+    public bool visit(MoveSourceEdit edit) {
+        return visitNode(edit);
+    }
+
+    /**
+     * Visits a <code>MoveTargetEdit</code> instance.
+     *
+     * @param edit the node to visit
+     * @return If <code>true</code> is returned, the given node's child
+     *  nodes will be visited next; however, if <code>false</code> is
+     *  returned, the given node's child nodes will not be visited.
+     */
+    public bool visit(MoveTargetEdit edit) {
+        return visitNode(edit);
+    }
+
+    /**
+     * Visits a <code>RangeMarker</code> instance.
+     *
+     * @param edit the node to visit
+     * @return If <code>true</code> is returned, the given node's child
+     *  nodes will be visited next; however, if <code>false</code> is
+     *  returned, the given node's child nodes will not be visited.
+     */
+    public bool visit(RangeMarker edit) {
+        return visitNode(edit);
+    }
+
+    /**
+     * Visits a <code>CopyingRangeMarker</code> instance.
+     *
+     * @param edit the node to visit
+     * @return If <code>true</code> is returned, the given node's child
+     *  nodes will be visited next; however, if <code>false</code> is
+     *  returned, the given node's child nodes will not be visited.
+     */
+    public bool visit(CopyingRangeMarker edit) {
+        return visitNode(edit);
+    }
+
+    /**
+     * Visits a <code>DeleteEdit</code> instance.
+     *
+     * @param edit the node to visit
+     * @return If <code>true</code> is returned, the given node's child
+     *  nodes will be visited next; however, if <code>false</code> is
+     *  returned, the given node's child nodes will not be visited.
+     */
+    public bool visit(DeleteEdit edit) {
+        return visitNode(edit);
+    }
+
+    /**
+     * Visits a <code>InsertEdit</code> instance.
+     *
+     * @param edit the node to visit
+     * @return If <code>true</code> is returned, the given node's child
+     *  nodes will be visited next; however, if <code>false</code> is
+     *  returned, the given node's child nodes will not be visited.
+     */
+    public bool visit(InsertEdit edit) {
+        return visitNode(edit);
+    }
+
+    /**
+     * Visits a <code>ReplaceEdit</code> instance.
+     *
+     * @param edit the node to visit
+     * @return If <code>true</code> is returned, the given node's child
+     *  nodes will be visited next; however, if <code>false</code> is
+     *  returned, the given node's child nodes will not be visited.
+     */
+    public bool visit(ReplaceEdit edit) {
+        return visitNode(edit);
+    }
+
+    /**
+     * Visits a <code>UndoEdit</code> instance.
+     *
+     * @param edit the node to visit
+     * @return If <code>true</code> is returned, the given node's child
+     *  nodes will be visited next; however, if <code>false</code> is
+     *  returned, the given node's child nodes will not be visited.
+     */
+    public bool visit(UndoEdit edit) {
+        return visitNode(edit);
+    }
+
+    /**
+     * Visits a <code>MultiTextEdit</code> instance.
+     *
+     * @param edit the node to visit
+     * @return If <code>true</code> is returned, the given node's child
+     *  nodes will be visited next; however, if <code>false</code> is
+     *  returned, the given node's child nodes will not be visited.
+     */
+    public bool visit(MultiTextEdit edit) {
+        return visitNode(edit);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/TreeIterationInfo.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.TreeIterationInfo;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.runtime.Assert;
+
+
+class TreeIterationInfo {
+
+    interface Visitor {
+        void visit(TextEdit edit);
+    }
+
+    private int fMark= -1;
+    private TextEdit[][] fEditStack;
+    private int[] fIndexStack;
+
+    public this(){
+        fEditStack= new TextEdit[][](10);
+        fIndexStack= new int[10];
+    }
+
+    public int getSize() {
+        return fMark + 1;
+    }
+    public void push(TextEdit[] edits) {
+        if (++fMark is fEditStack.length) {
+            TextEdit[][] t1= new TextEdit[][](fEditStack.length * 2);
+            SimpleType!(TextEdit[]).arraycopy(fEditStack, 0, t1, 0, fEditStack.length);
+            fEditStack= t1;
+            int[] t2= new int[fEditStack.length];
+            System.arraycopy(fIndexStack, 0, t2, 0, fIndexStack.length);
+            fIndexStack= t2;
+        }
+        fEditStack[fMark]= edits;
+        fIndexStack[fMark]= -1;
+    }
+    public void setIndex(int index) {
+        fIndexStack[fMark]= index;
+    }
+    public void pop() {
+        fEditStack[fMark]= null;
+        fIndexStack[fMark]= -1;
+        fMark--;
+    }
+    public void accept(Visitor visitor) {
+        for (int i= fMark; i >= 0; i--) {
+            Assert.isTrue(fIndexStack[i] >= 0);
+            int start= fIndexStack[i] + 1;
+            TextEdit[] edits= fEditStack[i];
+            for (int s= start; s < edits.length; s++) {
+                visitor.visit(edits[s]);
+            }
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/UndoCollector.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.UndoCollector;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.UndoEdit; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentListener;
+
+
+class UndoCollector : IDocumentListener {
+
+    protected UndoEdit undo;
+
+    package UndoEdit undo_package(){
+        return undo;
+    }
+
+    private int fOffset;
+    private int fLength;
+
+    /**
+     * @since 3.1
+     */
+    private String fLastCurrentText;
+
+    public this(TextEdit root) {
+        fOffset= root.getOffset();
+        fLength= root.getLength();
+    }
+
+    public void connect(IDocument document) {
+        document.addDocumentListener(this);
+        undo= new UndoEdit();
+    }
+
+    public void disconnect(IDocument document) {
+        if (undo !is null) {
+            document.removeDocumentListener(this);
+            undo.defineRegion(fOffset, fLength);
+        }
+    }
+
+    public void documentChanged(DocumentEvent event) {
+        fLength+= getDelta(event);
+    }
+
+    private static int getDelta(DocumentEvent event) {
+        String text= event.getText();
+        return text is null ? -event.getLength() : (text.length() - event.getLength());
+    }
+
+    public void documentAboutToBeChanged(DocumentEvent event) {
+        int offset= event.getOffset();
+        int currentLength= event.getLength();
+        String currentText= null;
+        try {
+            currentText= event.getDocument().get(offset, currentLength);
+        } catch (BadLocationException cannotHappen) {
+            Assert.isTrue(false, "Can't happen"); //$NON-NLS-1$
+        }
+
+        /*
+         * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=93634
+         * If the same string is replaced on many documents (e.g. rename
+         * package), the size of the undo can be reduced by using the same
+         * String instance in all edits, instead of using the unique String
+         * returned from IDocument.get(int, int).
+         */
+        if (fLastCurrentText !is null && fLastCurrentText.equals(currentText))
+            currentText= fLastCurrentText;
+        else
+            fLastCurrentText= currentText;
+
+        String newText= event.getText();
+        undo.add(new ReplaceEdit(offset, newText !is null ? newText.length() : 0, currentText));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/edits/UndoEdit.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,134 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.edits.UndoEdit;
+
+import dwtx.text.edits.MultiTextEdit; // packageimport
+import dwtx.text.edits.CopySourceEdit; // packageimport
+import dwtx.text.edits.MoveSourceEdit; // packageimport
+import dwtx.text.edits.CopyingRangeMarker; // packageimport
+import dwtx.text.edits.ReplaceEdit; // packageimport
+import dwtx.text.edits.EditDocument; // packageimport
+import dwtx.text.edits.UndoCollector; // packageimport
+import dwtx.text.edits.DeleteEdit; // packageimport
+import dwtx.text.edits.MoveTargetEdit; // packageimport
+import dwtx.text.edits.CopyTargetEdit; // packageimport
+import dwtx.text.edits.TextEditCopier; // packageimport
+import dwtx.text.edits.ISourceModifier; // packageimport
+import dwtx.text.edits.TextEditMessages; // packageimport
+import dwtx.text.edits.TextEditProcessor; // packageimport
+import dwtx.text.edits.MalformedTreeException; // packageimport
+import dwtx.text.edits.TreeIterationInfo; // packageimport
+import dwtx.text.edits.TextEditVisitor; // packageimport
+import dwtx.text.edits.TextEditGroup; // packageimport
+import dwtx.text.edits.TextEdit; // packageimport
+import dwtx.text.edits.RangeMarker; // packageimport
+import dwtx.text.edits.InsertEdit; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.IDocument;
+
+
+/**
+ * This class encapsulates the reverse changes of an executed text
+ * edit tree. To apply an undo memento to a document use method
+ * <code>apply(IDocument)</code>.
+ * <p>
+ * Clients can't add additional children to an undo edit nor can they
+ * add an undo edit as a child to another edit. Doing so results in
+ * both cases in a <code>MalformedTreeException<code>.
+ *
+ * @since 3.0
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class UndoEdit : TextEdit {
+
+    this() {
+        super(0, Integer.MAX_VALUE);
+    }
+
+    private this(UndoEdit other) {
+        super(other);
+    }
+
+    /*
+     * @see dwtx.text.edits.TextEdit#internalAdd(dwtx.text.edits.TextEdit)
+     */
+    void internalAdd(TextEdit child)  {
+        throw new MalformedTreeException(null, this, TextEditMessages.getString("UndoEdit.no_children")); //$NON-NLS-1$
+    }
+
+    /*
+     * @see dwtx.text.edits.MultiTextEdit#aboutToBeAdded(dwtx.text.edits.TextEdit)
+     */
+    void aboutToBeAdded(TextEdit parent) {
+        throw new MalformedTreeException(parent, this, TextEditMessages.getString("UndoEdit.can_not_be_added")); //$NON-NLS-1$
+    }
+
+    UndoEdit dispatchPerformEdits(TextEditProcessor processor)  {
+        return processor.executeUndo();
+    }
+
+    void dispatchCheckIntegrity(TextEditProcessor processor)  {
+        processor.checkIntegrityUndo();
+    }
+
+    /*
+     * @see dwtx.text.edits.TextEdit#doCopy()
+     */
+    protected TextEdit doCopy() {
+        return new UndoEdit(this);
+    }
+
+    /*
+     * @see TextEdit#accept0
+     */
+    protected void accept0(TextEditVisitor visitor) {
+        bool visitChildren= visitor.visit(this);
+        if (visitChildren) {
+            acceptChildren(visitor);
+        }
+    }
+
+    /*
+     * @see TextEdit#performDocumentUpdating
+     */
+    int performDocumentUpdating(IDocument document)  {
+        fDelta= 0;
+        return fDelta;
+    }
+
+    void add(ReplaceEdit edit) {
+        List children= internalGetChildren();
+        if (children is null) {
+            children= new ArrayList(2);
+            internalSetChildren(children);
+        }
+        children.add(edit);
+    }
+
+    void defineRegion(int offset, int length) {
+        internalSetOffset(offset);
+        internalSetLength(length);
+    }
+
+    bool deleteChildren() {
+        return false;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/undo/DocumentUndoEvent.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,175 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.undo.DocumentUndoEvent;
+
+// import dwtx.text.undo.DocumentUndoManager; // packageimport
+// import dwtx.text.undo.DocumentUndoManagerRegistry; // packageimport
+// import dwtx.text.undo.IDocumentUndoListener; // packageimport
+// import dwtx.text.undo.UndoMessages; // packageimport
+// import dwtx.text.undo.IDocumentUndoManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.IDocument;
+
+
+/**
+ * Describes document changes initiated by undo or redo.
+ * <p>
+ * Clients are not supposed to subclass or create instances of this class.
+ * </p>
+ *
+ * @see IDocumentUndoManager
+ * @see IDocumentUndoListener
+ * @since 3.2
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class DocumentUndoEvent {
+
+    /**
+     * Indicates that the described document event is about to be
+     * undone.
+     */
+    public static const int ABOUT_TO_UNDO= 1 << 0;
+
+    /**
+     * Indicates that the described document event is about to be
+     * redone.
+     */
+    public static const int ABOUT_TO_REDO= 1 << 1;
+
+    /**
+     * Indicates that the described document event has been undone.
+     */
+    public static const int UNDONE= 1 << 2;
+
+    /**
+     * Indicates that the described document event has been redone.
+     */
+    public static const int REDONE= 1 << 3;
+
+    /**
+     * Indicates that the described document event is a compound undo
+     * or redo event.
+     */
+    public static const int COMPOUND= 1 << 4;
+
+    /** The changed document. */
+    private IDocument fDocument;
+
+    /** The document offset where the change begins. */
+    private int fOffset;
+
+    /** Text inserted into the document. */
+    private String fText;
+
+    /** Text replaced in the document. */
+    private String fPreservedText;
+
+    /** Bit mask of event types describing the event */
+    private int fEventType;
+
+    /** The source that triggered this event or <code>null</code> if unknown. */
+    private Object fSource;
+
+    /**
+     * Creates a new document event.
+     *
+     * @param doc the changed document
+     * @param offset the offset of the replaced text
+     * @param text the substitution text
+     * @param preservedText the replaced text
+     * @param eventType a bit mask describing the type(s) of event
+     * @param source the source that triggered this event or <code>null</code> if unknown
+     */
+    this(IDocument doc, int offset, String text, String preservedText, int eventType, Object source) {
+
+        Assert.isNotNull(cast(Object)doc);
+        Assert.isTrue(offset >= 0);
+
+        fDocument= doc;
+        fOffset= offset;
+        fText= text;
+        fPreservedText= preservedText;
+        fEventType= eventType;
+        fSource= source;
+    }
+
+    /**
+     * Returns the changed document.
+     *
+     * @return the changed document
+     */
+    public IDocument getDocument() {
+        return fDocument;
+    }
+
+    /**
+     * Returns the offset of the change.
+     *
+     * @return the offset of the change
+     */
+    public int getOffset() {
+        return fOffset;
+    }
+
+    /**
+     * Returns the text that has been inserted.
+     *
+     * @return the text that has been inserted
+     */
+    public String getText() {
+        return fText;
+    }
+
+    /**
+     * Returns the text that has been replaced.
+     *
+     * @return the text that has been replaced
+     */
+    public String getPreservedText() {
+        return fPreservedText;
+    }
+
+    /**
+     * Returns the type of event that is occurring.
+     *
+     * @return the bit mask that indicates the type (or types) of the event
+     */
+    public int getEventType() {
+        return fEventType;
+    }
+
+    /**
+     * Returns the source that triggered this event.
+     *
+     * @return the source that triggered this event.
+     */
+    public Object getSource() {
+        return fSource;
+    }
+
+    /**
+     * Returns whether the change was a compound change or not.
+     *
+     * @return  <code>true</code> if the undo or redo change is a
+     *          compound change, <code>false</code> if it is not
+     */
+    public bool isCompound() {
+        return (fEventType & COMPOUND) !is 0;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/undo/DocumentUndoManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,1297 @@
+/*******************************************************************************
+ * Copyright (c) 2006, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.undo.DocumentUndoManager;
+
+import dwtx.text.undo.DocumentUndoManagerRegistry; // packageimport
+import dwtx.text.undo.DocumentUndoEvent; // packageimport
+import dwtx.text.undo.IDocumentUndoListener; // packageimport
+import dwtx.text.undo.UndoMessages; // packageimport
+import dwtx.text.undo.IDocumentUndoManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.core.commands.ExecutionException;
+import dwtx.core.commands.operations.AbstractOperation;
+import dwtx.core.commands.operations.IContextReplacingOperation;
+import dwtx.core.commands.operations.IOperationHistory;
+import dwtx.core.commands.operations.IOperationHistoryListener;
+import dwtx.core.commands.operations.IUndoContext;
+import dwtx.core.commands.operations.IUndoableOperation;
+import dwtx.core.commands.operations.ObjectUndoContext;
+import dwtx.core.commands.operations.OperationHistoryEvent;
+import dwtx.core.commands.operations.OperationHistoryFactory;
+import dwtx.core.runtime.Assert;
+import dwtx.core.runtime.IAdaptable;
+import dwtx.core.runtime.IProgressMonitor;
+import dwtx.core.runtime.IStatus;
+import dwtx.core.runtime.ListenerList;
+import dwtx.core.runtime.Status;
+import dwtx.jface.text.BadLocationException;
+import dwtx.jface.text.DocumentEvent;
+import dwtx.jface.text.IDocument;
+import dwtx.jface.text.IDocumentExtension4;
+import dwtx.jface.text.IDocumentListener;
+import dwtx.jface.text.TextUtilities;
+
+/**
+ * A standard implementation of a document-based undo manager that
+ * creates an undo history based on changes to its document.
+ * <p>
+ * Based on the 3.1 implementation of DefaultUndoManager, it was implemented
+ * using the document-related manipulations defined in the original
+ * DefaultUndoManager, by separating the document manipulations from the
+ * viewer-specific processing.</p>
+ * <p>
+ * The classes representing individual text edits (formerly text commands)
+ * were promoted from inner types to their own classes in order to support
+ * reassignment to a different undo manager.<p>
+ * <p>
+ * This class is not intended to be subclassed.
+ * </p>
+ *
+ * @see IDocumentUndoManager
+ * @see DocumentUndoManagerRegistry
+ * @see IDocumentUndoListener
+ * @see dwtx.jface.text.IDocument
+ * @since 3.2
+ * @noextend This class is not intended to be subclassed by clients.
+ */
+public class DocumentUndoManager : IDocumentUndoManager {
+
+
+    /**
+     * Represents an undo-able text change, described as the
+     * replacement of some preserved text with new text.
+     * <p>
+     * Based on the DefaultUndoManager.TextCommand from R3.1.
+     * </p>
+     */
+    private static class UndoableTextChange : AbstractOperation {
+
+        /** The start index of the replaced text. */
+        protected int fStart= -1;
+
+        /** The end index of the replaced text. */
+        protected int fEnd= -1;
+
+        /** The newly inserted text. */
+        protected String fText;
+
+        /** The replaced text. */
+        protected String fPreservedText;
+
+        /** The undo modification stamp. */
+        protected long fUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+
+        /** The redo modification stamp. */
+        protected long fRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+
+        /** The undo manager that generated the change. */
+        protected DocumentUndoManager fDocumentUndoManager;
+
+        /**
+         * Creates a new text change.
+         *
+         * @param manager the undo manager for this change
+         */
+        this(DocumentUndoManager manager) {
+            super(UndoMessages.getString("DocumentUndoManager.operationLabel")); //$NON-NLS-1$
+            this.fDocumentUndoManager= manager;
+            addContext(manager.getUndoContext());
+        }
+
+        /**
+         * Re-initializes this text change.
+         */
+        protected void reinitialize() {
+            fStart= fEnd= -1;
+            fText= fPreservedText= null;
+            fUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+            fRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+        }
+
+        /**
+         * Sets the start and the end index of this change.
+         *
+         * @param start the start index
+         * @param end the end index
+         */
+        protected void set(int start, int end) {
+            fStart= start;
+            fEnd= end;
+            fText= null;
+            fPreservedText= null;
+        }
+
+        /*
+         * @see dwtx.core.commands.operations.IUndoableOperation#dispose()
+         */
+        public void dispose() {
+            reinitialize();
+        }
+
+        /**
+         * Undo the change described by this change.
+         */
+        protected void undoTextChange() {
+            try {
+                if (auto de4 = cast(IDocumentExtension4)fDocumentUndoManager.fDocument )
+                    de4.replace(fStart, fText
+                            .length(), fPreservedText, fUndoModificationStamp);
+                else
+                    fDocumentUndoManager.fDocument.replace(fStart, fText.length(),
+                            fPreservedText);
+            } catch (BadLocationException x) {
+            }
+        }
+
+        /*
+         * @see dwtx.core.commands.operations.IUndoableOperation#canUndo()
+         */
+        public bool canUndo() {
+            if (isValid()) {
+                if (cast(IDocumentExtension4)fDocumentUndoManager.fDocument) {
+                    long docStamp= (cast(IDocumentExtension4) fDocumentUndoManager.fDocument)
+                            .getModificationStamp();
+
+                    // Normal case: an undo is valid if its redo will restore
+                    // document to its current modification stamp
+                    bool canUndo= docStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP
+                            || docStamp is getRedoModificationStamp();
+
+                    /*
+                     * Special case to check if the answer is false. If the last
+                     * document change was empty, then the document's modification
+                     * stamp was incremented but nothing was committed. The
+                     * operation being queried has an older stamp. In this case
+                     * only, the comparison is different. A sequence of document
+                     * changes that include an empty change is handled correctly
+                     * when a valid commit follows the empty change, but when
+                     * #canUndo() is queried just after an empty change, we must
+                     * special case the check. The check is very specific to prevent
+                     * false positives. see
+                     * https://bugs.eclipse.org/bugs/show_bug.cgi?id=98245
+                     */
+                    if (!canUndo
+                            && this is fDocumentUndoManager.fHistory
+                                    .getUndoOperation(fDocumentUndoManager.fUndoContext)
+                                // this is the latest operation
+                            && this !is fDocumentUndoManager.fCurrent
+                                // there is a more current operation not on the stack
+                            && !fDocumentUndoManager.fCurrent.isValid()
+                            // the current operation is not a valid document
+                            // modification
+                            && fDocumentUndoManager.fCurrent.fUndoModificationStamp !is
+                            // the invalid current operation has a document stamp
+                            IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) {
+                        canUndo= fDocumentUndoManager.fCurrent.fRedoModificationStamp is docStamp;
+                    }
+                    /*
+                     * When the composite is the current operation, it may hold the
+                     * timestamp of a no-op change. We check this here rather than
+                     * in an override of canUndo() in UndoableCompoundTextChange simply to
+                     * keep all the special case checks in one place.
+                     */
+                    if (!canUndo
+                            && this is fDocumentUndoManager.fHistory
+                                    .getUndoOperation(fDocumentUndoManager.fUndoContext)
+                            && // this is the latest operation
+                            null !is cast(UndoableCompoundTextChange)this
+                            && this is fDocumentUndoManager.fCurrent
+                            && // this is the current operation
+                            this.fStart is -1
+                            && // the current operation text is not valid
+                            fDocumentUndoManager.fCurrent.fRedoModificationStamp !is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP) {
+                            // but it has a redo stamp
+                        canUndo= fDocumentUndoManager.fCurrent.fRedoModificationStamp is docStamp;
+                    }
+                    return canUndo;
+
+                }
+                // if there is no timestamp to check, simply return true per the
+                // 3.0.1 behavior
+                return true;
+            }
+            return false;
+        }
+
+        /*
+         * @see dwtx.core.commands.operations.IUndoableOperation#canRedo()
+         */
+        public bool canRedo() {
+            if (isValid()) {
+                if (cast(IDocumentExtension4)fDocumentUndoManager.fDocument ) {
+                    long docStamp= (cast(IDocumentExtension4) fDocumentUndoManager.fDocument)
+                            .getModificationStamp();
+                    return docStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP
+                            || docStamp is getUndoModificationStamp();
+                }
+                // if there is no timestamp to check, simply return true per the
+                // 3.0.1 behavior
+                return true;
+            }
+            return false;
+        }
+
+        /*
+         * @see dwtx.core.commands.operations.IUndoableOperation#canExecute()
+         */
+        public bool canExecute() {
+            return fDocumentUndoManager.isConnected();
+        }
+
+        /*
+         * @see dwtx.core.commands.operations.IUndoableOperation.IUndoableOperation#execute(IProgressMonitor, IAdaptable)
+         */
+        public IStatus execute(IProgressMonitor monitor, IAdaptable uiInfo) {
+            // Text changes execute as they are typed, so executing one has no
+            // effect.
+            return Status.OK_STATUS;
+        }
+
+        /**
+         * {@inheritDoc}
+         * Notifies clients about the undo.
+         */
+        public IStatus undo(IProgressMonitor monitor, IAdaptable uiInfo) {
+            if (isValid()) {
+                fDocumentUndoManager.fireDocumentUndo(fStart, fPreservedText, fText, cast(Object)uiInfo, DocumentUndoEvent.ABOUT_TO_UNDO, false);
+                undoTextChange();
+                fDocumentUndoManager.resetProcessChangeState();
+                fDocumentUndoManager.fireDocumentUndo(fStart, fPreservedText, fText, cast(Object)uiInfo, DocumentUndoEvent.UNDONE, false);
+                return Status.OK_STATUS;
+            }
+            return IOperationHistory.OPERATION_INVALID_STATUS;
+        }
+
+        /**
+         * Re-applies the change described by this change.
+         */
+        protected void redoTextChange() {
+            try {
+                if (cast(IDocumentExtension4)fDocumentUndoManager.fDocument)
+                    (cast(IDocumentExtension4) fDocumentUndoManager.fDocument).replace(fStart, fEnd - fStart, fText, fRedoModificationStamp);
+                else
+                    fDocumentUndoManager.fDocument.replace(fStart, fEnd - fStart, fText);
+            } catch (BadLocationException x) {
+            }
+        }
+
+        /**
+         * Re-applies the change described by this change that was previously
+         * undone. Also notifies clients about the redo.
+         *
+         * @param monitor the progress monitor to use if necessary
+         * @param uiInfo an adaptable that can provide UI info if needed
+         * @return the status
+         */
+        public IStatus redo(IProgressMonitor monitor, IAdaptable uiInfo) {
+            if (isValid()) {
+                fDocumentUndoManager.fireDocumentUndo(fStart, fText, fPreservedText, cast(Object)uiInfo, DocumentUndoEvent.ABOUT_TO_REDO, false);
+                redoTextChange();
+                fDocumentUndoManager.resetProcessChangeState();
+                fDocumentUndoManager.fireDocumentUndo(fStart, fText, fPreservedText, cast(Object)uiInfo, DocumentUndoEvent.REDONE, false);
+                return Status.OK_STATUS;
+            }
+            return IOperationHistory.OPERATION_INVALID_STATUS;
+        }
+
+        /**
+         * Update the change in response to a commit.
+         */
+
+        protected void updateTextChange() {
+            fText= fDocumentUndoManager.fTextBuffer.toString();
+            fDocumentUndoManager.fTextBuffer.clear();
+            fPreservedText= fDocumentUndoManager.fPreservedTextBuffer.toString();
+            fDocumentUndoManager.fPreservedTextBuffer.clear();
+        }
+
+        /**
+         * Creates a new uncommitted text change depending on whether a compound
+         * change is currently being executed.
+         *
+         * @return a new, uncommitted text change or a compound text change
+         */
+        protected UndoableTextChange createCurrent() {
+            if (fDocumentUndoManager.fFoldingIntoCompoundChange)
+                return new UndoableCompoundTextChange(fDocumentUndoManager);
+            return new UndoableTextChange(fDocumentUndoManager);
+        }
+
+        /**
+         * Commits the current change into this one.
+         */
+        protected void commit() {
+            if (fStart < 0) {
+                if (fDocumentUndoManager.fFoldingIntoCompoundChange) {
+                    fDocumentUndoManager.fCurrent= createCurrent();
+                } else {
+                    reinitialize();
+                }
+            } else {
+                updateTextChange();
+                fDocumentUndoManager.fCurrent= createCurrent();
+            }
+            fDocumentUndoManager.resetProcessChangeState();
+        }
+
+        /**
+         * Updates the text from the buffers without resetting the buffers or adding
+         * anything to the stack.
+         */
+        protected void pretendCommit() {
+            if (fStart > -1) {
+                fText= fDocumentUndoManager.fTextBuffer.toString();
+                fPreservedText= fDocumentUndoManager.fPreservedTextBuffer.toString();
+            }
+        }
+
+        /**
+         * Attempt a commit of this change and answer true if a new fCurrent was
+         * created as a result of the commit.
+         *
+         * @return <code>true</code> if the change was committed and created
+         *          a new <code>fCurrent</code>, <code>false</code> if not
+         */
+        protected bool attemptCommit() {
+            pretendCommit();
+            if (isValid()) {
+                fDocumentUndoManager.commit();
+                return true;
+            }
+            return false;
+        }
+
+        /**
+         * Checks whether this text change is valid for undo or redo.
+         *
+         * @return <code>true</code> if the change is valid for undo or redo
+         */
+        protected bool isValid() {
+            return fStart > -1 && fEnd > -1 && fText !is null;
+        }
+
+        /*
+         * @see java.lang.Object#toString()
+         */
+        public override String toString() {
+            String delimiter= ", "; //$NON-NLS-1$
+            StringBuffer text= new StringBuffer(super.toString());
+            text.append("\n"); //$NON-NLS-1$
+            text.append(this.classinfo.name);
+            text.append(" undo modification stamp: "); //$NON-NLS-1$
+            text.append(fUndoModificationStamp);
+            text.append(" redo modification stamp: "); //$NON-NLS-1$
+            text.append(fRedoModificationStamp);
+            text.append(" start: "); //$NON-NLS-1$
+            text.append(fStart);
+            text.append(delimiter);
+            text.append("end: "); //$NON-NLS-1$
+            text.append(fEnd);
+            text.append(delimiter);
+            text.append("text: '"); //$NON-NLS-1$
+            text.append(fText);
+            text.append('\'');
+            text.append(delimiter);
+            text.append("preservedText: '"); //$NON-NLS-1$
+            text.append(fPreservedText);
+            text.append('\'');
+            return text.toString();
+        }
+
+        /**
+         * Return the undo modification stamp
+         *
+         * @return the undo modification stamp for this change
+         */
+        protected long getUndoModificationStamp() {
+            return fUndoModificationStamp;
+        }
+
+        /**
+         * Return the redo modification stamp
+         *
+         * @return the redo modification stamp for this change
+         */
+        protected long getRedoModificationStamp() {
+            return fRedoModificationStamp;
+        }
+    }
+
+
+    /**
+     * Represents an undo-able text change consisting of several individual
+     * changes.
+     */
+    private static class UndoableCompoundTextChange : UndoableTextChange {
+
+        /** The list of individual changes */
+        private List fChanges;
+
+        /**
+         * Creates a new compound text change.
+         *
+         * @param manager
+         *            the undo manager for this change
+         */
+        this(DocumentUndoManager manager) {
+            fChanges= new ArrayList();
+            super(manager);
+        }
+
+        /**
+         * Adds a new individual change to this compound change.
+         *
+         * @param change the change to be added
+         */
+        protected void add(UndoableTextChange change) {
+            fChanges.add(change);
+        }
+
+        /*
+         * @see dwtx.text.undo.UndoableTextChange#undo(dwtx.core.runtime.IProgressMonitor, dwtx.core.runtime.IAdaptable)
+         */
+        public IStatus undo(IProgressMonitor monitor, IAdaptable uiInfo) {
+
+            int size= fChanges.size();
+            if (size > 0) {
+                UndoableTextChange c;
+
+                c= cast(UndoableTextChange) fChanges.get(0);
+                fDocumentUndoManager.fireDocumentUndo(c.fStart, c.fPreservedText, c.fText, cast(Object)uiInfo, DocumentUndoEvent.ABOUT_TO_UNDO, true);
+
+                for (int i= size - 1; i >= 0; --i) {
+                    c= cast(UndoableTextChange) fChanges.get(i);
+                    c.undoTextChange();
+                }
+                fDocumentUndoManager.resetProcessChangeState();
+                fDocumentUndoManager.fireDocumentUndo(c.fStart, c.fPreservedText, c.fText, cast(Object)uiInfo,
+                        DocumentUndoEvent.UNDONE, true);
+            }
+            return Status.OK_STATUS;
+        }
+
+        /*
+         * @see dwtx.text.undo.UndoableTextChange#redo(dwtx.core.runtime.IProgressMonitor, dwtx.core.runtime.IAdaptable)
+         */
+        public IStatus redo(IProgressMonitor monitor, IAdaptable uiInfo) {
+
+            int size= fChanges.size();
+            if (size > 0) {
+
+                UndoableTextChange c;
+                c= cast(UndoableTextChange) fChanges.get(size - 1);
+                fDocumentUndoManager.fireDocumentUndo(c.fStart, c.fText, c.fPreservedText, cast(Object)uiInfo, DocumentUndoEvent.ABOUT_TO_REDO, true);
+
+                for (int i= 0; i <= size - 1; ++i) {
+                    c= cast(UndoableTextChange) fChanges.get(i);
+                    c.redoTextChange();
+                }
+                fDocumentUndoManager.resetProcessChangeState();
+                fDocumentUndoManager.fireDocumentUndo(c.fStart, c.fText, c.fPreservedText, cast(Object)uiInfo, DocumentUndoEvent.REDONE, true);
+            }
+
+            return Status.OK_STATUS;
+        }
+
+        /*
+         * @see dwtx.text.undo.UndoableTextChange#updateTextChange()
+         */
+        protected void updateTextChange() {
+            // first gather the data from the buffers
+            super.updateTextChange();
+
+            // the result of the update is stored as a child change
+            UndoableTextChange c= new UndoableTextChange(fDocumentUndoManager);
+            c.fStart= fStart;
+            c.fEnd= fEnd;
+            c.fText= fText;
+            c.fPreservedText= fPreservedText;
+            c.fUndoModificationStamp= fUndoModificationStamp;
+            c.fRedoModificationStamp= fRedoModificationStamp;
+            add(c);
+
+            // clear out all indexes now that the child is added
+            reinitialize();
+        }
+
+        /*
+         * @see dwtx.text.undo.UndoableTextChange#createCurrent()
+         */
+        protected UndoableTextChange createCurrent() {
+
+            if (!fDocumentUndoManager.fFoldingIntoCompoundChange)
+                return new UndoableTextChange(fDocumentUndoManager);
+
+            reinitialize();
+            return this;
+        }
+
+        /*
+         * @see dwtx.text.undo.UndoableTextChange#commit()
+         */
+        protected void commit() {
+            // if there is pending data, update the text change
+            if (fStart > -1)
+                updateTextChange();
+            fDocumentUndoManager.fCurrent= createCurrent();
+            fDocumentUndoManager.resetProcessChangeState();
+        }
+
+        /*
+         * @see dwtx.text.undo.UndoableTextChange#isValid()
+         */
+        protected bool isValid() {
+            return fStart > -1 || fChanges.size() > 0;
+        }
+
+        /*
+         * @see dwtx.text.undo.UndoableTextChange#getUndoModificationStamp()
+         */
+        protected long getUndoModificationStamp() {
+            if (fStart > -1)
+                return super.getUndoModificationStamp();
+            else if (fChanges.size() > 0)
+                return (cast(UndoableTextChange) fChanges.get(0))
+                        .getUndoModificationStamp();
+
+            return fUndoModificationStamp;
+        }
+
+        /*
+         * @see dwtx.text.undo.UndoableTextChange#getRedoModificationStamp()
+         */
+        protected long getRedoModificationStamp() {
+            if (fStart > -1)
+                return super.getRedoModificationStamp();
+            else if (fChanges.size() > 0)
+                return (cast(UndoableTextChange) fChanges.get(fChanges.size() - 1))
+                        .getRedoModificationStamp();
+
+            return fRedoModificationStamp;
+        }
+    }
+
+
+    /**
+     * Internal listener to document changes.
+     */
+    private class DocumentListener : IDocumentListener {
+
+        private String fReplacedText;
+
+        /*
+         * @see dwtx.jface.text.IDocumentListener#documentAboutToBeChanged(dwtx.jface.text.DocumentEvent)
+         */
+        public void documentAboutToBeChanged(DocumentEvent event) {
+            try {
+                fReplacedText= event.getDocument().get(event.getOffset(),
+                        event.getLength());
+                fPreservedUndoModificationStamp= event.getModificationStamp();
+            } catch (BadLocationException x) {
+                fReplacedText= null;
+            }
+        }
+
+        /*
+         * @see dwtx.jface.text.IDocumentListener#documentChanged(dwtx.jface.text.DocumentEvent)
+         */
+        public void documentChanged(DocumentEvent event) {
+            fPreservedRedoModificationStamp= event.getModificationStamp();
+
+            // record the current valid state for the top operation in case it
+            // remains the
+            // top operation but changes state.
+            IUndoableOperation op= fHistory.getUndoOperation(fUndoContext);
+            bool wasValid= false;
+            if (op !is null)
+                wasValid= op.canUndo();
+            // Process the change, providing the before and after timestamps
+            processChange(event.getOffset(), event.getOffset()
+                    + event.getLength(), event.getText(), fReplacedText,
+                    fPreservedUndoModificationStamp,
+                    fPreservedRedoModificationStamp);
+
+            // now update fCurrent with the latest buffers from the document
+            // change.
+            fCurrent.pretendCommit();
+
+            if (op is fCurrent) {
+                // if the document change did not cause a new fCurrent to be
+                // created, then we should
+                // notify the history that the current operation changed if its
+                // validity has changed.
+                if (wasValid !is fCurrent.isValid())
+                    fHistory.operationChanged(op);
+            } else {
+                // if the change created a new fCurrent that we did not yet add
+                // to the
+                // stack, do so if it's valid and we are not in the middle of a
+                // compound change.
+                if (fCurrent !is fLastAddedTextEdit && fCurrent.isValid()) {
+                    addToOperationHistory(fCurrent);
+                }
+            }
+        }
+    }
+
+    /*
+     * @see IOperationHistoryListener
+     */
+    private class HistoryListener : IOperationHistoryListener {
+
+        private IUndoableOperation fOperation;
+
+        public void historyNotification(OperationHistoryEvent event) {
+            final int type= event.getEventType();
+            switch (type) {
+            case OperationHistoryEvent.ABOUT_TO_UNDO:
+            case OperationHistoryEvent.ABOUT_TO_REDO:
+                // if this is one of our operations
+                if (event.getOperation().hasContext(fUndoContext)) {
+                    // if we are undoing/redoing an operation we generated, then
+                    // ignore
+                    // the document changes associated with this undo or redo.
+                    if (cast(UndoableTextChange)event.getOperation() ) {
+                        listenToTextChanges(false);
+
+                        // in the undo case only, make sure compounds are closed
+                        if (type is OperationHistoryEvent.ABOUT_TO_UNDO) {
+                            if (fFoldingIntoCompoundChange) {
+                                endCompoundChange();
+                            }
+                        }
+                    } else {
+                        // the undo or redo has our context, but it is not one
+                        // of our edits. We will listen to the changes, but will
+                        // reset the state that tracks the undo/redo history.
+                        commit();
+                        fLastAddedTextEdit= null;
+                    }
+                    fOperation= event.getOperation();
+                }
+                break;
+            case OperationHistoryEvent.UNDONE:
+            case OperationHistoryEvent.REDONE:
+            case OperationHistoryEvent.OPERATION_NOT_OK:
+                if (event.getOperation() is fOperation) {
+                    listenToTextChanges(true);
+                    fOperation= null;
+                }
+                break;
+            }
+        }
+
+    }
+
+
+    /**
+     * The undo context for this document undo manager.
+     */
+    private ObjectUndoContext fUndoContext;
+
+    /**
+     * The document whose changes are being tracked.
+     */
+    private IDocument fDocument;
+
+    /**
+     * The currently constructed edit.
+     */
+    private UndoableTextChange fCurrent;
+
+    /**
+     * The internal document listener.
+     */
+    private DocumentListener fDocumentListener;
+
+    /**
+     * Indicates whether the current change belongs to a compound change.
+     */
+    private bool fFoldingIntoCompoundChange= false;
+
+    /**
+     * The operation history being used to store the undo history.
+     */
+    private IOperationHistory fHistory;
+
+    /**
+     * The operation history listener used for managing undo and redo before and
+     * after the individual edits are performed.
+     */
+    private IOperationHistoryListener fHistoryListener;
+
+    /**
+     * The text edit last added to the operation history. This must be tracked
+     * internally instead of asking the history, since outside parties may be
+     * placing items on our undo/redo history.
+     */
+    private UndoableTextChange fLastAddedTextEdit= null;
+
+    /**
+     * The document modification stamp for redo.
+     */
+    private long fPreservedRedoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+
+    /**
+     * Text buffer to collect viewer content which has been replaced
+     */
+    private StringBuffer fPreservedTextBuffer;
+
+    /**
+     * The document modification stamp for undo.
+     */
+    private long fPreservedUndoModificationStamp= IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP;
+
+    /**
+     * The last delete text edit.
+     */
+    private UndoableTextChange fPreviousDelete;
+
+    /**
+     * Text buffer to collect text which is inserted into the viewer
+     */
+    private StringBuffer fTextBuffer;
+
+    /** Indicates inserting state. */
+    private bool fInserting= false;
+
+    /** Indicates overwriting state. */
+    private bool fOverwriting= false;
+
+    /** The registered document listeners. */
+    private ListenerList fDocumentUndoListeners;
+
+    /** The list of clients connected. */
+    private List fConnected;
+
+    /**
+     *
+     * Create a DocumentUndoManager for the given document.
+     *
+     * @param document the document whose undo history is being managed.
+     */
+    public this(IDocument document) {
+//         super();
+        Assert.isNotNull(cast(Object)document);
+        fDocument= document;
+        fHistory= OperationHistoryFactory.getOperationHistory();
+        fUndoContext= new ObjectUndoContext(cast(Object)fDocument);
+        fConnected= new ArrayList();
+        fDocumentUndoListeners= new ListenerList(ListenerList.IDENTITY);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentUndoManager#addDocumentUndoListener(dwtx.jface.text.IDocumentUndoListener)
+     */
+    public void addDocumentUndoListener(IDocumentUndoListener listener) {
+        fDocumentUndoListeners.add(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentUndoManager#removeDocumentUndoListener(dwtx.jface.text.IDocumentUndoListener)
+     */
+    public void removeDocumentUndoListener(IDocumentUndoListener listener) {
+        fDocumentUndoListeners.remove(cast(Object)listener);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentUndoManager#getUndoContext()
+     */
+    public IUndoContext getUndoContext() {
+        return fUndoContext;
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentUndoManager#commit()
+     */
+    public void commit() {
+        // if fCurrent has never been placed on the history, do so now.
+        // this can happen when there are multiple programmatically commits in a
+        // single document change.
+        if (fLastAddedTextEdit !is fCurrent) {
+            fCurrent.pretendCommit();
+            if (fCurrent.isValid())
+                addToOperationHistory(fCurrent);
+        }
+        fCurrent.commit();
+    }
+
+    /*
+     * @see dwtx.text.undo.IDocumentUndoManager#reset()
+     */
+    public void reset() {
+        if (isConnected()) {
+            shutdown();
+            initialize();
+        }
+    }
+
+    /*
+     * @see dwtx.text.undo.IDocumentUndoManager#redoable()
+     */
+    public bool redoable() {
+        return OperationHistoryFactory.getOperationHistory().canRedo(fUndoContext);
+    }
+
+    /*
+     * @see dwtx.text.undo.IDocumentUndoManager#undoable()
+     */
+    public bool undoable() {
+        return OperationHistoryFactory.getOperationHistory().canUndo(fUndoContext);
+    }
+
+    /*
+     * @see dwtx.text.undo.IDocumentUndoManager#undo()
+     */
+    public void redo()  {
+        if (isConnected() && redoable())
+            OperationHistoryFactory.getOperationHistory().redo(getUndoContext(), null, null);
+    }
+
+    /*
+     * @see dwtx.text.undo.IDocumentUndoManager#undo()
+     */
+    public void undo()  {
+        if (undoable())
+            OperationHistoryFactory.getOperationHistory().undo(fUndoContext, null, null);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentUndoManager#connect(java.lang.Object)
+     */
+    public void connect(Object client) {
+        if (!isConnected()) {
+            initialize();
+        }
+        if (!fConnected.contains(client))
+            fConnected.add(client);
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentUndoManager#disconnect(java.lang.Object)
+     */
+    public void disconnect(Object client) {
+        fConnected.remove(client);
+        if (!isConnected()) {
+            shutdown();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentUndoManager#beginCompoundChange()
+     */
+    public void beginCompoundChange() {
+        if (isConnected()) {
+            fFoldingIntoCompoundChange= true;
+            commit();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentUndoManager#endCompoundChange()
+     */
+    public void endCompoundChange() {
+        if (isConnected()) {
+            fFoldingIntoCompoundChange= false;
+            commit();
+        }
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentUndoManager#setUndoLimit(int)
+     */
+    public void setMaximalUndoLevel(int undoLimit) {
+        fHistory.setLimit(fUndoContext, undoLimit);
+    }
+
+    /**
+     * Fires a document undo event to all registered document undo listeners.
+     * Uses a robust iterator.
+     *
+     * @param offset the document offset
+     * @param text the text that was inserted
+     * @param preservedText the text being replaced
+     * @param source the source which triggered the event
+     * @param eventType the type of event causing the change
+     * @param isCompound a flag indicating whether the change is a compound change
+     * @see IDocumentUndoListener
+     */
+    void fireDocumentUndo(int offset, String text, String preservedText, Object source, int eventType, bool isCompound) {
+        eventType= isCompound ? eventType | DocumentUndoEvent.COMPOUND : eventType;
+        DocumentUndoEvent event= new DocumentUndoEvent(fDocument, offset, text, preservedText, eventType, source);
+        Object[] listeners= fDocumentUndoListeners.getListeners();
+        for (int i= 0; i < listeners.length; i++) {
+            (cast(IDocumentUndoListener)listeners[i]).documentUndoNotification(event);
+        }
+    }
+
+    /**
+     * Adds any listeners needed to track the document and the operations
+     * history.
+     */
+    private void addListeners() {
+        fHistoryListener= new HistoryListener();
+        fHistory.addOperationHistoryListener(fHistoryListener);
+        listenToTextChanges(true);
+    }
+
+    /**
+     * Removes any listeners that were installed by the document.
+     */
+    private void removeListeners() {
+        listenToTextChanges(false);
+        fHistory.removeOperationHistoryListener(fHistoryListener);
+        fHistoryListener= null;
+    }
+
+    /**
+     * Adds the given text edit to the operation history if it is not part of a
+     * compound change.
+     *
+     * @param edit
+     *            the edit to be added
+     */
+    private void addToOperationHistory(UndoableTextChange edit) {
+        if (!fFoldingIntoCompoundChange
+                || cast(UndoableCompoundTextChange)edit ) {
+            fHistory.add(edit);
+            fLastAddedTextEdit= edit;
+        }
+    }
+
+    /**
+     * Disposes the undo history.
+     */
+    private void disposeUndoHistory() {
+        fHistory.dispose(fUndoContext, true, true, true);
+    }
+
+    /**
+     * Initializes the undo history.
+     */
+    private void initializeUndoHistory() {
+        if (fHistory !is null && fUndoContext !is null)
+            fHistory.dispose(fUndoContext, true, true, false);
+
+    }
+
+    /**
+     * Checks whether the given text starts with a line delimiter and
+     * subsequently contains a white space only.
+     *
+     * @param text the text to check
+     * @return <code>true</code> if the text is a line delimiter followed by
+     *         whitespace, <code>false</code> otherwise
+     */
+    private bool isWhitespaceText(String text) {
+
+        if (text is null || text.length() is 0)
+            return false;
+
+        String[] delimiters= fDocument.getLegalLineDelimiters();
+        int index= TextUtilities.startsWith(delimiters, text);
+        if (index > -1) {
+            char c;
+            int length= text.length();
+            for (int i= delimiters[index].length; i < length; i++) {
+                c= text.charAt(i);
+                if (c !is ' ' && c !is '\t')
+                    return false;
+            }
+            return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Switches the state of whether there is a text listener or not.
+     *
+     * @param listen the state which should be established
+     */
+    private void listenToTextChanges(bool listen) {
+        if (listen) {
+            if (fDocumentListener is null && fDocument !is null) {
+                fDocumentListener= new DocumentListener();
+                fDocument.addDocumentListener(fDocumentListener);
+            }
+        } else if (!listen) {
+            if (fDocumentListener !is null && fDocument !is null) {
+                fDocument.removeDocumentListener(fDocumentListener);
+                fDocumentListener= null;
+            }
+        }
+    }
+
+    private void processChange(int modelStart, int modelEnd,
+            String insertedText, String replacedText,
+            long beforeChangeModificationStamp,
+            long afterChangeModificationStamp) {
+
+        if (insertedText is null)
+            insertedText= ""; //$NON-NLS-1$
+
+        if (replacedText is null)
+            replacedText= ""; //$NON-NLS-1$
+
+        int length= insertedText.length();
+        int diff= modelEnd - modelStart;
+
+        if (fCurrent.fUndoModificationStamp is IDocumentExtension4.UNKNOWN_MODIFICATION_STAMP)
+            fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+        // normalize
+        if (diff < 0) {
+            int tmp= modelEnd;
+            modelEnd= modelStart;
+            modelStart= tmp;
+        }
+
+        if (modelStart is modelEnd) {
+            // text will be inserted
+            if ((length is 1) || isWhitespaceText(insertedText)) {
+                // by typing or whitespace
+                if (!fInserting
+                        || (modelStart !is fCurrent.fStart
+                                + fTextBuffer.length())) {
+                    fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
+                    if (fCurrent.attemptCommit())
+                        fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+                    fInserting= true;
+                }
+                if (fCurrent.fStart < 0)
+                    fCurrent.fStart= fCurrent.fEnd= modelStart;
+                if (length > 0)
+                    fTextBuffer.append(insertedText);
+            } else if (length > 0) {
+                // by pasting or model manipulation
+                fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
+                if (fCurrent.attemptCommit())
+                    fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+                fCurrent.fStart= fCurrent.fEnd= modelStart;
+                fTextBuffer.append(insertedText);
+                fCurrent.fRedoModificationStamp= afterChangeModificationStamp;
+                if (fCurrent.attemptCommit())
+                    fCurrent.fUndoModificationStamp= afterChangeModificationStamp;
+
+            }
+        } else {
+            if (length is 0) {
+                // text will be deleted by backspace or DEL key or empty
+                // clipboard
+                length= replacedText.length;
+                String[] delimiters= fDocument.getLegalLineDelimiters();
+
+                if ((length is 1)
+                        || TextUtilities.equals(delimiters, replacedText) > -1) {
+
+                    // whereby selection is empty
+
+                    if (fPreviousDelete.fStart is modelStart
+                            && fPreviousDelete.fEnd is modelEnd) {
+                        // repeated DEL
+
+                        // correct wrong settings of fCurrent
+                        if (fCurrent.fStart is modelEnd
+                                && fCurrent.fEnd is modelStart) {
+                            fCurrent.fStart= modelStart;
+                            fCurrent.fEnd= modelEnd;
+                        }
+                        // append to buffer && extend edit range
+                        fPreservedTextBuffer.append(replacedText);
+                        ++fCurrent.fEnd;
+
+                    } else if (fPreviousDelete.fStart is modelEnd) {
+                        // repeated backspace
+
+                        // insert in buffer and extend edit range
+                        fPreservedTextBuffer.select(0,0);
+                        fPreservedTextBuffer.replace(replacedText);
+                        fCurrent.fStart= modelStart;
+
+                    } else {
+                        // either DEL or backspace for the first time
+
+                        fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
+                        if (fCurrent.attemptCommit())
+                            fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+                        // as we can not decide whether it was DEL or backspace
+                        // we initialize for backspace
+                        fPreservedTextBuffer.append(replacedText);
+                        fCurrent.fStart= modelStart;
+                        fCurrent.fEnd= modelEnd;
+                    }
+
+                    fPreviousDelete.set(modelStart, modelEnd);
+
+                } else if (length > 0) {
+                    // whereby selection is not empty
+                    fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
+                    if (fCurrent.attemptCommit())
+                        fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+                    fCurrent.fStart= modelStart;
+                    fCurrent.fEnd= modelEnd;
+                    fPreservedTextBuffer.append(replacedText);
+                }
+            } else {
+                // text will be replaced
+
+                if (length is 1) {
+                    length= replacedText.length;
+                    String[] delimiters= fDocument.getLegalLineDelimiters();
+
+                    if ((length is 1)
+                            || TextUtilities.equals(delimiters, replacedText) > -1) {
+                        // because of overwrite mode or model manipulation
+                        if (!fOverwriting
+                                || (modelStart !is fCurrent.fStart
+                                        + fTextBuffer.length())) {
+                            fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
+                            if (fCurrent.attemptCommit())
+                                fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+                            fOverwriting= true;
+                        }
+
+                        if (fCurrent.fStart < 0)
+                            fCurrent.fStart= modelStart;
+
+                        fCurrent.fEnd= modelEnd;
+                        fTextBuffer.append(insertedText);
+                        fPreservedTextBuffer.append(replacedText);
+                        fCurrent.fRedoModificationStamp= afterChangeModificationStamp;
+                        return;
+                    }
+                }
+                // because of typing or pasting whereby selection is not empty
+                fCurrent.fRedoModificationStamp= beforeChangeModificationStamp;
+                if (fCurrent.attemptCommit())
+                    fCurrent.fUndoModificationStamp= beforeChangeModificationStamp;
+
+                fCurrent.fStart= modelStart;
+                fCurrent.fEnd= modelEnd;
+                fTextBuffer.append(insertedText);
+                fPreservedTextBuffer.append(replacedText);
+            }
+        }
+        // in all cases, the redo modification stamp is updated on the open
+        // text edit
+        fCurrent.fRedoModificationStamp= afterChangeModificationStamp;
+    }
+
+    /**
+     * Initialize the receiver.
+     */
+    private void initialize() {
+        initializeUndoHistory();
+
+        // open up the current text edit
+        fCurrent= new UndoableTextChange(this);
+        fPreviousDelete= new UndoableTextChange(this);
+        fTextBuffer= new StringBuffer();
+        fPreservedTextBuffer= new StringBuffer();
+
+        addListeners();
+    }
+
+    /**
+     * Reset processChange state.
+     *
+     * @since 3.2
+     */
+    private void resetProcessChangeState() {
+        fInserting= false;
+        fOverwriting= false;
+        fPreviousDelete.reinitialize();
+    }
+
+    /**
+     * Shutdown the receiver.
+     */
+    private void shutdown() {
+        removeListeners();
+
+        fCurrent= null;
+        fPreviousDelete= null;
+        fTextBuffer.clear();
+        fPreservedTextBuffer.clear();
+
+        disposeUndoHistory();
+    }
+
+    /**
+     * Return whether or not any clients are connected to the receiver.
+     *
+     * @return <code>true</code> if the receiver is connected to
+     *          clients, <code>false</code> if it is not
+     */
+    bool isConnected() {
+        if (fConnected is null)
+            return false;
+        return !fConnected.isEmpty();
+    }
+
+    /*
+     * @see dwtx.jface.text.IDocumentUndoManager#transferUndoHistory(IDocumentUndoManager)
+     */
+    public void transferUndoHistory(IDocumentUndoManager manager) {
+        IUndoContext oldUndoContext= manager.getUndoContext();
+        // Get the history for the old undo context.
+        IUndoableOperation [] operations= OperationHistoryFactory.getOperationHistory().getUndoHistory(oldUndoContext);
+        for (int i= 0; i < operations.length; i++) {
+            // First replace the undo context
+            IUndoableOperation op= operations[i];
+            if (cast(IContextReplacingOperation)op ) {
+                (cast(IContextReplacingOperation)op).replaceContext(oldUndoContext, getUndoContext());
+            } else {
+                op.addContext(getUndoContext());
+                op.removeContext(oldUndoContext);
+            }
+            // Now update the manager that owns the text edit.
+            if (cast(UndoableTextChange)op ) {
+                (cast(UndoableTextChange)op).fDocumentUndoManager= this;
+            }
+        }
+
+        IUndoableOperation op= OperationHistoryFactory.getOperationHistory().getUndoOperation(getUndoContext());
+        if (op !is null && !(cast(UndoableTextChange)op ))
+            return;
+
+        // Record the transfer itself as an undoable change.
+        // If the transfer results from some open operation, recording this change will
+        // cause our undo context to be added to the outer operation.  If there is no
+        // outer operation, there will be a local change to signify the transfer.
+        // This also serves to synchronize the modification stamps with the documents.
+        UndoableTextChange cmd= new UndoableTextChange(this);
+        cmd.fStart= cmd.fEnd= 0;
+        cmd.fText= cmd.fPreservedText= ""; //$NON-NLS-1$
+        if (cast(IDocumentExtension4)fDocument ) {
+            cmd.fRedoModificationStamp= (cast(IDocumentExtension4)fDocument).getModificationStamp();
+            if (op !is null)
+                cmd.fUndoModificationStamp= (cast(UndoableTextChange)op).fRedoModificationStamp;
+        }
+        addToOperationHistory(cmd);
+    }
+
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/undo/DocumentUndoManagerRegistry.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,122 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.undo.DocumentUndoManagerRegistry;
+
+import dwtx.text.undo.DocumentUndoManager; // packageimport
+import dwtx.text.undo.DocumentUndoEvent; // packageimport
+import dwtx.text.undo.IDocumentUndoListener; // packageimport
+import dwtx.text.undo.UndoMessages; // packageimport
+import dwtx.text.undo.IDocumentUndoManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.dwtxhelper.Collection;
+
+
+import dwtx.core.runtime.Assert;
+import dwtx.jface.text.IDocument;
+
+
+/**
+ * This document undo manager registry provides access to a document's
+ * undo manager. In order to connect a document a document undo manager
+ * call <code>connect</code>. After that call has successfully completed
+ * undo manager can be obtained via <code>getDocumentUndoManager</code>.
+ * The undo manager is created on the first connect and disposed on the last
+ * disconnect, i.e. this registry keeps track of how often a undo manager is
+ * connected and returns the same undo manager to each client as long as the
+ * document is connected.
+ * <p>
+ * <em>The recoding of changes starts with the first {@link #connect(IDocument)}.</em></p>
+ *
+ * @since 3.2
+ * @noinstantiate This class is not intended to be instantiated by clients.
+ */
+public final class DocumentUndoManagerRegistry {
+
+    private static final class Record {
+        public this(IDocument document) {
+            count= 0;
+            undoManager= new DocumentUndoManager(document);
+        }
+        private int count;
+        private IDocumentUndoManager undoManager;
+    }
+
+    private static Map fgFactory_;
+    private static Map fgFactory(){
+        if( fgFactory_ is null ) fgFactory_ = new HashMap();
+        return fgFactory_;
+    }
+
+    private this() {
+        //  Do not instantiate
+    }
+
+
+    /**
+     * Connects the file at the given location to this manager. After that call
+     * successfully completed it is guaranteed that each call to <code>getFileBuffer</code>
+     * returns the same file buffer until <code>disconnect</code> is called.
+     * <p>
+     * <em>The recoding of changes starts with the first {@link #connect(IDocument)}.</em></p>
+     *
+     * @param document the document to be connected
+     */
+    public static synchronized void connect(IDocument document) {
+        Assert.isNotNull(cast(Object)document);
+        Record record= cast(Record)fgFactory.get(cast(Object)document);
+        if (record is null) {
+            record= new Record(document);
+            fgFactory.put(cast(Object)document, record);
+        }
+        record.count++;
+    }
+
+    /**
+     * Disconnects the given document from this registry.
+     *
+     * @param document the document to be disconnected
+     */
+    public static synchronized void disconnect(IDocument document) {
+        Assert.isNotNull(cast(Object)document);
+        Record record= cast(Record)fgFactory.get(cast(Object)document);
+        record.count--;
+        if (record.count is 0)
+            fgFactory.remove(cast(Object)document);
+
+    }
+
+    /**
+     * Returns the file buffer managed for the given location or <code>null</code>
+     * if there is no such file buffer.
+     * <p>
+     * The provided location is either a full path of a workspace resource or
+     * an absolute path in the local file system. The file buffer manager does
+     * not resolve the location of workspace resources in the case of linked
+     * resources.
+     * </p>
+     *
+     * @param document the document for which to get its undo manager
+     * @return the document undo manager or <code>null</code>
+     */
+    public static synchronized IDocumentUndoManager getDocumentUndoManager(IDocument document) {
+        Assert.isNotNull(cast(Object)document);
+        Record record= cast(Record)fgFactory.get(cast(Object)document);
+        if (record is null)
+            return null;
+        return record.undoManager;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/undo/IDocumentUndoListener.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.undo.IDocumentUndoListener;
+
+import dwtx.text.undo.DocumentUndoEvent; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+
+/**
+ * This interface is used to listen to notifications from a DocumentUndoManager.
+ * The supplied DocumentUndoEvent describes the particular notification.
+ * <p>
+ * Document undo listeners must be prepared to receive notifications from a
+ * background thread. Any UI access occurring inside the implementation must be
+ * properly synchronized using the techniques specified by the client's widget
+ * library.</p>
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ *
+ * @since 3.2
+ */
+public interface IDocumentUndoListener {
+
+    /**
+     * The document is involved in an undo-related change.  Notify listeners
+     * with an event describing the change.
+     *
+     * @param event the document undo event that describes the particular notification
+     */
+    void documentUndoNotification(DocumentUndoEvent event);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/undo/IDocumentUndoManager.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,181 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.undo.IDocumentUndoManager;
+
+// import dwtx.text.undo.DocumentUndoManager; // packageimport
+// import dwtx.text.undo.DocumentUndoManagerRegistry; // packageimport
+import dwtx.text.undo.DocumentUndoEvent; // packageimport
+import dwtx.text.undo.IDocumentUndoListener; // packageimport
+// import dwtx.text.undo.UndoMessages; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwtx.core.commands.ExecutionException;
+import dwtx.core.commands.operations.IUndoContext;
+
+/**
+ * Interface for a document undo manager. Tracks changes in a document and
+ * builds a history of text commands that describe the undoable changes to the
+ * document.
+ * <p>
+ * Clients must explicitly connect to the undo manager to express their interest
+ * in the undo history. Clients should disconnect from the undo manager when
+ * they are no longer interested in tracking the undo history. If there are no
+ * clients connected to the undo manager, it will not track the document's
+ * changes and will dispose of any history that was previously kept.</p>
+ * <p>
+ * Clients may also listen to the undo manager for notifications before and
+ * after undo or redo events are performed. Clients must connect to the undo
+ * manager in addition to registering listeners.</p>
+ * <p>
+ * Clients may implement this interface.
+ * </p>
+ *
+ * @see DocumentUndoManagerRegistry
+ * @see IDocumentUndoListener
+ * @see dwtx.jface.text.IDocument
+ * @since 3.2
+ */
+public interface IDocumentUndoManager {
+
+    /**
+     * Adds the specified listener to the list of document undo listeners that
+     * are notified before and after changes are undone or redone in the
+     * document. This method has no effect if the instance being added is
+     * already in the list.
+     * <p>
+     * Notifications will not be received if there are no clients connected to
+     * the receiver. Registering a document undo listener does not implicitly
+     * connect the listener to the receiver.</p>
+     * <p>
+     * Document undo listeners must be prepared to receive notifications from a
+     * background thread. Any UI access occurring inside the implementation must
+     * be properly synchronized using the techniques specified by the client's
+     * widget library.</p>
+     *
+     * @param listener the document undo listener to be added as a listener
+     */
+    void addDocumentUndoListener(IDocumentUndoListener listener);
+
+    /**
+     * Removes the specified listener from the list of document undo listeners.
+     * <p>
+     * Removing a listener which is not registered has no effect
+     * </p>
+     *
+     * @param listener the document undo listener to be removed
+     */
+    void removeDocumentUndoListener(IDocumentUndoListener listener);
+
+    /**
+     * Returns the undo context registered for this document
+     *
+     * @return the undo context registered for this document
+     */
+    IUndoContext getUndoContext();
+
+    /**
+     * Closes the currently open text edit and open a new one.
+     */
+    void commit();
+
+    /**
+     * Connects to the undo manager. Used to signify that a client is monitoring
+     * the history kept by the undo manager. This message has no effect if the
+     * client is already connected.
+     *
+     * @param client the object connecting to the undo manager
+     */
+    void connect(Object client);
+
+    /**
+     * Disconnects from the undo manager. Used to signify that a client is no
+     * longer monitoring the history kept by the undo manager. If all clients
+     * have disconnected from the undo manager, the undo history will be
+     * deleted.
+     *
+     * @param client the object disconnecting from the undo manager
+     */
+    void disconnect(Object client);
+
+    /**
+     * Signals the undo manager that all subsequent changes until
+     * <code>endCompoundChange</code> is called are to be undone in one piece.
+     */
+    void beginCompoundChange();
+
+    /**
+     * Signals the undo manager that the sequence of changes which started with
+     * <code>beginCompoundChange</code> has been finished. All subsequent
+     * changes are considered to be individually undo-able.
+     */
+    void endCompoundChange();
+
+    /**
+     * Sets the limit of the undo history to the specified value. The provided
+     * limit will supersede any previously set limit.
+     *
+     * @param undoLimit the length of this undo manager's history
+     */
+    void setMaximalUndoLevel(int undoLimit);
+
+    /**
+     * Resets the history of the undo manager. After that call,
+     * there aren't any undo-able or redo-able text changes.
+     */
+    void reset();
+
+    /**
+     * Returns whether at least one text change can be rolled back.
+     *
+     * @return <code>true</code> if at least one text change can be rolled back
+     */
+    bool undoable();
+
+    /**
+     * Returns whether at least one text change can be repeated. A text change
+     * can be repeated only if it was executed and rolled back.
+     *
+     * @return <code>true</code> if at least on text change can be repeated
+     */
+    bool redoable();
+
+    /**
+     * Rolls back the most recently executed text change.
+     *
+     * @throws ExecutionException if an exception occurred during undo
+     */
+    void undo() ;
+
+    /**
+     * Repeats the most recently rolled back text change.
+     *
+     * @throws ExecutionException if an exception occurred during redo
+     */
+    void redo() ;
+
+    /**
+     * Transfers the undo history from the specified document undo manager to
+     * this undo manager.  This message should only be used when it is known
+     * that the content of the document of the original undo manager when the
+     * last undo operation was recorded is the same as this undo manager's
+     * current document content, since the undo history is based on document
+     * indexes.  It is the responsibility of the caller
+     * to ensure that this call is used correctly.
+     *
+     * @param manager the document undo manger whose history is to be transferred to the receiver
+     */
+    public void transferUndoHistory(IDocumentUndoManager manager);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/undo/UndoMessages.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ * Port to the D programming language:
+ *     Frank Benoit <benoit@tionex.de>
+ *******************************************************************************/
+module dwtx.text.undo.UndoMessages;
+
+import dwtx.text.undo.DocumentUndoManager; // packageimport
+import dwtx.text.undo.DocumentUndoManagerRegistry; // packageimport
+import dwtx.text.undo.DocumentUndoEvent; // packageimport
+import dwtx.text.undo.IDocumentUndoListener; // packageimport
+import dwtx.text.undo.IDocumentUndoManager; // packageimport
+
+
+import dwt.dwthelper.utils;
+
+import dwt.dwthelper.ResourceBundle;
+import dwtx.dwtxhelper.MessageFormat;
+
+/**
+ * Helper class to get NLSed messages.
+ *
+ * @since 3.2
+ */
+final class UndoMessages {
+
+//     private static const String BUNDLE_NAME= "dwtx.text.undo.UndoMessages"; //$NON-NLS-1$
+
+    private static const ResourceBundle RESOURCE_BUNDLE;//= ResourceBundle.getBundle(BUNDLE_NAME);
+
+    static this() {
+        RESOURCE_BUNDLE = ResourceBundle.getBundle(
+            getImportData!("dwtx.text.undo.UndoMessages.properties"));
+    }
+
+    private this() {
+    }
+
+    public static String getString(String key) {
+        try {
+            return RESOURCE_BUNDLE.getString(key);
+        } catch (MissingResourceException e) {
+            return '!' ~ key ~ '!';
+        }
+    }
+
+    public static String getFormattedString(String key, Object[] args...) {
+        return MessageFormat.format(getString(key), args);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/dwtx/text/undo/UndoMessages.properties	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2006 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+DocumentUndoManager.operationLabel= Typing
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fixmodule.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,87 @@
+module packageimport;
+
+import tango.io.FilePath;
+import tango.io.File;
+import tango.io.Buffer;
+import tango.io.stream.FileStream;
+import tango.io.stream.TextFileStream;
+import tango.util.log.Trace;
+import tango.text.Regex;
+import tango.text.Util;
+import tango.text.stream.LineIterator;
+import tango.text.convert.Format;
+
+void processDir( char[] dir ){
+    auto pack = dir.dup.replace( '/', '.' );
+    auto fp = FilePath(dir);
+    char[][] mods;
+    // read all module names
+    foreach( fileinfo; fp ){
+        if( fileinfo.folder ){
+            processDir( fileinfo.path ~ fileinfo.name );
+            continue;
+        }
+        if( fileinfo.name.length > 2 && fileinfo.name[ $-2 .. $ ] == ".d" ){
+            mods ~= fileinfo.name.dup;
+        }
+    }
+    // foreach module
+    foreach( mod; mods ){
+        auto filename = Format("{}/{}", dir, mod );
+        auto cont = cast(char[])File( filename ).read;
+        char[][] lines = cont.splitLines();
+        int modLine = -1;
+        foreach( uint idx, char[] line; lines ){
+            if( line.length && line.locatePattern( "module dwtx" ) is 0 ){
+        //Trace.formatln( "mod: {} {}", idx, line );
+                modLine = idx;
+                break;
+            }
+        }
+        int impLine = -1;
+        foreach( uint idx, char[] line; lines ){
+            if( line.length && line.locatePattern( "import dwtx" ) is 0 ){
+        //Trace.formatln( "imp: {} {}", idx, line );
+                impLine = idx;
+                break;
+            }
+        }
+        assert( modLine !is -1 );
+        assert( impLine !is -1 );
+        if( modLine > impLine ){
+            Trace.formatln( "{} {} {} {}", filename, modLine, impLine, lines.length );
+            auto moddecl = lines[ modLine .. modLine + 2 ].dup;
+            for( int i = modLine; i >= impLine+1; i-- ){
+                lines[i+1] = lines[i-1];
+            }
+            lines[ impLine .. impLine+2 ] = moddecl;
+            auto output = new TextFileOutput( filename );
+            bool first = true;
+            foreach( line; lines ){
+                if( !first ){
+                    output.write( \n );
+                }
+                first = false;
+                output.write( line );
+            }
+            output.flush();
+            output.close();
+        }
+    }
+        // read content into buffer
+        // search module statement and print to outfile
+        // write package imports
+        // write all remaining lines
+}
+
+void main(){
+    processDir( "dwtx/text" );
+    processDir( "dwtx/jface/text" );
+    processDir( "dwtx/jface/internal/text" );
+}
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/packageimport.d	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,82 @@
+module packageimport;
+
+import tango.io.FilePath;
+import tango.io.File;
+import tango.io.Buffer;
+import tango.io.stream.FileStream;
+import tango.io.stream.TextFileStream;
+import tango.util.log.Trace;
+import tango.text.Regex;
+import tango.text.Util;
+import tango.text.stream.LineIterator;
+import tango.text.convert.Format;
+
+void processDir( char[] dir ){
+    auto pack = dir.dup.replace( '/', '.' );
+    auto fp = FilePath(dir);
+    char[][] mods;
+    // read all module names
+    foreach( fileinfo; fp ){
+        if( fileinfo.folder ){
+            processDir( fileinfo.path ~ fileinfo.name );
+            continue;
+        }
+        if( fileinfo.name.length > 2 && fileinfo.name[ $-2 .. $ ] == ".d" ){
+            mods ~= fileinfo.name.dup;
+        }
+    }
+    // foreach module
+    foreach( mod; mods ){
+        auto filename = Format("{}/{}", dir, mod );
+        Trace.formatln( "{}", filename );
+        auto cont = cast(char[])File( filename ).read;
+        auto output = new TextFileOutput( filename );
+        bool firstline = true;
+        void println( char[] l ){
+            if( !firstline ){
+                output.newline();
+            }
+            output(l);
+            firstline = false;
+        }
+        bool found = false;
+        auto it = new LineIterator!(char)( new Buffer( cont ));
+        foreach( line; it ){
+            println(line);
+            if( line.length && line.locatePattern( "module " ) is 0 ){
+                found = true;
+                break;
+            }
+        }
+        assert( found );
+        println( "" );
+        foreach( impmod; mods ){
+            if( impmod == mod ){
+                continue;
+            }
+            println( Format( "import {}.{}; // packageimport", pack, impmod[ 0 .. $-2] ));
+        }
+        println( "" );
+        foreach( line; it ){
+            println(line);
+        }
+        output.flush();
+        output.close();
+    }
+        // read content into buffer
+        // search module statement and print to outfile
+        // write package imports
+        // write all remaining lines
+}
+
+void main(){
+    processDir( "dwtx/text" );
+    processDir( "dwtx/jface/text" );
+    processDir( "dwtx/jface/internal/text" );
+}
+
+
+
+
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/dwtx.jface.internal.text.html.HTMLMessages.properties	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2006 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+
+HTMLTextPresenter.ellipse= ...
+
+# The following property value must end with a space
+HTML2TextReader.listItemPrefix=\t-\ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/dwtx.jface.internal.text.link.contentassist.ContentAssistMessages.properties	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,20 @@
+###############################################################################
+# Copyright (c) 2000, 2005 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+
+InfoPopup.info_delay_timer_name=AdditionalInfo Delay
+
+ContentAssistant.assist_delay_timer_name=AutoAssist Delay
+
+HTMLTextPresenter.ellipse= ...
+
+# The following property value must end with a space
+HTML2TextReader.listItemPrefix=\t-\ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/dwtx.jface.text.JFaceTextMessages.properties	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,45 @@
+###############################################################################
+# Copyright (c) 2000, 2007 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+
+TextViewer.error.bad_location.WidgetCommand.setEvent= TextViewer.WidgetCommand.setEvent: BadLocationException
+TextViewer.error.bad_location.findAndSelect= TextViewer.findAndSelect: BadLocationException
+TextViewer.error.bad_location.getBottomIndex= TextViewer.getBottomIndex: BadLocationException
+TextViewer.error.bad_location.getBottomIndexEndOffset= TextViewer.getBottomIndexEndOffset: BadLocationException
+TextViewer.error.bad_location.getFirstCompleteLineOfRegion= TextViewer.getFirstCompleteLineOfRegion: BadLocationException
+TextViewer.error.bad_location.getTopIndex= TextViewer.getTopIndex: BadLocationException
+TextViewer.error.bad_location.getTopIndexStartOffset= TextViewer.getTopIndexStartOffset: BadLocationException
+TextViewer.error.bad_location.selectContentTypePlugin= TextViewer.selectContentTypePlugin: BadLocationException
+TextViewer.error.bad_location.setTopIndex_1= TextViewer.setTopIndex: BadLocationException
+TextViewer.error.bad_location.setTopIndex_2= TextViewer.setTopIndex: BadLocationException
+TextViewer.error.bad_location.shift_1= TextViewer.shift: BadLocationException
+TextViewer.error.bad_location.shift_2= TextViewer.shift: BadLocationException
+TextViewer.error.bad_location.verifyText= TextViewer.verifyText: BadLocationException
+TextViewer.error.invalid_range= Invalid range argument
+TextViewer.error.invalid_visible_region_1= Invalid visible region argument
+TextViewer.error.invalid_visible_region_2= Invalid visible region argument
+
+AbstractHoverInformationControlManager.hover.restarter= Hover Restart Delay
+
+# The first parameter is the annotation type label and the second is the number of annotations
+OverviewRulerHeader.toolTipTextEntry= {0}: {1}
+
+DefaultUndoManager.operationLabel= Typing
+DefaultUndoManager.error.undoFailed.title= Undo Failed
+DefaultUndoManager.error.redoFailed.title= Redo Failed
+
+DefaultAnnotationHover.multipleMarkers= Multiple markers at this line
+# The parameter is the text of the list item
+DefaultAnnotationHover.listItem= - {0}
+
+# The parameter is the line number
+DefaultAnnotationHover.lineNumber=Line: {0}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/dwtx.jface.text.RegExMessages.properties	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,535 @@
+###############################################################################
+# Copyright (c) 2008 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+#     Cagatay Calli <ccalli@gmail.com> - [find/replace] retain caps when replacing - https://bugs.eclipse.org/bugs/show_bug.cgi?id=28949
+#     Cagatay Calli <ccalli@gmail.com> - [find/replace] define & fix behavior of retain caps with other escapes and text before \C - https://bugs.eclipse.org/bugs/show_bug.cgi?id=217061
+###############################################################################
+
+## Content Assist for regular expressions ##
+# use \\\u0075 for a backslash-u
+displayString_bs_bs= \\\\ - Backslash
+additionalInfo_bs_bs= Backslash
+displayString_bs_0= \\0nnn - Octal character code
+additionalInfo_bs_0= Octal character code\n\nExamples:\n\\011 (tabulator)\n\\0112 (character J)
+displayString_bs_x= \\xhh - Hex character code
+additionalInfo_bs_x= Hexadecimal character code\n\nExamples:\n\\x09 (tabulator)\n\\x4A or \\x4a (character J)
+displayString_bs_u= \\\u0075hhhh - Hex code for Unicode character
+additionalInfo_bs_u= Hexadecimal code for Unicode character\n\nExamples:\n\\\u0075004A (character J)\n\\\u007503B2 (lowercase Greek letter beta: \u03B2)
+displayString_bs_t= \\t - Tab
+additionalInfo_bs_t= Tabulator (\\x09, decimal: 9)
+displayString_bs_R= \\R - Line delimiter (platform independent)
+additionalInfo_bs_R= Line delimiter (platform independent)\n\n\
+This pattern matches any form of line delimiter, i.e.\n\
+- Windows (\\r\\n)\n\
+- Unix (\\n)\n\
+- Mac OS 9 (\\r)\n\n\
+Note that this pattern does not work inside [].
+displayString_bs_n= \\n - Newline
+additionalInfo_bs_n= Newline (\\x0A, decimal: 10)\n\n\
+WARNING: \\n only finds newline characters. \
+This can lead to unexpected results when the actual document uses different line delimiters.\n\n\
+RECOMMENDATION: use \\R to find a line delimiter.
+displayString_bs_r= \\r - CR
+additionalInfo_bs_r= Carriage Return (\\x0D, decimal: 13)\n\n\
+WARNING: \\r only finds carriage return characters. \
+This can lead to unexpected results when the actual document uses different line delimiters.\n\n\
+RECOMMENDATION: use \\R to find a line delimiter.
+displayString_bs_f= \\f - FF
+additionalInfo_bs_f= Form Feed (\\x0C, decimal: 12)
+displayString_bs_a= \\a - Beep
+additionalInfo_bs_a= Beep, Bell, Alert (\\x07, decimal: 7)
+displayString_bs_e= \\e - Esc
+additionalInfo_bs_e= Escape (\\x1B, decimal: 27)
+displayString_bs_c= \\cC - Control character
+additionalInfo_bs_c= Control character for C\n\nExample:\n\\cC (Ctrl+C, \\x03, decimal: 3)
+
+displayString_dot= . - Any character
+additionalInfo_dot= The dot matches any character except line terminators.\n\n\
+To make the dot match line terminators as well, \n\
+start the expression with the embedded flag expression \n\
+"(?s)" (without quotes).
+displayString_bs_d= \\d - A digit
+additionalInfo_bs_d= A digit: [0-9]
+displayString_bs_D= \\D - Not a digit
+additionalInfo_bs_D= Not a digit: [^0-9]
+displayString_bs_s= \\s - A whitespace
+additionalInfo_bs_s= A whitespace: [ \\t\\n\\x0B\\f\\r]
+displayString_bs_S= \\S - Not a whitespace
+additionalInfo_bs_S= Not a whitespace: [^\\s]
+displayString_bs_w= \\w - An alphanumeric (word character)
+additionalInfo_bs_w= An alphanumeric (a word character): [a-zA-Z_0-9]
+displayString_bs_W= \\W - Not an alphanumeric
+additionalInfo_bs_W= Not an alphanumeric (not a word character): [^\\w]
+
+displayString_start= ^ - Line start
+additionalInfo_start= Line start (positional match)\n\nExample:\n\
+The expression "^Eclipse" matches the term "Eclipse"\n\
+only on the second line of text\n\
+"The Eclipse Project\n\
+Eclipse Platform".
+displayString_end= $ - Line end
+additionalInfo_end= Line end (positional match)\n\nExample:\n\
+The expression "Eclipse$" matches the term "Eclipse"\n\
+only on the second line of text\n\
+"- Install the Eclipse Platform\n\
+- Run Eclipse".
+displayString_bs_b= \\b- Word beginning or end
+additionalInfo_bs_b= Word beginning or end (positional match)\n\nExample:\n\
+The expression "s\\b" matches only the last "s" of "glasses" in text\n\
+"I lost my glasses."
+displayString_bs_B= \\B - Not a word beginning or end
+additionalInfo_bs_B= Not a word beginning or end (positional match)\n\nExample:\n\
+The expression "\\BS" matches only "S" of "printString" in text\n\
+"void print(String printString)".
+displayString_bs_A= \\A - Start of input
+additionalInfo_bs_A= Start of input (positional match)\n\nExample:\n\
+The expression "\\ABC" matches only "BC" of "BCD" in text\n\
+"BCD ABC\n\
+BCDEF".
+displayString_bs_G= \\G - Previous match's end
+additionalInfo_bs_G= Previous match's end (positional match)\n\nExample:\n\
+The expression "\\Ga" matches the first and then the second "a" in text\n\
+"aardvark" (when starting from the beginning).
+displayString_bs_Z= \\Z - End of input, does not consider last line terminator
+additionalInfo_bs_Z= End of input, does not consider last line terminator (positional match)\n\n\
+The expression matches at the end of the file, except for when the\n\
+file ends in a line terminator, in which case it matches before that\n\
+line terminator.\n\nExample:\n\
+The expression "ing\\Z" matches "ing" in text\n\
+"testing", as well as in text\n\
+"testing\n\
+", but doesn't match in text\n\
+"testing\n\
+\n\
+"
+displayString_bs_z= \\z - End of input
+additionalInfo_bs_z= End of input (positional match)\n\nExample:\n\
+The expression "ing\\z" matches "ing" in text\n\
+"testing", but doesn't match in text\n\
+"testing\n\
+"
+
+### repetition quantifiers ###
+displayString_quest= ? - Greedy match 0 or 1 times
+additionalInfo_quest= Greedy match 0 or 1 times.\n\n\
+First tries to match the preceding token.\n\
+Falls back to not matching if this choice made a full match impossible.\n\nExample:\n\
+The expression "fo?" matches "f", "fo", and "fo" in text\n\
+"f fo foo".
+displayString_star= * - Greedy match 0 or more times
+additionalInfo_star= Greedy match 0 or more times.\n\n\
+First tries to match the preceding token as many times as possible.\n\
+Falls back to matching it less often if this choice made a full match impossible.\n\nExamples:\n\
+- The expression "fo*" matches "f", "fo", and "foo" in text\n\
+"f fo foo".\n\
+- The expression "fo*o\\d" matches all three words in text\n\
+"fo1 foo2 fooo3".\n\
+- The expression "<.*>" matches the whole text\n\
+"<p><b>bold</b>".
+displayString_plus= + - Greedy match 1 or more times
+additionalInfo_plus= Greedy match 1 or more times\n\n\
+First tries to match the preceding token as many times as possible.\n\
+Falls back to matching it less often if this choice made a full match impossible.\n\nExamples:\n\
+- The expression "fo+" matches "fo" and "foo" in text\n\
+"f fo foo".\n\
+- The expression "fo+o\\d" matches "foo2" and "fooo3" in text\n\
+"fo1 foo2 fooo3".\n\
+- The expression "<.+>" matches the whole text\n\
+"<p><b>bold</b>", but does not match anywhere in "<>".
+displayString_exact= {n} - Greedy match exactly n times
+additionalInfo_exact= Greedy match exactly n times.\n\nExamples:\n\
+- The expression "\\\\0[0-3][0-7]{2}" matches all three-digit octal character tokens.\n\
+- The expression "\\b\\w{4}\\b" matches all four-letter-words\n\
+such as "Java", "cool", or "food" (but not "dog").
+displayString_least= {n,} - Greedy match >= n times
+additionalInfo_least= Greedy match >= n times.\n\n\
+First tries to match the preceding token as many times as possible.\n\
+Falls back to matching it less often (but at least n times),\n\
+if this choice made a full match impossible.\n\nExamples:\n\
+- The expression "fo{2,}" matches "foo" and "fooo" in text\n\
+"f fo foo fooo".\n\
+- The expression "fo{2,}o\\d" matches "fooo3" and "foooo4" in text\n\
+"fo1 foo2 fooo3 foooo4".\n\
+- The expression "10{3,}[^0]" matches all powers of ten that are larger than one thousand.\n\n\
+Note: The expressions "{0,}" and "*" are equivalent;\n\
+likewise, "{1,}" is equivalent to "+".
+displayString_count= {n,m} - Greedy match >= n times but <= m times
+additionalInfo_count= Greedy match >= n times but <= m times.\n\n\
+First tries to match the preceding token m times.\n\
+Falls back to matching it less often (but at least n times),\n\
+if this choice made a full match impossible.\n\nExamples:\n\
+- The expression "fo{1,2}" matches "fo", "foo", and "foo" in text\n\
+"f fo foo fooo".\n\
+- The expression "fo{1,2}o\\d" matches "foo2" and "fooo3" in text\n\
+"fo1 foo2 fooo3 foooo4".\n\
+- The expression "^.{70,80}$" matches all the lines that contain\n\
+between 70 and 80 characters (inclusive).
+
+displayString_questLazy= ?? - Lazy match 0 or 1 times
+additionalInfo_questLazy= Lazy match 0 or 1 times.\n\n\
+First tries to not match the preceding token.\n\
+Falls back to matching it if this choice made a full match impossible.\n\nExample:\n\
+The expression "fo??" matches "f", "f", and "f" in text\n\
+"f fo foo".
+displayString_starLazy= *? - Lazy match 0 or more times
+additionalInfo_starLazy= Lazy match 0 or more times.\n\n\
+First tries to not match the preceding token.\n\
+Falls back to matching it more often if this choice made a full match impossible.\n\nExamples:\n\
+- The expression "fo*?" matches "f", "f", and "f" in text\n\
+"f fo foo".\n\
+- The expression "fo*?o\\d" matches all three words in text\n\
+"fo1 foo2 fooo3".\n\
+- The expression "<.*?>" matches "<p>", "<b>", and "</b>" in text\n\
+"<p><b>bold</b>". Note: a more performant expression for finding\n\
+xml tags is "<[^>]*>", which avoids backtracking.
+displayString_plusLazy= +? - Lazy match 1 or more times
+additionalInfo_plusLazy= Lazy match 1 or more times\n\n\
+First tries to match the preceding token once.\n\
+Falls back to matching it more often if this choice made a full match impossible.\n\nExamples:\n\
+- The expression "fo+?" matches "fo" and "fo" in text\n\
+"f fo foo".\n\
+- The expression "fo+?o\\d" matches "foo2" and "fooo3" in text\n\
+"fo1 foo2 fooo3".\n\
+- The expression "<.+?>" matches "<p>", "<b>", and "</b>" in text\n\
+"<p><b>bold</b>". Note: a more performant expression for finding\n\
+xml tags is "<[^>]*>", which avoids backtracking.
+displayString_exactLazy= {n}? - Lazy match exactly n times
+additionalInfo_exactLazy= Lazy match exactly n times.\n\n\
+This expression is equivalent to the expression\n\
+{n} - Greedy match exactly n times.
+displayString_leastLazy= {n,}? - Lazy match >= n times
+additionalInfo_leastLazy= Lazy match >= n times.\n\n\
+First tries to match the preceding token n times. Falls back to\n\
+matching it more often, if this choice made a full match impossible.\n\nExamples:\n\
+- The expression "fo{2,}?" matches "foo" and "foo" in text\n\
+"f fo foo fooo".\n\
+- The expression "fo{2,}?o\\d" matches "fooo3" and "foooo4" in text\n\
+"fo1 foo2 fooo3 foooo4".\n\
+- The expression "10{3,}?[^0]" matches all powers of ten that are larger than one thousand.\n\n\
+Note: The expressions "{0,}?" and "*?" are equivalent;\n\
+likewise, "{1,}?" is equivalent to "+?".
+displayString_countLazy= {n,m}? - Lazy match >= n times but <= m times
+additionalInfo_countLazy= Lazy match >= n times but <= m times.\n\n\
+First tries to match the preceding token n times.\n\
+Falls back to matching it more often (but at most m times),\n\
+if this choice made a full match impossible.\n\nExamples:\n\
+- The expression "fo{1,2}?" matches "fo", "fo", and "fo" in text\n\
+"f fo foo fooo".\n\
+- The expression "fo{1,2}?o\\d" matches "foo2" and "fooo3" in text\n\
+"fo1 foo2 fooo3 foooo4".\n\
+
+displayString_questPoss= ?+ - Possessive match 0 or 1 times (no backtracking)
+additionalInfo_questPoss= Possessive match 0 or 1 times.\n\n\
+Matches the preceding token if possible. Never backtracks,\n\
+even if this choice renders a full match impossible.\n\nExample:\n\
+The expression "fo?+o\\d" matches the first, but not the second line in text\n\
+"foo1\n\
+fo1".
+displayString_starPoss= *+ Possessive match 0 or more times (no backtracking)
+additionalInfo_starPoss= Possessive match 0 or more times.\n\n\
+Tries to match the preceding token as many times as possible. Never backtracks,\n\
+even if this choice renders a full match impossible.\n\nExamples:\n\
+- The expression "fo*+" matches "f", "fo" and "foo" in text\n\
+"f fo foo".\n\
+- The expression "fo*+o\\d" matches nowhere in text\n\
+"fo1 foo2 fooo3".\n\
+- The expression "<.*+>" matches nowhere in text\n\
+"<p><b>bold</b>".
+displayString_plusPoss= ++ - Possessive match 1 or more times (no backtracking)
+additionalInfo_plusPoss= Possessive match 1 or more times.\n\n\
+Tries to match the preceding token as many times as possible. Never backtracks,\n\
+even if this choice renders a full match impossible.\n\nExamples:\n\
+- The expression "fo++" matches "fo" and "foo" in text\n\
+"f fo foo".\n\
+- The expression "fo++o\\d" matches nowhere in text\n\
+"fo1 foo2 fooo3".\n\
+- The expression "<.++>" matches nowhere in text\n\
+"<p><b>bold</b>".
+
+displayString_exactPoss= {n}+ - Possessive match exactly n times (no backtracking)
+additionalInfo_exactPoss= Possessive match exactly n times.\n\n\
+This expression is equivalent to the expression\n\
+{n} - Greedy match exactly n times.
+displayString_leastPoss= {n,}+ - Possessive match >= n times (no backtracking)
+additionalInfo_leastPoss= Possessive match >= n times.\n\n\
+Tries to match the preceding token as many times as possible, but at least n times.\n\
+Never backtracks, even if this choice renders a full match impossible.\n\nExamples:\n\
+- The expression "fo{2,}+" matches "foo" and "fooo" in text\n\
+"f fo foo fooo".\n\
+- The expression "fo{2,}?o\\d" matches nowhere in text\n\
+"fo1 foo2 fooo3 foooo4".\n\
+Note: The expressions "{0,}?" and "*?" are equivalent;\n\
+likewise, "{1,}?" is equivalent to "+?".
+
+displayString_countPoss= {n,m}+ - Possessive match >= n times but <= m times (no backtracking)
+additionalInfo_countPoss= Possessive match >= n times but <= m times.\n\n\
+Tries to match the preceding token as many times as possible, \n\
+at least n times and at most m times.\n\
+Never backtracks, even if this choice renders a full match impossible.\n\nExamples:\n\
+- The expression "fo{1,2}+" matches "fo", "foo", and "foo" in text\n\
+"f fo foo fooo".\n\
+- The expression "fo{1,2}+o\\d" matches only "fooo3" in text\n\
+"fo1 foo2 fooo3 foooo4".\n\
+- The expression "^.{70,80}+$" matches all the lines that contain\n\
+between 70 and 80 characters (inclusive).
+
+displayString_alt= U|V - Alternation: U or V
+additionalInfo_alt= Alternation.\n\n\
+First tries to match subexpression U. Falls back and tries to match V if U didn't match.\n\nExamples:\n\
+- The expression "A|B" applied to text "BA" first matches "B", then "A".\n\
+- The expression "AB|BC|CD" applied to text "ABC BC DAB" matches, in sequence:\n\
+"AB" in the first word, the second word "BC", "AB" at the very end.
+displayString_group= (Expr) - Mark Expr as capturing group
+additionalInfo_group= Mark Expr as capturing group.\n\n\
+Capturing groups are numbered by counting their opening parentheses from left to right.\n\
+In the expression "((A)(B(C)))", for example, there are four such groups:\n\
+1   ((A)(B(C)))\n\
+2   (A)\n\
+3   (B(C))\n\
+4   (C)\n\
+\n\
+Group zero always stands for the entire expression. During a match,\n\
+each subsequence of the input sequence that matches such a group is saved.\n\
+The captured subsequence i may be used later in the expression, via a back reference "\\i",\n\
+and may also be used in the replace string via "$i".\n\
+\n\
+Note: Groups beginning with (? are pure, non-capturing groups that\n\
+do not capture text and do not count towards the group total.
+
+displayString_bs_i= \\i - Match of the capturing group i
+additionalInfo_bs_i= Match of the capturing group i.\n\n\
+\\i matches the subsequence that has already been saved as capturing group i.\n\
+\\0 is not a valid group number in the regular expression.\n\nExample:\n\
+The expression "(\\d+)\\+\\1" matches "10+10" in text "9+10+10+11".\n\
+\n\
+Note: in the replace string, $i stands for the capturing group i. 
+
+displayString_bs= \\ - Quote next character
+additionalInfo_bs= Quote next character\n\nExample:\n\
+The expression "\\{\\n\\}" matches the text "{n}".
+
+displayString_bs_Q= \\Q - Start quoting
+additionalInfo_bs_Q= Start quoting\n\n\
+All characters between \\Q and the next \\E are taken literally and are not interpreted.\n\nExample:\n\
+The expression "\\Qnew int[] {42}\\E;" matches text "new int[] {42}".
+displayString_bs_E= \\E - End quoting
+additionalInfo_bs_E= End quoting\n\n\
+All characters between \\Q and the next \\E are taken literally and are not interpreted.\n\nExample:\n\
+The expression "\\Qnew int[] {42}\\E;" matches text "new int[] {42}".
+
+displayString_set= [ecl] - Character set
+additionalInfo_set= Character set\n\n\
+Matches a single character out of the set.\n\nExample:\n\
+The expression "[ecl]" matches "c" and "l" in text "cold".
+displayString_setExcl= [^ecl] - Excluded character set
+additionalInfo_setExcl= Excluded character set\n\n\
+Matches a single character that is not one of the excluded characters.\n\nExamples:\n\
+The expression "[^ecl]" matches "o" and "d" in text "cold".\n\
+The expression "[a-z&&[^ecl]]" matches any character from a to z, excluding e, c, and l.
+displayString_setRange= [c-l] - Character range
+additionalInfo_setRange= Character range\n\n\
+Matches a single character out of the range from 'c' to 'l'.\n\nExamples:\n\
+The expression "[c-l]" matches "c", "l", and "d" in text "cold".\n\
+The expression "[a-z&&[^ecl]]" matches any character from a to z, excluding e, c, and l.
+displayString_setInter= && - Intersection of character sets
+additionalInfo_setInter= Intersection of character sets\n\n\
+Matches a character that is in both of the given sets.\n\nExample:\n\
+The expression "[a-z&&[^ecl]]" matches any character from a to z, excluding e, c, and l.
+
+displayString_posix= \\p{Class} - POSIX or Unicode character class
+additionalInfo_posix= POSIX or Unicode character class\n\n\
+Matches a character from the given character class 'Class'.\n\
+Valid classes are:\n\
+\n\
+- POSIX character classes (US-ASCII only):\n\
+\    Lower, Upper, ASCII, Alpha, Digit, Alnum, Punct,\n\
+\    Graph, Print, Blank, Cntrl, XDigit, and Space.\n\
+\n\
+- Unicode blocks (with the prefix 'In'), e.g.:\n\
+\    InBasicLatin\n\
+\    InLatin-1Supplement\n\
+\    InGreek\n\
+\n\
+- Unicode categories, e.g.:\n\
+\    Lu: Uppercase Letter\n\
+\    Ll: Lowercase Letter\n\
+\    L:  Letter\n\
+\    N:  Number\n\
+\    Z:  Separator\n\
+\    LD: Letter or Digit\n\
+\    L1: Latin-1
+
+displayString_posixNot= \\P{Class} - Excluded POSIX or Unicode character class
+additionalInfo_posixNot= Excluded POSIX or Unicode character class\n\n\
+Negation of character set \\p{Class}. Example:\n\
+\\P{ASCII} is equivalent to [^\\p{ASCII}] and matches all non-ASCII characters.\n\n\
+Valid classes are:\n\
+\n\
+- POSIX character classes (US-ASCII only):\n\
+\    Lower, Upper, ASCII, Alpha, Digit, Alnum, Punct,\n\
+\    Graph, Print, Blank, Cntrl, XDigit, and Space.\n\
+\n\
+- Unicode blocks (with the prefix 'In'), e.g.:\n\
+\    InBasicLatin\n\
+\    InLatin-1Supplement\n\
+\    InGreek\n\
+\n\
+- Unicode categories, e.g.:\n\
+\    Lu: Uppercase Letter\n\
+\    Ll: Lowercase Letter\n\
+\    L:  Letter\n\
+\    N:  Number\n\
+\    Z:  Separator\n\
+\    LD: Letter or Digit\n\
+\    L1: Latin-1
+
+
+#Flags:
+displayString_flag= (?ismd-ismd) - Turn flags on or off
+additionalInfo_flag= Turn flags on and off for the rest of the matching process.\n\n\
+Flags before the dash are turned on; those after the dash are turned off.\n\
+The following flags are supported:\n\
+- i: case-insensitive matching\n\
+\n\
+- s: single-line, or dotall matching mode:\n\
+\        The expression . matches any character, including a line terminator.\n\
+\n\
+- m: multiline matching mode:\n\
+\        The expressions ^ and $ match just after or just before,\n\
+\        respectively, a line terminator or the end of the input sequence.\n\
+\        When multiline matching is turned off, these expressions only\n\
+\        match at the beginning and the end of the entire input sequence.\n\
+\        This flag is ON by default.\n\
+\n\
+- d: Unix lines matching mode:\n\
+\        Only the '\\n' line terminator\n\
+\        is recognized in the behavior of ., ^, and $
+# - u: unicode-aware case folding:\n\
+#        Case-insensitive matching, when enabled, is done in a manner consistent\n\
+#        with the Unicode Standard. By default, case-insensitive matching\n\
+#        assumes that only characters in the US-ASCII charset are being matched.
+# - c: canonical equivalence\n\
+#        Two characters will be considered to match if, and only if, their full\n\
+#        canonical decompositions match. The expression "a\\\u0075030A", for example,\n\
+#        will match the string "a\u030A" when this flag is specified.\n\
+#        By default, matching does not take canonical equivalence into account.
+# - x: comments mode\n\
+#        Whitespace is ignored, and embedded comments starting with\n\
+#        # are ignored until the end of a line.\n\
+
+displayString_flagExpr= (?ismd-ismd:Expr) - Turn flags on or off in Expr
+additionalInfo_flagExpr= Turn flags on and off in Expr.\n\n\
+Flags before the dash are turned on; those after the dash are turned off.\n\
+The following flags are supported:\n\
+- i: case-insensitive matching\n\
+\n\
+- s: single-line, or dotall matching mode:\n\
+\        The expression . matches any character, including a line terminator.\n\
+\n\
+- m: multiline matching mode:\n\
+\        The expressions ^ and $ match just after or just before,\n\
+\        respectively, a line terminator or the end of the input sequence.\n\
+\        When multiline matching is turned off, these expressions only\n\
+\        match at the beginning and the end of the entire input sequence.\n\
+\        This flag is ON by default.\n\
+\n\
+- d: Unix lines matching mode:\n\
+\        Only the '\\n' line terminator\n\
+\        is recognized in the behavior of ., ^, and $
+
+
+#Noncapturing groups:
+displayString_nonCap= (?:Expr) - Non-capturing group
+additionalInfo_nonCap= Non-capturing group of regular expression Expr.\n\n\
+The group is not saved in a back reference.\n\nExample:\n\
+The expression "(?:\\w+) (\\d+)" matches "bug 42" in text "It's bug 42.".\n\
+A back reference "$1" in the replace string will be replaced by "42".
+
+displayString_atomicCap= (?>Expr) - Non-capturing atomic group
+additionalInfo_atomicCap= Non-capturing atomic group of regular expression Expr.\n\n\
+Matches the regular expression Expr once, but does not backtrack into the expression\n\
+again if the first match did not prove to be successful later on.\n\
+The group is not saved in a back reference.
+
+#Lookaround:
+displayString_posLookahead= (?=Expr) - Zero-width positive lookahead
+additionalInfo_posLookahead= Expr, via zero-width positive lookahead.\n\n\
+Matches a position (zero-width: does not consume the matched characters),\n\
+where the next characters (-> lookahead)\n\
+do match (-> positive) the embedded expression Expr.\n\nExamples:\n\
+- The expression "var(?==)" matches only the first "var" in text "var=17; other=var;".\n\
+- The expression "\\b(?=\\w{7}\\b)\\w*clip\\w*\\b" matches any\n\
+seven-letter-word that contains "clip". It matches "Eclipse", but not "paperclip".
+
+displayString_negLookahead= (?!Expr) - Zero-width negative lookahead
+additionalInfo_negLookahead= Expr, via zero-width negative lookahead.\n\n\
+Matches a position (zero-width: does not consume the matched characters),\n\
+where the next characters (-> lookahead)\n\
+do not match (-> negative) the embedded expression Expr.\n\nExamples:\n\
+- The expression "var(?!=)" matches only the second "var" in text "var=17; other=var;".\n\
+- The expression "\\b(?!\\w{5,7}\\b)\\w*clip\\w*\\b" matches any\n\
+word that contains "clip" and consists of less than 5 or more than 7 characters.\n\
+It matches "clip" and "paperclip", but not "Eclipse".
+
+displayString_posLookbehind= (?<=Expr) - Zero-width positive lookbehind
+additionalInfo_posLookbehind= Expr, via zero-width positive lookbehind.\n\n\
+Matches a position (zero-width: does not consume the matched characters),\n\
+where the previous characters (-> lookbehind)\n\
+do match (-> positive) the embedded expression Expr.\n\nExample:\n\
+- The expression "\\w{5,}+(?<=as)\\b" matches "alias" and "bananas",\n\
+but does not match "peas", "apples", or "Alaska".
+
+displayString_negLookbehind= (?<!Expr) - Zero-width negative lookbehind
+additionalInfo_negLookbehind= Expr, via zero-width negative lookbehind.\n\n\
+Matches a position (zero-width: does not consume the matched characters),\n\
+where the previous characters (-> lookbehind)\n\
+do not match (-> negative) the embedded expression Expr.\n\nExample:\n\
+- The expression "\\w{5,}+(?<!as)\\b" matches "Eclipse" and "apples",\n\
+but does not match "peas" or "bananas".
+
+#Replace string:
+displayString_dollar= $i - Match of the capturing group i
+additionalInfo_dollar= Match of the capturing group i.\n\n\
+$i is the string that has been saved as capturing group i.\n\
+$0 is the subsequence matched by the entire expression.\n\
+\n\
+Note: in the find expression, \\i stands for the capturing group i. 
+displayString_replace_cap= \\i - Match of the capturing group i
+additionalInfo_replace_cap= Match of the capturing group i.\n\n\
+\\i is the string that has been saved as capturing group i.\n\
+\\0 is the subsequence matched by the entire expression.\n\
+\n\
+Note: \\i is equivalent to $i 
+displayString_replace_bs= \\ - Quote next character
+additionalInfo_replace_bs= Quote next character\n\nExamples:\n\
+"\\$" will be replaced by "$".\n\
+"\\q" will be replaced by "q".\n\
+"\\\\" will be replaced by "\\".
+displayString_replace_bs_n= \\n - Newline
+additionalInfo_replace_bs_n= Newline (\\x0A, decimal: 10)\n\n\
+Note that \\n always inserts the newline character,\n\
+even if the document uses different line delimiters.\n\n\
+To insert the document line delimiter, use \\R.
+displayString_replace_bs_r= \\r - CR
+additionalInfo_replace_bs_r= Carriage Return (\\x0D, decimal: 13)\n\n\
+Note that \\r always inserts the carriage return character,\n\
+even if the document uses different line delimiters.\n\n\
+To insert the document line delimiter, use \\R.
+displayString_replace_bs_R= \\R - Line delimiter
+additionalInfo_replace_bs_R= Line delimiter\n\n\
+Inserts the default line delimiter of the document.
+displayString_replace_bs_C=\\C - Retain case
+additionalInfo_replace_bs_C=\\C - Retain casing of match (all lower case, all upper case, capitalized)\n\
+when replacing expression after \\C.\n\nExamples:\n\
+Find: "foo" Replace: "my\\Cbar\\CFar"\n\
+"foo" will be replaced by "mybarfar".\n\
+"FOO" will be replaced by "myBARFAR".\n\
+"Foo" will be replaced by "myBarFar".\n\n\
+Note that the content of a group ($i, \\i) is currently inserted unmodified.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/dwtx.jface.text.TextMessages.properties	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2008 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+FindReplaceDocumentAdapter.illegalControlEscape= Illegal control escape sequence {0}
+FindReplaceDocumentAdapter.illegalHexEscape= Illegal hexadecimal escape sequence {0}
+FindReplaceDocumentAdapter.illegalLinebreak=Illegal position for \\R
+FindReplaceDocumentAdapter.illegalUnicodeEscape= Illegal Unicode escape sequence {0}
+FindReplaceDocumentAdapter.incompatibleLineDelimiter= Incompatible line delimiter
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/dwtx.jface.text.contentassist.JFaceTextMessages.properties	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,17 @@
+###############################################################################
+# Copyright (c) 2000, 2006 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+
+InfoPopup.info_delay_timer_name=Additional info timer
+AdditionalInfoController.job_name=Computing additional info
+
+ContentAssistant.assist_delay_timer_name=AutoAssist Delay
+CompletionProposalPopup.no_proposals=no proposals
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/dwtx.jface.text.hyperlink.HyperlinkMessages.properties	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,16 @@
+###############################################################################
+# Copyright (c) 2008 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+LinkListInformationControl.unknownLink= Unknown Hyperlink
+
+MultipleHyperlinkPresenter.clickLinkAfordance =Click link to open
+
+URLHyperlink.hyperlinkText= Open ''{0}'' in a browser
Binary file res/dwtx.jface.text.source.projection.collapsed.gif has changed
Binary file res/dwtx.jface.text.source.projection.expanded.gif has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/dwtx.jface.text.templates.JFaceTextTemplateMessages.properties	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,14 @@
+###############################################################################
+# Copyright (c) 2000, 2005 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+# template proposal
+TemplateProposal.displayString= {0} - {1}
+TemplateProposal.errorDialog.title=Template Evaluation Error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/dwtx.jface.text.templates.TextTemplateMessages.properties	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,25 @@
+###############################################################################
+# Copyright (c) 2000, 2006 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+# template translator
+TemplateTranslator.error.incomplete.variable=Template has incomplete variables. Type '$$' if to enter the dollar character.
+TemplateTranslator.error.invalid.identifier=Template has invalid variable identifiers.
+TemplateTranslator.error.incompatible.type=Template variable ''{0}'' has incompatible types
+
+# global variables
+GlobalVariables.variable.description.cursor=The cursor position after editing template variables
+GlobalVariables.variable.description.dollar=The dollar symbol
+GlobalVariables.variable.description.date=Current date
+GlobalVariables.variable.description.year=Current year
+GlobalVariables.variable.description.time=Current time
+GlobalVariables.variable.description.user=User name
+GlobalVariables.variable.description.selectedWord= The selected word
+GlobalVariables.variable.description.selectedLines= The selected lines
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/res/dwtx.text.undo.UndoMessages.properties	Mon Sep 08 01:38:10 2008 +0200
@@ -0,0 +1,12 @@
+###############################################################################
+# Copyright (c) 2006 IBM Corporation and others.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+# Contributors:
+#     IBM Corporation - initial API and implementation
+###############################################################################
+
+DocumentUndoManager.operationLabel= Typing