/*******************************************************************************
 * Copyright (c) 2000, 2013 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Tom Eicher (Avaloq Evolution AG) - block selection mode
 *     Markus Schorn <markus.schorn@windriver.com> - shift with trailing empty line - https://bugs.eclipse.org/325438
 *******************************************************************************/
package org.eclipse.jface.text;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.PatternSyntaxException;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.LineBackgroundEvent;
import org.eclipse.swt.custom.LineBackgroundListener;
import org.eclipse.swt.custom.MovementEvent;
import org.eclipse.swt.custom.MovementListener;
import org.eclipse.swt.custom.ST;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.custom.StyledTextPrintOptions;
import org.eclipse.swt.custom.VerifyKeyListener;
import org.eclipse.swt.dnd.Clipboard;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.ControlListener;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.printing.PrintDialog;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.printing.PrinterData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.core.runtime.Assert;

import org.eclipse.text.edits.TextEdit;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.internal.text.NonDeletingPositionUpdater;
import org.eclipse.jface.internal.text.SelectionProcessor;
import org.eclipse.jface.internal.text.StickyHoverManager;
import org.eclipse.jface.util.Geometry;
import org.eclipse.jface.util.OpenStrategy;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.Viewer;

import org.eclipse.jface.text.hyperlink.HyperlinkManager;
import org.eclipse.jface.text.hyperlink.HyperlinkManager.DETECTION_STRATEGY;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetectorExtension;
import org.eclipse.jface.text.hyperlink.IHyperlinkPresenter;
import org.eclipse.jface.text.projection.ChildDocument;
import org.eclipse.jface.text.projection.ChildDocumentManager;


/**
 * SWT based implementation of {@link ITextViewer} and its extension interfaces.
 * Once the viewer and its SWT control have been created the viewer can only
 * indirectly be disposed by disposing its SWT control.
 * <p>
 * Clients are supposed to instantiate a text viewer and subsequently to
 * communicate with it exclusively using the
 * {@link org.eclipse.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 org.eclipse.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 extends Viewer implements
					ITextViewer, ITextViewerExtension, ITextViewerExtension2, ITextViewerExtension4, ITextViewerExtension6, ITextViewerExtension7, ITextViewerExtension8,
					IEditingSupportRegistry, ITextOperationTarget, ITextOperationTargetExtension,
					IWidgetTokenOwner, IWidgetTokenOwnerExtension, IPostSelectionProvider {

	/** Internal flag to indicate the debug state. */
	public static final boolean TRACE_ERRORS= false;
	/** Internal flag to indicate the debug state. */
	private static final boolean TRACE_DOUBLE_CLICK= false;

	// FIXME always use setRedraw to avoid flickering due to scrolling
	// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=158746
	private static final boolean REDRAW_BUG_158746= true;

	/**
	 * Width constraint for text hovers (in characters).
	 * @since 3.4
	 */
	private static final int TEXT_HOVER_WIDTH_CHARS= 100; //used to be 60 (text font)
	/**
	 * Height constraint for text hovers (in characters).
	 * @since 3.4
	 */
	private static final 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 != 0) {
				try {

					if (e instanceof SlaveDocumentEvent) {
						SlaveDocumentEvent slave= (SlaveDocumentEvent) e;
						DocumentEvent master= slave.getMasterEvent();
						if (master != 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 extends MouseAdapter implements MovementListener {

		/** Internal flag to remember the last double-click selection. */
		private Point fDoubleClickSelection;

		/*
		 * @see org.eclipse.swt.events.MouseAdapter#mouseUp(org.eclipse.swt.events.MouseEvent)
		 * @since 3.2
		 */
		public void mouseUp(MouseEvent e) {
			fDoubleClickSelection= null;
		}

		/*
		 * @see org.eclipse.swt.custom.MovementListener#getNextOffset(org.eclipse.swt.custom.MovementEvent)
		 * @since 3.3
		 */
		public void getNextOffset(MovementEvent event) {
			if (event.movement != SWT.MOVEMENT_WORD_END)
				return;

			if (TRACE_DOUBLE_CLICK) {
				System.out.println("\n+++"); //$NON-NLS-1$
				print(event);
			}

			if (fDoubleClickSelection != null) {
				if (fDoubleClickSelection.x <= event.offset && event.offset <= fDoubleClickSelection.y)
					event.newOffset= fDoubleClickSelection.y;
			}
		}

		/*
		 * @see org.eclipse.swt.custom.MovementListener#getPreviousOffset(org.eclipse.swt.custom.MovementEvent)
		 * @since 3.3
		 */
		public void getPreviousOffset(MovementEvent event) {
			if (event.movement != SWT.MOVEMENT_WORD_START)
				return;

			if (TRACE_DOUBLE_CLICK) {
				System.out.println("\n---"); //$NON-NLS-1$
				print(event);
			}
			if (fDoubleClickSelection == null) {
				ITextDoubleClickStrategy s= (ITextDoubleClickStrategy) selectContentTypePlugin(getSelectedRange().x, fDoubleClickStrategies);
				if (s != null) {
					StyledText textWidget= getTextWidget();
					s.doubleClicked(TextViewer.this);
					fDoubleClickSelection= textWidget.getSelection();
					event.newOffset= fDoubleClickSelection.x;
					if (TRACE_DOUBLE_CLICK)
						System.out.println("- setting selection: x= " + fDoubleClickSelection.x + ", y= " + 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("line offset: " + e.lineOffset); //$NON-NLS-1$
		System.out.println("line: " + e.lineText); //$NON-NLS-1$
		System.out.println("type: " + e.movement); //$NON-NLS-1$
		System.out.println("offset: " +  e.offset); //$NON-NLS-1$
		System.out.println("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 extends MouseAdapter
		implements 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 != null)
				fTextWidget.removeSelectionListener(this);
			updateViewportListeners(MOUSE_END);
		}

		/*
		 * @see MouseListener#mouseDown
		 */
		public void mouseDown(MouseEvent e) {
			if (fTextWidget != null)
				fTextWidget.addSelectionListener(this);
		}

		/*
		 * @see SelectionListener#widgetSelected
		 */
		public void widgetSelected(SelectionEvent e) {
			if (e.widget == 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 extends DefaultPositionUpdater {

		/**
		 * Creates the position updater for the given category.
		 *
		 * @param category the category this updater takes care of
		 */
		protected ShiftPositionUpdater(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 implements IDocumentListener {

		/*
		 * @see IDocumentListener#documentAboutToBeChanged
		 */
		public void documentAboutToBeChanged(DocumentEvent e) {
			if (e.getDocument() == getVisibleDocument())
				fWidgetCommand.setEvent(e);
			handleVisibleDocumentAboutToBeChanged(e);
		}

		/*
		 * @see IDocumentListener#documentChanged
		 */
		public void documentChanged(DocumentEvent e) {
			if (fWidgetCommand.event == e)
				updateTextListeners(fWidgetCommand);
			fLastSentSelectionChange= null;
			handleVisibleDocumentChanged(e);
		}
	}

	/**
	 * Internal verify listener.
	 */
	class TextVerifyListener implements VerifyListener {

		/**
		 * Indicates whether verify events are forwarded or ignored.
		 * @since 2.0
		 */
		private boolean 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(boolean 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 implements 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 Batch(VerifyKeyListener l, int i) {
				listener= l;
				index= i;
			}
		}

		/** List of registered verify key listeners. */
		private List fListeners= new ArrayList();
		/** List of pending batches. */
		private List fBatched= new ArrayList();
		/** The reentrance count. */
		private int fReentranceCount= 0;

		/*
		 * @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= (VerifyKeyListener) iterator.next();
					listener.verifyKey(event); // we might trigger reentrant calls on GTK
				}
			} finally {
				fReentranceCount--;
			}
			if (fReentranceCount == 0)
				processBatchedRequests();
		}

		/**
		 * Processes the pending batched requests.
		 */
		private void processBatchedRequests() {
			if (!fBatched.isEmpty()) {
				Iterator e= fBatched.iterator();
				while (e.hasNext()) {
					Batch batch= (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 == -1) {
				removeListener(listener);
			} else if (listener != 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 (listener == fListeners.get(i)) {
							idx= i;
							break;
						}
					}

					// move or add it
					if (idx != index) {

						if (idx != -1)
							fListeners.remove(idx);

						if (index > fListeners.size())
							fListeners.add(listener);
						else
							fListeners.add(index, listener);
					}

					if (size == 0)  // checking old size, i.e. current size == size + 1
						install();
				}
			}
		}

		/**
		 * Removes the given listener.
		 *
		 * @param listener the listener to be removed
		 */
		public void removeListener(VerifyKeyListener listener) {
			if (listener == null)
				return;

			if (fReentranceCount > 0) {

				fBatched.add(new Batch(listener, -1));

			} else {

				int size= fListeners.size();
				for (int i= 0; i < size; i++) {
					if (listener == fListeners.get(i)) {
						fListeners.remove(i);
						if (size == 1)  // checking old size, i.e. current size == size - 1
							uninstall();
						return;
					}
				}
			}
		}

		/**
		 * Installs this manager.
		 */
		private void install() {
			StyledText textWidget= getTextWidget();
			if (textWidget != null && !textWidget.isDisposed())
				textWidget.addVerifyKeyListener(this);
		}

		/**
		 * Uninstalls this manager.
		 */
		private void uninstall() {
			StyledText textWidget= getTextWidget();
			if (textWidget != 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 implements LineBackgroundListener, ITextListener, IPositionUpdater {

		/** Internal name for the position category used to update the range. */
		private final static String RANGE_CATEGORY= "org.eclipse.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 FindReplaceRange(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 != 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() {
			TextViewer.this.addTextListener(this);
			fTextWidget.addLineBackgroundListener(this);

			IDocument document= TextViewer.this.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= TextViewer.this.getDocument();
			if (document != null) {
				document.removePositionUpdater(this);
				document.removePosition(fPosition);
			}

			if (fTextWidget != null && !fTextWidget.isDisposed())
				fTextWidget.removeLineBackgroundListener(this);

			TextViewer.this.removeTextListener(this);

			clear();
		}

		/**
		 * Clears the highlighting of this range.
		 */
		private void clear() {
			if (fTextWidget != 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 implements 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= TextViewer.this.getSelectedRange();
			if (s.x > -1 && s.y > -1) {
				try {
					IDocument document= TextViewer.this.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, boolean regExReplace) {
			Point s= TextViewer.this.getSelectedRange();
			if (s.x > -1 && s.y > -1) {
				try {
					IRegion matchRegion= TextViewer.this.getFindReplaceDocumentAdapter().replace(text, regExReplace);
					int length= -1;
					if (matchRegion != null)
						length= matchRegion.getLength();

					if (text != null && length > 0)
						TextViewer.this.setSelectedRange(s.x, length);
				} catch (BadLocationException x) {
				}
			}
		}

		/*
		 * @see IFindReplaceTarget#isEditable()
		 */
		public boolean isEditable() {
			return TextViewer.this.isEditable();
		}

		/*
		 * @see IFindReplaceTarget#getSelection()
		 */
		public Point getSelection() {
			Point modelSelection= TextViewer.this.getSelectedRange();
			Point widgetSelection= modelSelection2WidgetSelection(modelSelection);
			return widgetSelection != null ? widgetSelection : new Point(-1, -1);
		}

		/*
		 * @see IFindReplaceTarget#findAndSelect(int, String, boolean, boolean, boolean)
		 */
		public int findAndSelect(int widgetOffset, String findString, boolean searchForward, boolean caseSensitive, boolean wholeWord) {
			try {
				return findAndSelect(widgetOffset, findString, searchForward, caseSensitive, wholeWord, false);
			} catch (PatternSyntaxException x) {
				return -1;
			}
		}

		/*
		 * @see IFindReplaceTarget#findAndSelect(int, String, boolean, boolean, boolean)
		 */
		public int findAndSelect(int widgetOffset, String findString, boolean searchForward, boolean caseSensitive, boolean wholeWord, boolean regExSearch) {

			int modelOffset= widgetOffset == -1 ? -1 : widgetOffset2ModelOffset(widgetOffset);

			if (fRange != null) {
				IRegion range= fRange.getRange();
				modelOffset= TextViewer.this.findAndSelectInRange(modelOffset, findString, searchForward, caseSensitive, wholeWord, range.getOffset(), range.getLength(), regExSearch);
			} else {
				modelOffset= TextViewer.this.findAndSelect(modelOffset, findString, searchForward, caseSensitive, wholeWord, regExSearch);
			}

			widgetOffset= modelOffset == -1 ? -1 : modelOffset2WidgetOffset(modelOffset);
			return widgetOffset;
		}

		/*
		 * @see IFindReplaceTarget#canPerformFind()
		 */
		public boolean canPerformFind() {
			return TextViewer.this.canPerformFind();
		}

		/*
		 * @see IFindReplaceTargetExtension#beginSession()
		 * @since 2.0
		 */
		public void beginSession() {
			fRange= null;
		}

		/*
		 * @see IFindReplaceTargetExtension#endSession()
		 * @since 2.0
		 */
		public void endSession() {
			if (fRange != null) {
				fRange.uninstall();
				fRange= null;
			}
		}

		/*
		 * @see IFindReplaceTargetExtension#getScope()
		 * @since 2.0
		 */
		public IRegion getScope() {
			return fRange == null ? null : fRange.getRange();
		}

		/*
		 * @see IFindReplaceTargetExtension#getLineSelection()
		 * @since 2.0
		 */
		public Point getLineSelection() {
			Point point= TextViewer.this.getSelectedRange();

			try {
				IDocument document= TextViewer.this.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() == 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) {
			TextViewer.this.setSelectedRange(modelOffset, modelLength);
		}

		/*
		 * @see IFindReplaceTargetExtension#setScope(IRegion)
		 * @since 2.0
		 */
		public void setScope(IRegion scope) {
			if (fRange != null)
				fRange.uninstall();

			if (scope == 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 != null)
				fRange.setHighlightColor(color);
			fScopeHighlightColor= color;
		}

		/*
		 * @see IFindReplaceTargetExtension#setReplaceAllMode(boolean)
		 * @since 2.0
		 */
		public void setReplaceAllMode(boolean replaceAll) {

			// http://bugs.eclipse.org/bugs/show_bug.cgi?id=18232

			IDocument document= TextViewer.this.getDocument();

			if (replaceAll) {

				if (document instanceof IDocumentExtension4) {
					IDocumentExtension4 extension= (IDocumentExtension4) document;
					fRewriteSession= extension.startRewriteSession(DocumentRewriteSessionType.SEQUENTIAL);
				} else {
					TextViewer.this.setRedraw(false);
					TextViewer.this.startSequentialRewriteMode(false);

					if (fUndoManager != null)
						fUndoManager.beginCompoundChange();

					fRememberedPartitioners= TextUtilities.removeDocumentPartitioners(document);
				}

			} else {

				if (document instanceof IDocumentExtension4) {
					IDocumentExtension4 extension= (IDocumentExtension4) document;
					extension.stopRewriteSession(fRewriteSession);
				} else {
					TextViewer.this.setRedraw(true);
					TextViewer.this.stopSequentialRewriteMode();

					if (fUndoManager != null)
						fUndoManager.endCompoundChange();

					if (fRememberedPartitioners != null)
						TextUtilities.addDocumentPartitioners(document, fRememberedPartitioners);
				}
			}
		}
	}


	/**
	 * The viewer's rewrite target.
	 * @since 2.0
	 */
	class RewriteTarget implements IRewriteTarget {

		/*
		 * @see org.eclipse.jface.text.IRewriteTarget#beginCompoundChange()
		 */
		public void beginCompoundChange() {
			if (fUndoManager != null)
				fUndoManager.beginCompoundChange();
		}

		/*
		 * @see org.eclipse.jface.text.IRewriteTarget#endCompoundChange()
		 */
		public void endCompoundChange() {
			if (fUndoManager != null)
				fUndoManager.endCompoundChange();
		}

		/*
		 * @see org.eclipse.jface.text.IRewriteTarget#getDocument()
		 */
		public IDocument getDocument() {
			return TextViewer.this.getDocument();
		}

		/*
		 * @see org.eclipse.jface.text.IRewriteTarget#setRedraw(boolean)
		 */
		public void setRedraw(boolean redraw) {
			TextViewer.this.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 TextHoverKey(String contentType, int stateMask) {
			Assert.isNotNull(contentType);
			fContentType= contentType;
			fStateMask= stateMask;
		}

		/*
		 * @see java.lang.Object#equals(java.lang.Object)
		 */
		public boolean equals(Object obj) {
			if (obj == null || obj.getClass() != getClass())
				return false;
			TextHoverKey textHoverKey= (TextHoverKey)obj;
			return textHoverKey.fContentType.equals(fContentType) && textHoverKey.fStateMask == fStateMask;
		}

		/*
		 * @see java.lang.Object#hashCode()
		 */
		public int hashCode() {
	 		return fStateMask << 16 | fContentType.hashCode();
		}

		/**
		 * Sets the state mask of this text hover key.
		 *
		 * @param stateMask the state mask
		 */
		private void setStateMask(int stateMask) {
			fStateMask= stateMask;
		}
	}
	
	/**
	 * Position storing block selection information in order to maintain a column selection.
	 * 
	 * @since 3.5
	 */
	private static final class ColumnPosition extends Position {
		int fStartColumn, fEndColumn;
		ColumnPosition(int offset, int length, int startColumn, int endColumn) {
			super(offset, length);
			fStartColumn= startColumn;
			fEndColumn= endColumn;
		}
	}

	/**
	 * 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 boolean fReverseSelection;
		/** <code>true</code> if the selection has been updated while in redraw(off) mode. */
		private boolean 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 ViewerState() {
			IDocument document= getDocument();
			if (document != 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 == 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 == 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(boolean restoreViewport) {
			if (isConnected())
				disconnect();
			if (fSelection != null) {
				if (fSelection instanceof ColumnPosition) {
					ColumnPosition cp= (ColumnPosition)fSelection;
					IDocument document= fDocument;
					try {
						int startLine= document.getLineOfOffset(fSelection.getOffset());
						int startLineOffset= document.getLineOffset(startLine);
						int selectionEnd= fSelection.getOffset() + fSelection.getLength();
						int endLine= document.getLineOfOffset(selectionEnd);
						int endLineOffset= document.getLineOffset(endLine);
						int tabs= getTextWidget().getTabs();
						int startColumn= fSelection.getOffset() - startLineOffset + cp.fStartColumn;
						int endColumn= selectionEnd - endLineOffset + cp.fEndColumn;
						setSelection(new BlockTextSelection(document, startLine, startColumn, endLine, endColumn, tabs));
					} catch (BadLocationException e) {
						// fall back to linear mode
						setSelectedRange(cp.getOffset(), cp.getLength());
					}
				} else {
					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 != null) {
				int stableLine;
				try {
					stableLine= fUpdaterDocument.getLineOfOffset(fStableLine.getOffset());
				} catch (BadLocationException x) {
					// ignore and return silently
					return;
				}
				int stableWidgetLine= getClosestWidgetLineForModelLine(stableLine);
				if (stableWidgetLine == -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 != null);
			Assert.isLegal(!isConnected());
			fUpdaterDocument= document;
			try {
				fUpdaterCategory= SELECTION_POSITION_CATEGORY + hashCode();
				fUpdater= new NonDeletingPositionUpdater(fUpdaterCategory);
				fUpdaterDocument.addPositionCategory(fUpdaterCategory);
				fUpdaterDocument.addPositionUpdater(fUpdater);

				ISelection selection= TextViewer.this.getSelection();
				if (selection instanceof IBlockTextSelection) {
					IBlockTextSelection bts= (IBlockTextSelection) selection;
					int startVirtual= Math.max(0, bts.getStartColumn() - document.getLineInformationOfOffset(bts.getOffset()).getLength());
					int endVirtual= Math.max(0, bts.getEndColumn() - document.getLineInformationOfOffset(bts.getOffset() + bts.getLength()).getLength());
					fSelection= new ColumnPosition(bts.getOffset(), bts.getLength(), startVirtual, endVirtual);
				} else {
					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(TextViewer.this);
			} 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 boolean isConnected() {
			return fUpdater != 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 implements KeyListener, MouseListener {

		/**
		 * Installs this cursor listener.
		 */
		private void install() {
			if (fTextWidget != null && !fTextWidget.isDisposed()) {
				fTextWidget.addKeyListener(this);
				fTextWidget.addMouseListener(this);
			}
		}

		/**
		 * Uninstalls this cursor listener.
		 */
		private void uninstall() {
			if (fTextWidget != null && !fTextWidget.isDisposed()) {
				fTextWidget.removeKeyListener(this);
				fTextWidget.removeMouseListener(this);
			}
		}

		/*
		 * @see KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
		 */
		public void keyPressed(KeyEvent event) {
		}

		/*
		 * @see KeyListener#keyPressed(org.eclipse.swt.events.KeyEvent)
		 */
		public void keyReleased(KeyEvent e) {
			if (!fTextWidget.isTextSelected()) {
				fLastSentSelectionChange= null;
				queuePostSelectionChanged(e.character == SWT.DEL);
			}
		}

		/*
		 * @see MouseListener#mouseDoubleClick(org.eclipse.swt.events.MouseEvent)
		 */
		public void mouseDoubleClick(MouseEvent e) {
		}

		/*
		 * @see MouseListener#mouseDown(org.eclipse.swt.events.MouseEvent)
		 */
		public void mouseDown(MouseEvent e) {
		}

		/*
		 * @see MouseListener#mouseUp(org.eclipse.swt.events.MouseEvent)
		 */
		public void mouseUp(MouseEvent event) {
			if (!fTextWidget.isTextSelected())
				queuePostSelectionChanged(false);
		}
	}

	/**
	 * Internal listener to document rewrite session state changes.
	 * @since 3.1
	 */
	private class DocumentRewriteSessionListener implements IDocumentRewriteSessionListener {

		/*
		 * @see org.eclipse.jface.text.IDocumentRewriteSessionListener#documentRewriteSessionChanged(org.eclipse.jface.text.DocumentRewriteSessionEvent)
		 */
		public void documentRewriteSessionChanged(DocumentRewriteSessionEvent event) {
			IRewriteTarget target= TextViewer.this.getRewriteTarget();
			final boolean toggleRedraw;
			if (REDRAW_BUG_158746)
				toggleRedraw= true;
			else
				toggleRedraw= event.getSession().getSessionType() != DocumentRewriteSessionType.UNRESTRICTED_SMALL;
			final boolean viewportStabilize= !toggleRedraw;
			if (DocumentRewriteSessionEvent.SESSION_START == event.getChangeType()) {
				if (toggleRedraw)
					target.setRedraw(false);
				target.beginCompoundChange();
				if (viewportStabilize && fViewerState == null)
					fViewerState= new ViewerState();
			} else if (DocumentRewriteSessionEvent.SESSION_STOP == event.getChangeType()) {
				if (viewportStabilize && fViewerState != 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 final String SELECTION_POSITION_CATEGORY= "_textviewer_selection_category"; //$NON-NLS-1$

	/**
	 * The shared printer data.
	 * 
	 * @since 3.6
	 */
	private static PrinterData fgPrinterData= null;

	/** 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= new WidgetCommand();
	/** The SWT control's scrollbars */
	private ScrollBar fScroller;
	/** Listener on the visible document */
	private VisibleDocumentListener fVisibleDocumentListener= new VisibleDocumentListener();
	/** Verify listener */
	private TextVerifyListener fVerifyListener= new TextVerifyListener();
	/** The most recent widget modification as document command */
	private DocumentCommand fDocumentCommand= new DocumentCommand();
	/** 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= new VerifyKeyListenersManager();
	/**
	 * The mark position.
	 * @since 2.0
	 */
	protected Position fMarkPosition;
	/**
	 * The mark position category.
	 * @since 2.0
	 */
	private final String MARK_POSITION_CATEGORY="__mark_category_" + hashCode(); //$NON-NLS-1$
	/**
	 * The mark position updater
	 * @since 2.0
	 */
	private final IPositionUpdater fMarkPositionUpdater= new DefaultPositionUpdater(MARK_POSITION_CATEGORY);
	/**
	 * 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 final int[] fNumberOfPostSelectionChangedEvents= new int[1];
	/**
	 * 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= new HashSet();
	/**
	 * The internal rewrite session listener.
	 * @since 3.1
	 */
	private DocumentRewriteSessionListener fDocumentRewriteSessionListener= new DocumentRewriteSessionListener();

	/** Should the auto indent strategies ignore the next edit operation */
	protected boolean  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 boolean 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 SWT 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;
	/**
	 * The last verify event time, used to fold block editing events.
	 * @since 3.5
	 */
	private int fLastEventTime;
	/**
	 * Pointer to disposed control.
	 * 
	 * @since 3.8
	 */
	private Control fDisposedControl;


	//---- Construction and disposal ------------------


	/**
	 * Internal use only
	 */
	protected TextViewer() {
	}

	/**
	 * Create a new text viewer with the given SWT 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 SWT style bits for the viewer's control,
	 * 			<em>if <code>SWT.WRAP</code> is set then a custom document adapter needs to be provided, see {@link #createDocumentAdapter()}
	 */
	public TextViewer(Composite parent, int styles) {
		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) {
		StyledText styledText= new StyledText(parent, styles);
		styledText.setLeftMargin(Math.max(styledText.getLeftMargin(), 2));
		return styledText;
	}

	/**
	 * 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 SWT 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 SWT 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(SWT.MouseVerticalWheel, new Listener() {

			public void handleEvent(Event event) {
				if (((event.stateMask & SWT.MOD1) == 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 DisposeListener() {
				public void widgetDisposed(DisposeEvent e) {
					fDisposedControl= getControl();
					handleDispose();
				}
			}
		);

		fTextWidget.setFont(parent.getFont());
		fTextWidget.setDoubleClickEnabled(true);

		/*
		 * Disable SWT Shift+TAB traversal in this viewer
		 * 1GIYQ9K: ITPUI:WINNT - StyledText swallows Shift+TAB
		 */
		fTextWidget.addTraverseListener(new TraverseListener() {
			public void keyTraversed(TraverseEvent e) {
				if ((SWT.SHIFT == e.stateMask) && ('\t' == e.character))
					e.doit= !fTextWidget.getEditable();
			}
		});

		// where does the first line start
		fTopInset= -fTextWidget.computeTrim(0, 0, 0, 0).y;

		fVerifyListener.forward(true);
		fTextWidget.addVerifyListener(fVerifyListener);

		fTextWidget.addSelectionListener(new 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 != null ? fTextWidget : fDisposedControl;
	}

	/*
	 * @see ITextViewer#activatePlugins()
	 */
	public void activatePlugins() {

		if (fDoubleClickStrategies != null && !fDoubleClickStrategies.isEmpty() && fDoubleClickStrategyConnector == null) {
			fDoubleClickStrategyConnector= new TextDoubleClickStrategyConnector();
			fTextWidget.addWordMovementListener(fDoubleClickStrategyConnector);
			fTextWidget.addMouseListener(fDoubleClickStrategyConnector);
		}

		ensureHoverControlManagerInstalled();
		ensureHyperlinkManagerInstalled();

		if (fUndoManager != 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 != null && !fTextHovers.isEmpty() && fHoverControlCreator != null && fTextHoverManager == 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 != 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 != null) {
			fPaintManager.dispose();
			fPaintManager= null;
		}

		removeViewPortUpdate();
		fViewportGuard= null;

		if (fViewportListeners != null) {
			fViewportListeners.clear();
			fViewportListeners= null;
		}

		if (fTextListeners != null) {
			fTextListeners.clear();
			fTextListeners= null;
		}

		if (fTextInputListeners != null)  {
			fTextInputListeners.clear();
			fTextInputListeners= null;
		}

		if (fPostSelectionChangedListeners != null)  {
			fPostSelectionChangedListeners.clear();
			fPostSelectionChangedListeners= null;
		}

		if (fAutoIndentStrategies != null) {
			fAutoIndentStrategies.clear();
			fAutoIndentStrategies= null;
		}

		if (fUndoManager != null) {
			fUndoManager.disconnect();
			fUndoManager= null;
		}

		if (fDoubleClickStrategies != null) {
			fDoubleClickStrategies.clear();
			fDoubleClickStrategies= null;
		}

		if (fTextHovers != null) {
			fTextHovers.clear();
			fTextHovers= null;
		}

		fDoubleClickStrategyConnector= null;

		if (fTextHoverManager != null) {
			fTextHoverManager.dispose();
			fTextHoverManager= null;
		}

		if (fVisibleDocumentListener !=null) {
			if (fVisibleDocument != null)
				fVisibleDocument.removeDocumentListener(fVisibleDocumentListener);
			fVisibleDocumentListener= null;
		}

		if (fDocumentAdapter != null) {
			fDocumentAdapter.setDocument(null);
			fDocumentAdapter= null;
		}

		if (fSlaveDocumentManager != null) {
			if (fVisibleDocument != null)
				fSlaveDocumentManager.freeSlaveDocument(fVisibleDocument);
			fSlaveDocumentManager= null;
		}

		if (fCursorListener != null) {
			fCursorListener.uninstall();
			fCursorListener= null;
		}

		if (fHyperlinkManager != null) {
			fHyperlinkManager.uninstall();
			fHyperlinkManager= null;
		}

		fHyperlinkDetectors= null;
		fVisibleDocument= null;
		fDocument= null;
		fScroller= null;

		fTextWidget= null;
	}


	//---- simple getters and setters

	/*
	 * @see org.eclipse.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>
	 * This implementation returns {@link OpenStrategy#getPostSelectionDelay()}.
	 * </p>
	 * 
	 * @return delay in milliseconds
	 * @see org.eclipse.jface.util.OpenStrategy
	 * @since 3.0
	 */
	protected int getEmptySelectionChangedEventDelay() {
		return OpenStrategy.getPostSelectionDelay();
	}

	/**
	 * {@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(new IAutoEditStrategy[] { 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 == null)
			fAutoIndentStrategies= new HashMap();

		List autoEditStrategies= (List) fAutoIndentStrategies.get(contentType);

		if (strategies == null) {
			if (autoEditStrategies == null)
				return;

			fAutoIndentStrategies.put(contentType, null);

		} else {
			if (autoEditStrategies == null) {
				autoEditStrategies= new ArrayList();
				fAutoIndentStrategies.put(contentType, autoEditStrategies);
			}

			autoEditStrategies.clear();
			autoEditStrategies.addAll(Arrays.asList(strategies));
		}
	}

	/*
	 * @see org.eclipse.jface.text.ITextViewerExtension2#prependAutoEditStrategy(org.eclipse.jface.text.IAutoEditStrategy, java.lang.String)
	 * @since 2.1
	 */
	public void prependAutoEditStrategy(IAutoEditStrategy strategy, String contentType) {

		if (strategy == null || contentType == null)
			throw new IllegalArgumentException();

		if (fAutoIndentStrategies == null)
			fAutoIndentStrategies= new HashMap();

		List autoEditStrategies= (List) fAutoIndentStrategies.get(contentType);
		if (autoEditStrategies == null) {
			autoEditStrategies= new ArrayList();
			fAutoIndentStrategies.put(contentType, autoEditStrategies);
		}

		autoEditStrategies.add(0, strategy);
	}

	/*
	 * @see org.eclipse.jface.text.ITextViewerExtension2#removeAutoEditStrategy(org.eclipse.jface.text.IAutoEditStrategy, java.lang.String)
	 * @since 2.1
	 */
	public void removeAutoEditStrategy(IAutoEditStrategy strategy, String contentType) {
		if (fAutoIndentStrategies == null)
			return;

		List autoEditStrategies= (List) fAutoIndentStrategies.get(contentType);
		if (autoEditStrategies == null)
			return;

		for (final Iterator iterator= autoEditStrategies.iterator(); iterator.hasNext(); ) {
			if (iterator.next().equals(strategy)) {
				iterator.remove();
				break;
			}
		}

		if (autoEditStrategies.isEmpty())
			fAutoIndentStrategies.put(contentType, 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;
		boolean ok= (indentPrefixes != null);
		while (ok &&  ++i < indentPrefixes.length)
			ok= (indentPrefixes[i] != null);

		if (ok) {

			if (fIndentChars == null)
				fIndentChars= new HashMap();

			fIndentChars.put(contentType, indentPrefixes);

		} else if (fIndentChars != null)
			fIndentChars.remove(contentType);
	}

	/*
	 * @see ITextViewer#getTopInset()
	 */
	public int getTopInset() {
		return fTopInset;
	}

	/*
	 * @see ITextViewer#isEditable()
	 */
	public boolean isEditable() {
		if (fTextWidget == null)
			return false;
		return fTextWidget.getEditable();
	}

	/*
	 * @see ITextViewer#setEditable(boolean)
	 */
	public void setEditable(boolean editable) {
		if (fTextWidget != null)
			fTextWidget.setEditable(editable);
	}

	/*
	 * @see ITextViewer#setDefaultPrefixes
	 * @since 2.0
	 */
	public void setDefaultPrefixes(String[] defaultPrefixes, String contentType) {

		if (defaultPrefixes != null && defaultPrefixes.length > 0) {
			if (fDefaultPrefixChars == null)
				fDefaultPrefixChars= new HashMap();
			fDefaultPrefixChars.put(contentType, defaultPrefixes);
		} else if (fDefaultPrefixChars != 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 != null) {
			if (fTextHovers == null) {
				fTextHovers= new HashMap();
			}
			fTextHovers.put(key, hover);
		} else if (fTextHovers != null)
			fTextHovers.remove(key);

		ensureHoverControlManagerInstalled();
	}

	/*
	 * @see ITextViewerExtension2#removeTextHovers(String)
	 * @since 2.1
	 */
	public void removeTextHovers(String contentType) {
		if (fTextHovers == null)
			return;

		Iterator iter= new HashSet(fTextHovers.keySet()).iterator();
		while (iter.hasNext()) {
			TextHoverKey key= (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);
	}

	/**
	 * 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 SWT event state mask
	 * @return the text hover for the given offset and state mask
	 * @since 2.1
	 */
	protected ITextHover getTextHover(int offset, int stateMask) {
		if (fTextHovers == null)
			return null;

		IDocument document= getDocument();
		if (document == null)
			return null;

		try {
			TextHoverKey key= new TextHoverKey(TextUtilities.getContentType(document, getDocumentPartitioning(), offset, true), stateMask);
			Object textHover= fTextHovers.get(key);
			if (textHover == null) {
				// Use default text hover
				key.setStateMask(ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
				textHover= fTextHovers.get(key);
			}
			return (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 == null)
			return;
		fTextHoverManager.setHoverEnrichMode(mode);
	}

	/*
	 * @see IWidgetTokenOwner#requestWidgetToken(IWidgetTokenKeeper)
	 * @since 2.0
	 */
	 public boolean requestWidgetToken(IWidgetTokenKeeper requester) {
		 if (fTextWidget != null) {
			 if (fWidgetTokenKeeper != null) {
				 if (fWidgetTokenKeeper == requester)
					 return true;
				 if (fWidgetTokenKeeper.requestWidgetToken(this)) {
					 fWidgetTokenKeeper= requester;
					 return true;
				 }
			} else {
				fWidgetTokenKeeper= requester;
				return true;
			}
		}
		return false;
	}

	/*
	 * @see org.eclipse.jface.text.IWidgetTokenOwnerExtension#requestWidgetToken(org.eclipse.jface.text.IWidgetTokenKeeper, int)
	 * @since 3.0
	 */
	public boolean requestWidgetToken(IWidgetTokenKeeper requester, int priority) {
		if (fTextWidget != null) {
			if (fWidgetTokenKeeper != null) {

				if (fWidgetTokenKeeper == requester)
					return true;

				boolean accepted= false;
				if (fWidgetTokenKeeper instanceof IWidgetTokenKeeperExtension)  {
					IWidgetTokenKeeperExtension extension= (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 == tokenKeeper)
			fWidgetTokenKeeper= null;
	}


	//---- Selection

	/*
	 * @see ITextViewer#getSelectedRange()
	 */
	public Point getSelectedRange() {

		if (!redraws() && fViewerState != null)
			return fViewerState.getSelection();

		if (fTextWidget != null) {
			Point p= fTextWidget.getSelectionRange();
			p= widgetSelection2ModelSelection(p);
			if (p != null)
				return p;
		}

		return new Point(-1, -1);
	}

	/*
	 * @see ITextViewer#setSelectedRange(int, int)
	 */
	public void setSelectedRange(int selectionOffset, int selectionLength) {

		if (!redraws()) {
			if (fViewerState != null)
				fViewerState.updateSelection(selectionOffset, selectionLength);
			return;
		}

		if (fTextWidget == null)
			return;

		IRegion widgetSelection= modelRange2ClosestWidgetRange(new Region(selectionOffset, selectionLength));
		if (widgetSelection != null) {

			int[] selectionRange= new int[] { 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 == 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;
				length += delta;
				String delimiter= document.getLineDelimiter(lineNumber);
				if (delimiter != null) {
					int delimiterLength= delimiter.length();
					offset += delimiterLength;
					length -= delimiterLength;
				}
			}

			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, boolean reveal) {
		if (selection instanceof IBlockTextSelection && getTextWidget().getBlockSelection()) {
			IBlockTextSelection s= (IBlockTextSelection) selection;

			try {
				int startLine= s.getStartLine();
				int endLine= s.getEndLine();
				IRegion startLineInfo= fDocument.getLineInformation(startLine);
				int startLineLength= startLineInfo.getLength();
				int startVirtuals= Math.max(0, s.getStartColumn() - startLineLength);

				IRegion endLineInfo= fDocument.getLineInformation(endLine);
				int endLineLength= endLineInfo.getLength();
				int endVirtuals= Math.max(0, s.getEndColumn() - endLineLength);
				
				IRegion startRegion= new Region(startLineInfo.getOffset() + s.getStartColumn() - startVirtuals, 0);
				int startOffset= modelRange2ClosestWidgetRange(startRegion).getOffset();
				IRegion endRegion= new Region(endLineInfo.getOffset() + s.getEndColumn() - endVirtuals, 0);
				int endOffset= modelRange2ClosestWidgetRange(endRegion).getOffset();
				Point clientAreaOrigin= new Point(fTextWidget.getHorizontalPixel(), fTextWidget.getTopPixel());
				Point startLocation= Geometry.add(clientAreaOrigin, fTextWidget.getLocationAtOffset(startOffset));
				int averageCharWidth= getAverageCharWidth();
				startLocation.x += startVirtuals * averageCharWidth;
				Point endLocation= Geometry.add(clientAreaOrigin, fTextWidget.getLocationAtOffset(endOffset));
				endLocation.x += endVirtuals * averageCharWidth;
				endLocation.y += fTextWidget.getLineHeight(endOffset);

				int widgetLength= endOffset - startOffset;
				int[] widgetSelection= { startOffset, widgetLength};
				validateSelectionRange(widgetSelection);
				if (widgetSelection[0] >= 0) {
					fTextWidget.setBlockSelectionBounds(Geometry.createRectangle(startLocation, Geometry.subtract(endLocation, startLocation)));
					selectionChanged(startOffset, widgetLength);
				}
			} catch (BadLocationException e) {
				// fall back to linear selection mode
				setSelectedRange(s.getOffset(), s.getLength());
			}
			if (reveal)
				revealRange(s.getOffset(), s.getLength());
		} else if (selection instanceof ITextSelection) {
			ITextSelection s= (ITextSelection) selection;
			setSelectedRange(s.getOffset(), s.getLength());
			if (reveal)
				revealRange(s.getOffset(), s.getLength());
		}
	}

	/*
	 * @see Viewer#getSelection()
	 */
	public ISelection getSelection() {
		if (fTextWidget != null && fTextWidget.getBlockSelection()) {
			int[] ranges= fTextWidget.getSelectionRanges();
			int startOffset= ranges[0];
			int endOffset= ranges[ranges.length - 2] + ranges[ranges.length - 1];
			
			// getBlockSelectionBounds returns pixel coordinates relative to document
			Rectangle bounds= fTextWidget.getBlockSelectionBounds();
			int clientAreaX= fTextWidget.getHorizontalPixel();
			int startX= bounds.x - clientAreaX;
			int endX= bounds.x + bounds.width - clientAreaX;
			int avgCharWidth= getAverageCharWidth();
			int startVirtuals= computeVirtualChars(startOffset, startX, avgCharWidth);
			int endVirtuals= computeVirtualChars(endOffset, endX, avgCharWidth);
			
			IDocument document= getDocument();
			Point modelSelection= widgetSelection2ModelSelection(new Point(startOffset, endOffset - startOffset));
			if (modelSelection == null)
				return TextSelection.emptySelection();
			startOffset= modelSelection.x;
			endOffset= modelSelection.x + modelSelection.y;

			try {
				int startLine= document.getLineOfOffset(startOffset);
				int endLine= document.getLineOfOffset(endOffset);
				
				int startColumn= startOffset - document.getLineOffset(startLine) + startVirtuals;
				int endColumn= endOffset - document.getLineOffset(endLine) + endVirtuals;
				if (startLine == -1 || endLine == -1)
					return TextSelection.emptySelection();
				return new BlockTextSelection(document, startLine, startColumn, endLine, endColumn, fTextWidget.getTabs());
			} catch (BadLocationException e) {
				return TextSelection.emptySelection();
			}
		}
		
		Point p= getSelectedRange();
		if (p.x == -1 || p.y == -1)
			return TextSelection.emptySelection();

		return new TextSelection(getDocument(), p.x, p.y);
	}

	/**
	 * Returns the number of virtual characters that exist beyond the end-of-line at offset
	 * <code>offset</code> for an x-coordinate <code>x</code>.
	 * 
	 * @param offset the non-virtual offset to consider
	 * @param x the x-coordinate (relative to the client area) of the possibly virtual offset
	 * @param avgCharWidth the average character width to assume for virtual spaces
	 * @return the number of virtual spaces needed to reach <code>x</code> from the location of
	 *         <code>offset</code>, <code>0</code> if <code>x</code> points inside the text
	 * @since 3.5
	 */
	private int computeVirtualChars(int offset, int x, int avgCharWidth) {
		int diff= x - fTextWidget.getLocationAtOffset(offset).x;
		return diff > 0 ? diff / avgCharWidth : 0;
	}

	/*
	 * @see ITextViewer#getSelectionProvider()
	 */
	public ISelectionProvider getSelectionProvider() {
		return this;
	}

	/*
	 * @see org.eclipse.jface.text.IPostSelectionProvider#addPostSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
	 * @since 3.0
	 */
	public void addPostSelectionChangedListener(ISelectionChangedListener listener)  {

		Assert.isNotNull(listener);

		if (fPostSelectionChangedListeners == null)
			fPostSelectionChangedListeners= new ArrayList();

		if (!fPostSelectionChangedListeners.contains(listener))
			fPostSelectionChangedListeners.add(listener);
	}

	/*
	 * @see org.eclipse.jface.text.IPostSelectionProvider#removePostSelectionChangedListener(org.eclipse.jface.viewers.ISelectionChangedListener)
	 * @since 3.0
	 */
	public void removePostSelectionChangedListener(ISelectionChangedListener listener)  {

		Assert.isNotNull(listener);

		if (fPostSelectionChangedListeners != null)  {
			fPostSelectionChangedListeners.remove(listener);
			if (fPostSelectionChangedListeners.size() == 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 == null || fTextWidget.isDisposed())
			return null;

		Display display= fTextWidget.getDisplay();
		if (display != 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(final boolean fireEqualSelection) {
		Display display= getDisplay();
		if (display == null)
			return;

		fNumberOfPostSelectionChangedEvents[0]++;
		display.timerExec(getEmptySelectionChangedEventDelay(), new Runnable() {
			final int id= fNumberOfPostSelectionChangedEvents[0];
			public void run() {
				if (id == fNumberOfPostSelectionChangedEvents[0]) {
					// Check again because this is executed after the delay
					if (getDisplay() != null)  {
						Point selection= fTextWidget.getSelectionRange();
						if (selection != null) {
							IRegion r= widgetRange2ModelRange(new Region(selection.x, selection.y));
							if (fireEqualSelection || (r != null && !r.equals(fLastSentPostSelectionChange)) || r == 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 != 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()) {
			if (length < 0) {
				length= -length;
				offset= offset + length;
			}
			IRegion r= widgetRange2ModelRange(new Region(offset, length));
			if ((r != null && !r.equals(fLastSentSelectionChange)) || r == null)  {
				fLastSentSelectionChange= r;
				ISelection selection= r != 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 != null) {
			listeners= new ArrayList(listeners);
			for (int i= 0; i < listeners.size(); i++) {
				ISelectionChangedListener l= (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 != -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(listener);

		if (fTextListeners == null)
			fTextListeners= new ArrayList();

		if (!fTextListeners.contains(listener))
			fTextListeners.add(listener);
	}

	/*
	 * @see ITextViewer#removeTextListener(ITextListener)
	 */
	public void removeTextListener(ITextListener listener) {

		Assert.isNotNull(listener);

		if (fTextListeners != null) {
			fTextListeners.remove(listener);
			if (fTextListeners.size() == 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 != null) {
			textListeners= new ArrayList(textListeners);
			DocumentEvent event= cmd.event;
			if (event instanceof SlaveDocumentEvent)
				event= ((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= (ITextListener) textListeners.get(i);
				l.textChanged(e);
			}
		}
	}

	//---- Text input listeners

	/*
	 * @see ITextViewer#addTextInputListener(ITextInputListener)
	 */
	public void addTextInputListener(ITextInputListener listener) {

		Assert.isNotNull(listener);

		if (fTextInputListeners == null)
			fTextInputListeners= new ArrayList();

		if (!fTextInputListeners.contains(listener))
			fTextInputListeners.add(listener);
	}

	/*
	 * @see ITextViewer#removeTextInputListener(ITextInputListener)
	 */
	public void removeTextInputListener(ITextInputListener listener) {

		Assert.isNotNull(listener);

		if (fTextInputListeners != null) {
			fTextInputListeners.remove(listener);
			if (fTextInputListeners.size() == 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 != null) {
			for (int i= 0; i < listener.size(); i++) {
				ITextInputListener l= (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 != null) {
			for (int i= 0; i < listener.size(); i++) {
				ITextInputListener l= (ITextInputListener) listener.get(i);
				l.inputDocumentChanged(oldInput, newInput);
			}
		}
	}

	//---- Document

	/*
	 * @see Viewer#getInput()
	 */
	public Object getInput() {
		return getDocument();
	}

	/*
	 * @see ITextViewer#getDocument()
	 */
	public IDocument getDocument() {
		return fDocument;
	}

	/*
	 * @see Viewer#setInput(Object)
	 */
	public void setInput(Object input) {

		IDocument document= null;
		if (input instanceof IDocument)
			document= (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(fDocument, 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(fDocument, 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 != 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 boolean updateVisibleDocument(IDocument visibleDocument, int visibleRegionOffset, int visibleRegionLength) throws BadLocationException {
		if (visibleDocument instanceof ChildDocument) {
			ChildDocument childDocument= (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 != parentRange.getOffset() || length != 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 boolean updateSlaveDocument(IDocument slaveDocument, int modelRangeOffset, int modelRangeLength) throws BadLocationException {
		return updateVisibleDocument(slaveDocument, modelRangeOffset, modelRangeLength);
	}



	//---- View ports

	/**
	 * Initializes all listeners and structures required to set up view port listeners.
	 */
	private void initializeViewportUpdate() {

		if (fViewportGuard != null)
			return;

		if (fTextWidget != null) {

			fViewportGuard= new ViewportGuard();
			fLastTopPixel= -1;

			fTextWidget.addKeyListener(fViewportGuard);
			fTextWidget.addMouseListener(fViewportGuard);

			fScroller= fTextWidget.getVerticalBar();
			if (fScroller != null)
				fScroller.addSelectionListener(fViewportGuard);
		}
	}

	/**
	 * Removes all listeners and structures required to set up view port listeners.
	 */
	private void removeViewPortUpdate() {

		if (fTextWidget != null) {

			fTextWidget.removeKeyListener(fViewportGuard);
			fTextWidget.removeMouseListener(fViewportGuard);

			if (fScroller != null && !fScroller.isDisposed()) {
				fScroller.removeSelectionListener(fViewportGuard);
				fScroller= null;
			}

			fViewportGuard= null;
		}
	}

	/*
	 * @see ITextViewer#addViewportListener(IViewportListener)
	 */
	public void addViewportListener(IViewportListener listener) {

		if (fViewportListeners == null) {
			fViewportListeners= new ArrayList();
			initializeViewportUpdate();
		}

		if (!fViewportListeners.contains(listener))
			fViewportListeners.add(listener);
	}

	/*
	 * @see ITextViewer#removeViewportListener(IVewportListener)
	 */
	public void removeViewportListener(IViewportListener listener) {
		if (fViewportListeners != null)
			fViewportListeners.remove(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 != fLastTopPixel) {
				if (fViewportListeners != null) {
					for (int i= 0; i < fViewportListeners.size(); i++) {
						IViewportListener l= (IViewportListener) fViewportListeners.get(i);
						l.viewportChanged(topPixel);
					}
				}
				fLastTopPixel= topPixel;
			}
		}
	}

	//---- scrolling and revealing

	/*
	 * @see ITextViewer#getTopIndex()
	 */
	public int getTopIndex() {

		if (fTextWidget != null) {
			int top= fTextWidget.getTopIndex();
			return widgetLine2ModelLine(top);
		}

		return -1;
	}

	/*
	 * @see ITextViewer#setTopIndex(int)
	 */
	public void setTopIndex(int index) {

		if (fTextWidget != null) {

			int widgetLine= modelLine2WidgetLine(index);
			if (widgetLine == -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 != null) {
			Rectangle clArea= fTextWidget.getClientArea();
			if (!clArea.isEmpty())
				return clArea.height / fTextWidget.getLineHeight();
		}
		return -1;
	}

	/*
	 * @see ITextViewer#getBottomIndex()
	 */
	public int getBottomIndex() {

		if (fTextWidget == null)
			return -1;

		int widgetBottom= JFaceTextUtil.getBottomIndex(fTextWidget);
		return widgetLine2ModelLine(widgetBottom);
	}

	/*
	 * @see ITextViewer#getTopIndexStartOffset()
	 */
	public int getTopIndexStartOffset() {

		if (fTextWidget != 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 == 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 == null || !redraws())
			return;

		IRegion modelRange= new Region(start, length);
		IRegion widgetRange= modelRange2ClosestWidgetRange(modelRange);
		if (widgetRange != null) {

			int[] range= new int[] { widgetRange.getOffset(), widgetRange.getLength() };
			validateSelectionRange(range);
			if (range[0] >= 0)
				internalRevealRangeWithWorkaround(range[0], range[0] + range[1]);

		} else {

			IRegion coverage= getModelCoverage();
			int cursor= (coverage == null || start < coverage.getOffset()) ? 0 : getVisibleDocument().getLength();
			internalRevealRangeWithWorkaround(cursor, cursor);
		}
	}

	/**
	 * First makes sure that the layout is not deferred (workaround for Platform UI bug 375576) and
	 * then reveals the given range of the visible document and.
	 * <p>
	 * NOTE: Only {@link #revealRange(int, int)} needs to use this method. The other methods are
	 * called at a time where the editor is already realized.
	 * </p>
	 * 
	 * @param start the start offset of the range
	 * @param end the end offset of the range
	 * @since 3.8.1, but only used/effective in 4.x
	 */
	private void internalRevealRangeWithWorkaround(int start, int end) {

		// XXX: Workaround for https://bugs.eclipse.org/375576
		final Shell shell= fTextWidget.getShell(); // only the shell layout is deferred
		int d= 0;
		for (; shell.isLayoutDeferred(); d++)
			shell.setLayoutDeferred(false);
		try {
			internalRevealRange(start, end);
		} finally {
			for (; d > 0; d--)
				shell.setLayoutDeferred(true);
		}

	}

	/**
	 * 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= ((float)newOffset) / ((float)getAverageCharWidth());

					fTextWidget.setHorizontalIndex(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 == 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 org.eclipse.jface.text.ITextViewer#invalidateTextPresentation()
	 */
	public final void invalidateTextPresentation() {
		if (fVisibleDocument != 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 != null) {

			IRegion widgetRange= modelRange2WidgetRange(new Region(offset, length));
			if (widgetRange != 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 != null && fVisibleDocument != null) {

			// set widget content
			if (fDocumentAdapter == 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 != 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 == document && fVisibleDocument instanceof ChildDocument) {
			// optimization for new child documents
			return;
		}

		if (fVisibleDocument != null) {
			if (fVisibleDocumentListener != null)
				fVisibleDocument.removeDocumentListener(fVisibleDocumentListener);
			if (fVisibleDocument != document)
				freeSlaveDocument(fVisibleDocument);
		}

		fVisibleDocument= document;
		initializeDocumentInformationMapping(fVisibleDocument);

		initializeWidgetContents();

		fFindReplaceDocumentAdapter= null;
		if (fVisibleDocument != null && fVisibleDocumentListener != 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 == 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 (document instanceof ChildDocument) {
			ChildDocument cdoc= (ChildDocument) document;
			return cdoc.getParentDocumentRange().getOffset();
		}

		return 0;
	}

	/*
	 * @see ITextViewer#getVisibleRegion()
	 */
	public IRegion getVisibleRegion() {

		IDocument document= getVisibleDocument();
		if (document instanceof ChildDocument) {
			Position p= ((ChildDocument) document).getParentDocumentRange();
			return new Region(p.getOffset(), p.getLength());
		}

		return new Region(0, document == null ? 0 : document.getLength());
	}

	/*
	 * @see ITextViewer#overlapsWithVisibleRegion(int, int)
	 */
	public boolean overlapsWithVisibleRegion(int start, int length) {
		IDocument document= getVisibleDocument();
		if (document instanceof ChildDocument) {
			ChildDocument cdoc= (ChildDocument) document;
			return cdoc.getParentDocumentRange().overlapsWith(start, length);
		} else if (document != 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 == region.getOffset() && length == 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 != null) {
			IDocument slave= getVisibleDocument();
			IDocument master= manager.getMasterDocument(slave);
			if (master != null) {
				setVisibleDocument(master);
				manager.freeSlaveDocument(slave);
			}
		}
	}


	//--------------------------------------

	/*
	 * @see ITextViewer#setTextDoubleClickStrategy(ITextDoubleClickStrategy, String)
	 */
	public void setTextDoubleClickStrategy(ITextDoubleClickStrategy strategy, String contentType) {

		if (strategy != null) {
			if (fDoubleClickStrategies == null)
				fDoubleClickStrategies= new HashMap();
			fDoubleClickStrategies.put(contentType, strategy);
		} else if (fDoubleClickStrategies != 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 or <code>null</code> if none
	 */
	protected Object selectContentTypePlugin(int offset, Map plugins) {
		final IDocument document= getDocument();
		if (document == null)
			return null;
		try {
			return selectContentTypePlugin(TextUtilities.getContentType(document, 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 == 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 != null)
			fTabsToSpacesConverter.customizeDocumentCommand(document, command);

		List strategies= (List) selectContentTypePlugin(command.offset, fAutoIndentStrategies);
		if (strategies == null)
			return;

		switch (strategies.size()) {
		// optimization
		case 0:
			break;

		case 1:
			((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(); )
				((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 != null) {
			fEventConsumer.processEvent(e);
			if (!e.doit)
				return;
		}
		
		if (fTextWidget.getBlockSelection() && (e.text == null || e.text.length() < 2)) {
			Point sel = fTextWidget.getSelection();
			if (fTextWidget.getLineAtOffset(sel.x) != fTextWidget.getLineAtOffset(sel.y)) {
				verifyEventInBlockSelection(e);
				return;
			}
		}

		IRegion modelRange= event2ModelRange(e);
		fDocumentCommand.setEvent(e, modelRange);
		customizeDocumentCommand(fDocumentCommand);
		if (!fDocumentCommand.fillEvent(e, modelRange)) {

			boolean compoundChange= fDocumentCommand.getCommandCount() > 1;
			try {

				fVerifyListener.forward(false);

				if (compoundChange && fUndoManager != null)
					fUndoManager.beginCompoundChange();

				fDocumentCommand.execute(getDocument());

				if (fTextWidget != null) {
					int documentCaret= fDocumentCommand.caretOffset;
					if (documentCaret == -1) {
						// old behavior of document command
						documentCaret= fDocumentCommand.offset + (fDocumentCommand.text == null ? 0 : fDocumentCommand.text.length());
					}

					int widgetCaret= modelOffset2WidgetOffset(documentCaret);
					if (widgetCaret == -1) {
						// try to move it to the closest spot
						IRegion region= getModelCoverage();
						if (region != null) {
							if (documentCaret <= region.getOffset())
								widgetCaret= 0;
							else if (documentCaret >= region.getOffset() + region.getLength())
								widgetCaret= getVisibleRegion().getLength();
						}
					}

					if (widgetCaret != -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 != null)
					fUndoManager.endCompoundChange();

				fVerifyListener.forward(true);

			}
		}
	}

	/**
	 * Simulates typing behavior in block selection mode.
	 * 
	 * @param e the verify event.
	 * @since 3.5
	 */
	private void verifyEventInBlockSelection(final VerifyEvent e) {
		/*
		 Implementation Note: StyledText sends a sequence of n events
		 for a single character typed, where n is the number of affected lines. Since
		 the events share no manifest attribute to group them together or to detect the last event
		 of a sequence, we simulate the modification at the first event and veto any following
		 events with an equal event time.
		 
		 See also bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=268044
		 */
		e.doit= false;
		boolean isFirst= e.time != fLastEventTime;
		fLastEventTime= e.time;
		if (isFirst) {
			wrapCompoundChange(new Runnable() {
				public void run() {
					SelectionProcessor processor= new SelectionProcessor(TextViewer.this);
					try {
						/* Use the selection instead of the event's coordinates. Is this dangerous? */
						ISelection selection= getSelection();
						int length= e.text.length();
						if (length == 0 && e.character == '\0') {
							// backspace in StyledText block selection mode...
							TextEdit edit= processor.backspace(selection);
							edit.apply(fDocument, TextEdit.UPDATE_REGIONS);
							ISelection empty= processor.makeEmpty(selection, true);
							setSelection(empty);
						} else {
							int lines= processor.getCoveredLines(selection);
							String delim= fDocument.getLegalLineDelimiters()[0];
							StringBuffer text= new StringBuffer(lines * length + (lines - 1) * delim.length());
							text.append(e.text);
							for (int i= 0; i < lines - 1; i++) {
								text.append(delim);
								text.append(e.text);
							}
							processor.doReplace(selection, text.toString());
						}
					} catch (BadLocationException x) {
						if (TRACE_ERRORS)
							System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.verifyText")); //$NON-NLS-1$
					}
				}
			});
		}
	}

	//---- 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 boolean isMarkedRegionEmpty() {
		return
			fTextWidget == null ||
			fMarkPosition == null ||
			fMarkPosition.isDeleted() ||
			modelRange2WidgetRange(fMarkPosition) == null;
	}

	/*
	 * @see ITextViewer#canDoOperation(int)
	 */
	public boolean canDoOperation(int operation) {

		if (fTextWidget == null || !redraws())
			return false;

		switch (operation) {
			case CUT:
				return isEditable() && (fTextWidget.isTextSelected() || !isMarkedRegionEmpty());
			case COPY:
				return fTextWidget.isTextSelected() || !isMarkedRegionEmpty();
			case DELETE:
			case PASTE:
				return isEditable();
			case SELECT_ALL:
				return true;
			case SHIFT_LEFT:
			case SHIFT_RIGHT:
				return isEditable() && fIndentChars != null && areMultipleLinesSelected();
			case PREFIX:
			case STRIP_PREFIX:
				return isEditable() && fDefaultPrefixChars != null;
			case UNDO:
				return fUndoManager != null && fUndoManager.undoable();
			case REDO:
				return fUndoManager != null && fUndoManager.redoable();
			case PRINT:
				return isPrintable();
			case HyperlinkManager.OPEN_HYPERLINK:
				return fHyperlinkManager != null;
		}

		return false;
	}

	/*
	 * @see ITextViewer#doOperation(int)
	 */
	public void doOperation(int operation) {

		if (fTextWidget == null || !redraws())
			return;

		Point selection= null;

		switch (operation) {

			case UNDO:
				if (fUndoManager != null) {
					ignoreAutoEditStrategies(true);
					fUndoManager.undo();
					ignoreAutoEditStrategies(false);
				}
				break;
			case REDO:
				if (fUndoManager != null) {
					ignoreAutoEditStrategies(true);
					fUndoManager.redo();
					ignoreAutoEditStrategies(false);
				}
				break;
			case CUT:
				if (!fTextWidget.isTextSelected())
					copyMarkedRegion(true);
				else
					wrapCompoundChange(new Runnable() {
						public void run() {
							fTextWidget.cut();
						}
					});

				selection= fTextWidget.getSelectionRange();
				fireSelectionChanged(selection.x, selection.y);

				break;
			case COPY:
				if (!fTextWidget.isTextSelected())
					copyMarkedRegion(false);
				else
					fTextWidget.copy();
				break;
			case PASTE:
				paste();
				break;
			case DELETE:
				delete();
				break;
			case SELECT_ALL: {
				IDocument doc= getDocument();
				if (doc != null) {
					if (fTextWidget.getBlockSelection())
						// XXX: performance hack: use 1000 for the endColumn - StyledText will not select more than what's possible in the viewport.
						setSelection(new BlockTextSelection(doc, 0, 0, doc.getNumberOfLines() - 1, 1000, fTextWidget.getTabs()));
					else
						setSelectedRange(0, doc.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;
			case HyperlinkManager.OPEN_HYPERLINK:
				boolean atleastOneLinkOpened= fHyperlinkManager.openHyperlink();
				if (!atleastOneLinkOpened)
					MessageDialog.openInformation(getControl().getShell(),
							JFaceTextMessages.getString("TextViewer.open_hyperlink_error_title"), JFaceTextMessages.getString("TextViewer.open_hyperlink_error_message")); //$NON-NLS-1$ //$NON-NLS-2$
				return;
		}
	}

	private void delete() {
		if (!fTextWidget.getBlockSelection()) {
			fTextWidget.invokeAction(ST.DELETE_NEXT);
		} else {
			wrapCompoundChange(new Runnable(){
				public void run() {
					try {
						new SelectionProcessor(TextViewer.this).doDelete(getSelection());
					} catch (BadLocationException e) {
						if (TRACE_ERRORS)
							System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.delete")); //$NON-NLS-1$
					}
				}
			});
		}
		Point selection= fTextWidget.getSelectionRange();
		fireSelectionChanged(selection.x, selection.y);
	}

	private void paste() {
//		ignoreAutoEditStrategies(true);
		if (!fTextWidget.getBlockSelection()) {
			fTextWidget.paste();
		} else {
			wrapCompoundChange(new Runnable(){
				public void run() {
					SelectionProcessor processor= new SelectionProcessor(TextViewer.this);
					Clipboard clipboard= new Clipboard(getDisplay());
					try {
						/*
						 * Paste in block selection mode. If the pasted text is not a multi-line
						 * text, pasting behaves like typing, i.e. the pasted text replaces
						 * the selection on each line. If the pasted text is multi-line (e.g. from
						 * copying a column selection), the selection is replaced, line-by-line, by
						 * the corresponding contents of the pasted text. If the selection touches
						 * more lines than the pasted text, the selection on the remaining lines
						 * is deleted (assuming an empty text being pasted). If the pasted
						 * text contains more lines than the selection, the selection is extended
						 * to the succeeding lines, or more lines are added to accommodate the
						 * paste operation.
						 */
						ISelection selection= getSelection();
						TextTransfer plainTextTransfer = TextTransfer.getInstance();
						String contents= (String)clipboard.getContents(plainTextTransfer, DND.CLIPBOARD);
						String toInsert;
						if (TextUtilities.indexOf(fDocument.getLegalLineDelimiters(), contents, 0)[0] != -1) {
							// multi-line insertion
							toInsert= contents;
						} else {
							// single-line insertion
							int length= contents.length();
							int lines= processor.getCoveredLines(selection);
							String delim= fDocument.getLegalLineDelimiters()[0];
							StringBuffer text= new StringBuffer(lines * length + (lines - 1) * delim.length());
							text.append(contents);
							for (int i= 0; i < lines - 1; i++) {
								text.append(delim);
								text.append(contents);
							}
							toInsert= text.toString();
						}
						processor.doReplace(selection, toInsert);
					} catch (BadLocationException x) {
						if (TRACE_ERRORS)
							System.out.println(JFaceTextMessages.getString("TextViewer.error.bad_location.paste")); //$NON-NLS-1$
					} finally {
						clipboard.dispose();
					}
				}
			});
		}
		Point selection= fTextWidget.getSelectionRange();
		fireSelectionChanged(selection.x, selection.y);
//		ignoreAutoEditStrategies(false);
	}

	/**
	 * If the text widget is in {@link StyledText#getBlockSelection() block selection mode}, the
	 * passed code is wrapped into a begin/endCompoundChange undo session on the
	 * {@linkplain #getRewriteTarget() rewrite target}; otherwise, the runnable is executed
	 * directly.
	 * 
	 * @param runnable the code to wrap when in block selection mode
	 * @since 3.5
	 */
	private void wrapCompoundChange(Runnable runnable) {
		if (!fTextWidget.getBlockSelection()) {
			runnable.run();
			return;
		}
		IRewriteTarget target= getRewriteTarget();
		target.beginCompoundChange();
		try {
			runnable.run();
		} finally {
			target.endCompoundChange();
		}
			
	}

	/**
	 * 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(boolean ignore) {
		if (fIgnoreAutoIndent == ignore)
			return;

		fIgnoreAutoIndent= ignore;

		IDocument document= getDocument();
		if (document instanceof IDocumentExtension2) {
			IDocumentExtension2 extension= (IDocumentExtension2) document;
			if (ignore)
				extension.ignorePostNotificationReplaces();
			else
				extension.acceptPostNotificationReplaces();
		}
	}

	/**
	 * Returns whether this viewer ignores the registered auto edit strategies.
	 *
	 * @return <code>true</code> if the strategies are ignored
	 * @since 2.1
	 */
	protected boolean isIgnoringAutoEditStrategies() {
		return fIgnoreAutoIndent;
	}

	/*
	 * @see ITextOperationTargetExtension#enableOperation(int, boolean)
	 * @since 2.0
	 */
	public void enableOperation(int operation, boolean 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(boolean delete) {

		if (fTextWidget == null)
			return;

		if (fMarkPosition == null || fMarkPosition.isDeleted() || modelRange2WidgetRange(fMarkPosition) == 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) {
			wrapCompoundChange(new Runnable() {
				public void run() {
					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 boolean isBlockSelected() {

		Point s= getSelectedRange();
		if (s.y == 0)
			return false;

		try {

			IDocument document= getDocument();
			int line= document.getLineOfOffset(s.x);
			int start= document.getLineOffset(line);
			return (s.x == 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 boolean areMultipleLinesSelected() {
		Point s= getSelectedRange();
		if (s.y == 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 != endLine || (s.x == line.getOffset() && s.y == 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
	 * @throws BadLocationException when the document does not contain the selection
	 */
	private IRegion getTextBlockFromSelection(ITextSelection selection) throws BadLocationException {
		IDocument document= getDocument();
		int start= document.getLineOffset(selection.getStartLine());
		int end;
		int endLine= selection.getEndLine();
		if (document.getNumberOfLines() > endLine+1) {
			end= document.getLineOffset(endLine+1);
		} else {
			end= document.getLength();
		}
		return new Region(start, end - start);
	}

	/**
	 * 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(boolean, boolean, boolean) instead
	 */
	protected void shift(boolean useDefaultPrefixes, boolean 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(boolean useDefaultPrefixes, boolean right, boolean ignoreWhitespace) {
		if (fUndoManager != null)
			fUndoManager.beginCompoundChange();

		IDocument d= getDocument();
		Map partitioners= null;
		DocumentRewriteSession rewriteSession= null;
		try {
			ITextSelection selection= (ITextSelection) getSelection();
			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] == -1 ? -1 : d.getLineOfOffset(offset));
				lineCount += lines[j + 1] - lines[j] + 1;
			}

			if (d instanceof IDocumentExtension4) {
				IDocumentExtension4 extension= (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= (String[]) selectContentTypePlugin(regions[i].getType(), map);
				if (prefixes != 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 != null)
				TextUtilities.addDocumentPartitioners(d, partitioners);

			if (d instanceof IDocumentExtension4) {
				IDocumentExtension4 extension= (IDocumentExtension4) d;
				extension.stopRewriteSession(rewriteSession);
			} else {
				stopSequentialRewriteMode();
				setRedraw(true);
			}

			if (fUndoManager != 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, boolean 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] != -1) {
					if (ignoreWhitespace) {
						String s= d.get(line.getOffset(), found[0]);
						s= s.trim();
						if (s.length() == 0)
							index= line.getOffset() + found[0];
					} else if (found[0] == 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 == 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 boolean isPrintable() {
		return true; // see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=250528
	}

	/**
	 * {@inheritDoc}
	 *
	 * @since 3.4
	 */
	public void print(StyledTextPrintOptions options) {
		final Shell shell= fTextWidget.getShell();

		if (Printer.getPrinterList().length == 0) {
			String title= JFaceTextMessages.getString("TextViewer.warning.noPrinter.title"); //$NON-NLS-1$
			String msg= JFaceTextMessages.getString("TextViewer.warning.noPrinter.message"); //$NON-NLS-1$
			MessageDialog.openWarning(shell, title, msg);
			return;
		}

		final PrintDialog dialog= new PrintDialog(shell, SWT.PRIMARY_MODAL);
		dialog.setPrinterData(fgPrinterData);
		final PrinterData data= dialog.open();

		if (data != null) {
			final Printer printer= new Printer(data);
			final Runnable styledTextPrinter= fTextWidget.print(printer, options);

			Thread printingThread= new Thread("Printing") { //$NON-NLS-1$
				public void run() {
					styledTextPrinter.run();
					printer.dispose();
				}
			};
			printingThread.start();

			/*
			 * FIXME:
			 * 	Should copy the printer data to avoid threading issues,
			 *	but this is currently not possible, see http://bugs.eclipse.org/297957
			 */
			fgPrinterData= data;
			fgPrinterData.startPage= 1;
			fgPrinterData.endPage= 1;
			fgPrinterData.scope= PrinterData.ALL_PAGES;
			fgPrinterData.copyCount= 1;
		}
	}

	/**
	 * 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 boolean canPerformFind() {
		IDocument d= getVisibleDocument();
		return (fTextWidget != null && d != null && d.getLength() > 0);
	}

	/**
	 * Adheres to the contract of {@link IFindReplaceTarget#findAndSelect(int, String, boolean, boolean, boolean)}.
	 *
	 * @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, boolean, boolean, boolean, boolean)}
	 */
	protected int findAndSelect(int startPosition, String findString, boolean forwardSearch, boolean caseSensitive, boolean 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 org.eclipse.jface.text.IFindReplaceTargetExtension3#findAndSelect(int, String, boolean, boolean, boolean, boolean)}.
	 *
	 * @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, boolean forwardSearch, boolean caseSensitive, boolean wholeWord, boolean regExSearch) {
		if (fTextWidget == null)
			return -1;

		try {

			int widgetOffset= (startPosition == -1 ? startPosition : modelOffset2WidgetOffset(startPosition));
			FindReplaceDocumentAdapter adapter= getFindReplaceDocumentAdapter();
			IRegion matchRegion= adapter.find(widgetOffset, findString, forwardSearch, caseSensitive, wholeWord, regExSearch);
			if (matchRegion != 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);
				boolean borderHasLineDelimiter= startChar == '\n' || startChar == '\r' || endChar == '\n' || endChar == '\r';
				boolean 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 org.eclipse.jface.text.IFindReplaceTargetExtension3#findAndSelect(int, String, boolean, boolean, boolean, boolean)}.
	 *
	 * @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, boolean forwardSearch, boolean caseSensitive, boolean wholeWord, int rangeOffset, int rangeLength, boolean regExSearch) {
		if (fTextWidget == null)
			return -1;

		try {

			int modelOffset;
			if (forwardSearch && (startPosition == -1 || startPosition < rangeOffset)) {
				modelOffset= rangeOffset;
			} else if (!forwardSearch && (startPosition == -1 || startPosition > rangeOffset + rangeLength)) {
				modelOffset= rangeOffset + rangeLength;
			} else {
				modelOffset= startPosition;
			}

			int widgetOffset= modelOffset2WidgetOffset(modelOffset);
			if (widgetOffset == -1)
				return -1;

			FindReplaceDocumentAdapter adapter= getFindReplaceDocumentAdapter();
			IRegion matchRegion= adapter.find(widgetOffset, findString, forwardSearch, caseSensitive, wholeWord, regExSearch);
			int widgetPos= -1;
			int length= 0;
			if (matchRegion != null) {
				widgetPos= matchRegion.getOffset();
				length= matchRegion.getLength();
			}
			int modelPos= widgetPos == -1 ? -1 : widgetOffset2ModelOffset(widgetPos);

			if (widgetPos != -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);
				boolean borderHasLineDelimiter= startChar == '\n' || startChar == '\r' || endChar == '\n' || endChar == '\r';
				boolean 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 != null)
			setTextColor(color, 0, getDocument().getLength(), true);
	}

	/*
	 * @see ITextViewer#setTextColor(Color, start, length, boolean)
	 */
	public void setTextColor(Color color, int start, int length, boolean controlRedraw) {
		if (fTextWidget != null) {

			StyleRange s= new StyleRange();
			s.foreground= color;
			s.start= start;
			s.length= length;

			s= modelStyleRange2WidgetStyleRange(s);
			if (s != 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 != null) {

			range= modelStyleRange2WidgetStyleRange(range);
			if (range != null)
				fTextWidget.setStyleRange(range);

			ArrayList ranges= new ArrayList(presentation.getDenumerableRanges());
			Iterator e= presentation.getNonDefaultStyleRangeIterator();
			while (e.hasNext()) {
				range= (StyleRange) e.next();
				range= modelStyleRange2WidgetStyleRange(range);
				if (range != null)
					ranges.add(range);
			}

			if (!ranges.isEmpty())
				fTextWidget.replaceStyleRanges(0, 0, (StyleRange[])ranges.toArray(new StyleRange[ranges.size()]));

		} else {
			IRegion region= modelRange2WidgetRange(presentation.getCoverage());
			if (region == null)
				return;

			List list= new ArrayList(presentation.getDenumerableRanges());
			Iterator e= presentation.getAllStyleRangeIterator();
			while (e.hasNext()) {
				range= (StyleRange) e.next();
				range= modelStyleRange2WidgetStyleRange(range);
				if (range != 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= (StyleRange) e.next();
			range= modelStyleRange2WidgetStyleRange(range);
			if (range != 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 (document instanceof ChildDocument) {
			Position p= ((ChildDocument) document).getParentDocumentRange();
			return new Region(p.getOffset(), p.getLength());
		}

		return null;
	}

	/*
	 * @see ITextViewer#changeTextPresentation(TextPresentation, boolean)
	 */
	public void changeTextPresentation(TextPresentation presentation, boolean controlRedraw) {

		if (presentation == null || !redraws())
			return;

		if (fTextWidget == null)
			return;


		/*
		 * Call registered text presentation listeners
		 * and let them apply their presentation.
		 */
		if (fTextPresentationListeners != null) {
			ArrayList listeners= new ArrayList(fTextPresentationListeners);
			for (int i= 0, size= listeners.size(); i < size; i++) {
				ITextPresentationListener listener= (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 == 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 == 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 == null || fMarkPosition.isDeleted() ? -1 : fMarkPosition.getOffset();
	}

	/*
	 * @see ITextViewerExtension#setMark(int)
	 * @since 2.0
	 */
	public void setMark(int offset) {

		// clear
		if (offset == -1) {
			if (fMarkPosition != null && !fMarkPosition.isDeleted()) {

				IDocument document= getDocument();
				if (document != null)
					document.removePosition(fMarkPosition);
			}

			fMarkPosition= null;

			markChanged(-1, 0);

		// set
		} else {

			IDocument document= getDocument();
			if (document == null) {
				fMarkPosition= null;
				return;
			}

			if (fMarkPosition != 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= (IDocument) oldInput;
		if (oldDocument != null) {

			if (fMarkPosition != null && !fMarkPosition.isDeleted())
				oldDocument.removePosition(fMarkPosition);

			try {
				oldDocument.removePositionUpdater(fMarkPositionUpdater);
				oldDocument.removePositionCategory(MARK_POSITION_CATEGORY);

			} catch (BadPositionCategoryException e) {
			}
		}

		fMarkPosition= null;

		if (oldDocument instanceof IDocumentExtension4) {
			IDocumentExtension4 document= (IDocumentExtension4) oldDocument;
			document.removeDocumentRewriteSessionListener(fDocumentRewriteSessionListener);
		}

		super.inputChanged(newInput, oldInput);

		if (newInput instanceof IDocumentExtension4) {
			IDocumentExtension4 document= (IDocumentExtension4) newInput;
			document.addDocumentRewriteSessionListener(fDocumentRewriteSessionListener);
		}

		IDocument newDocument= (IDocument) newInput;
		if (newDocument != 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 (fDocumentAdapter instanceof IDocumentAdapterExtension) {
			IDocumentAdapterExtension extension= (IDocumentAdapterExtension) fDocumentAdapter;
			StyledText textWidget= getTextWidget();
			if (textWidget != 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 != null) {
			fViewerState.restore(topIndex == -1);
			fViewerState= null;
		}

		if (fTextWidget != 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 == null)
			fViewerState= new ViewerState();

		if (fDocumentAdapter instanceof IDocumentAdapterExtension) {
			IDocumentAdapterExtension extension= (IDocumentAdapterExtension) fDocumentAdapter;
			extension.stopForwardingDocumentChanges();
		}

		if (fTextWidget != null && !fTextWidget.isDisposed())
			fTextWidget.setRedraw(false);

		fireRedrawChanged();
	}

	/*
	 * @see ITextViewerExtension#setRedraw(boolean)
	 * @since 2.0
	 */
	public final void setRedraw(boolean redraw) {
		setRedraw(redraw, -1);
	}

	/**
	 * Basically same functionality as <code>ITextViewerExtension.setRedraw(boolean)</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(boolean)</code>.
	 *
	 * @see ITextViewerExtension#setRedraw(boolean)
	 *
	 * @param redraw <code>true</code> if redraw is enabled
	 * @param topIndex the top index
	 * @since 3.0
	 */
	protected final void setRedraw(boolean redraw, int topIndex) {
		if (!redraw) {

			++ fRedrawCounter;
			if (fRedrawCounter == 1)
				disableRedrawing();

		} else {
			-- fRedrawCounter;
			if (fRedrawCounter == 0) {
				if (topIndex == -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 boolean 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(boolean normalized) {
		IDocument document= getDocument();
		if (document instanceof IDocumentExtension) {
			IDocumentExtension extension= (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 (document instanceof IDocumentExtension) {
			IDocumentExtension extension= (IDocumentExtension) document;
			extension.stopSequentialRewrite();
		}
	}

	/*
	 * @see org.eclipse.jface.text.ITextViewerExtension#getRewriteTarget()
	 * @since 2.0
	 */
	public IRewriteTarget getRewriteTarget() {
		if (fRewriteTarget == null)
			fRewriteTarget= new RewriteTarget();
		return fRewriteTarget;
	}

	/*
	 * @see org.eclipse.jface.text.ITextViewerExtension2#getCurrentTextHover()
	 */
	public ITextHover getCurrentTextHover() {
		if (fTextHoverManager == null)
			return null;
		return fTextHoverManager.getCurrentTextHover();
	}

	/*
	 * @see org.eclipse.jface.text.ITextViewerExtension2#getHoverEventLocation()
	 */
	public Point getHoverEventLocation() {
		if (fTextHoverManager == null)
			return null;
		return fTextHoverManager.getHoverEventLocation();
	}

	/**
	 * Returns the paint manager of this viewer.
	 *
	 * @return the paint manager of this viewer
	 * @since 2.1
	 */
	protected PaintManager getPaintManager() {
		if (fPaintManager == 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 == 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 == 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 == 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 != 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 (!(fInformationMapping instanceof IDocumentInformationMappingExtension2))
			return modelRange2WidgetRange(modelRange);

		try {
			if (modelRange.getLength() < 0) {
				Region reversed= new Region(modelRange.getOffset() + modelRange.getLength(), -modelRange.getLength());
				IRegion result= ((IDocumentInformationMappingExtension2) fInformationMapping).toClosestImageRegion(reversed);
				if (result != null)
					return new Region(result.getOffset() + result.getLength(), -result.getLength());
			}
			return ((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 == 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 == null)
			return widgetOffset;

		try {
			return fInformationMapping.toOriginOffset(widgetOffset);
		} catch (BadLocationException x) {
			if (widgetOffset == 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 == 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 == null) {
			IDocument document= getDocument();
			if (document == 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 == 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 != null) {
			StyleRange result= (StyleRange) range.clone();
			result.start= region.getOffset();
			result.length= region.getLength();
			return result;
		}
		return null;
	}

	/**
	 * Same as {@link #modelRange2WidgetRange(IRegion)} just for a {@link org.eclipse.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 == 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 == null)
			return modelSelection;

		try {
			IRegion region= new Region(modelSelection.x, modelSelection.y);
			region= fInformationMapping.toImageRegion(region);
			if (region != 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 != null) {
			try {
				return document.getLineOfOffset(widgetOffset);
			} catch (BadLocationException e) {
			}
		}
		return -1;
	}

	/*
	 * @see org.eclipse.jface.text.ITextViewerExtension4#moveFocusToWidgetToken()
	 * @since 3.0
	 */
	public boolean moveFocusToWidgetToken() {
		if (fWidgetTokenKeeper instanceof IWidgetTokenKeeperExtension) {
			IWidgetTokenKeeperExtension extension= (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(listener);

		if (fTextPresentationListeners == null)
			fTextPresentationListeners= new ArrayList();

		if (!fTextPresentationListeners.contains(listener))
			fTextPresentationListeners.add(listener);
	}

	/*
	 * @see ITextViewerExtension4#removeTextPresentationListener(ITextPresentationListener)
	 * @since 3.0
	 */
	public void removeTextPresentationListener(ITextPresentationListener listener) {

		Assert.isNotNull(listener);

		if (fTextPresentationListeners != null) {
			fTextPresentationListeners.remove(listener);
			if (fTextPresentationListeners.size() == 0)
				fTextPresentationListeners= null;
		}
	}

	/*
	 * @see org.eclipse.jface.text.IEditingSupportRegistry#registerHelper(org.eclipse.jface.text.IEditingSupport)
	 * @since 3.1
	 */
	public void register(IEditingSupport helper) {
		Assert.isLegal(helper != null);
		fEditorHelpers.add(helper);
	}

	/*
	 * @see org.eclipse.jface.text.IEditingSupportRegistry#deregisterHelper(org.eclipse.jface.text.IEditingSupport)
	 * @since 3.1
	 */
	public void unregister(IEditingSupport helper) {
		fEditorHelpers.remove(helper);
	}

	/*
	 * @see org.eclipse.jface.text.IEditingSupportRegistry#getCurrentHelpers()
	 * @since 3.1
	 */
	public IEditingSupport[] getRegisteredSupports() {
		return (IEditingSupport[]) fEditorHelpers.toArray(new IEditingSupport[fEditorHelpers.size()]);
	}

	/*
	 * @see org.eclipse.jface.text.ITextViewerExtension6#setHyperlinkDetectors(org.eclipse.jface.text.hyperlink.IHyperlinkDetector[], int)
	 * @since 3.1
	 */
	public void setHyperlinkDetectors(IHyperlinkDetector[] hyperlinkDetectors, int eventStateMask) {
		if (fHyperlinkDetectors != null) {
			for (int i= 0; i < fHyperlinkDetectors.length; i++) {
				if (fHyperlinkDetectors[i] instanceof IHyperlinkDetectorExtension)
					((IHyperlinkDetectorExtension)fHyperlinkDetectors[i]).dispose();
			}
		}

		boolean enable= hyperlinkDetectors != null && hyperlinkDetectors.length > 0;
		fHyperlinkStateMask= eventStateMask;
		fHyperlinkDetectors= hyperlinkDetectors;
		if (enable) {
			if (fHyperlinkManager != null) {
				fHyperlinkManager.setHyperlinkDetectors(fHyperlinkDetectors);
				fHyperlinkManager.setHyperlinkStateMask(fHyperlinkStateMask);
			}
			ensureHyperlinkManagerInstalled();
		} else {
			if (fHyperlinkManager != 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) throws IllegalStateException {
		if (fHyperlinkManager != 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 != null && fHyperlinkDetectors.length > 0 && fHyperlinkPresenter != null && fHyperlinkManager == null) {
			DETECTION_STRATEGY strategy= fHyperlinkPresenter.canShowMultipleHyperlinks() ? HyperlinkManager.ALL : HyperlinkManager.FIRST;
			fHyperlinkManager= new HyperlinkManager(strategy);
			fHyperlinkManager.install(this, fHyperlinkPresenter, fHyperlinkDetectors, fHyperlinkStateMask);
		}
	}

	/*
	 * @see org.eclipse.jface.text.ITextViewerExtension7#setTabsToSpacesConverter(org.eclipse.jface.text.IAutoEditStrategy)
	 * @since 3.3
	 */
	public void setTabsToSpacesConverter(IAutoEditStrategy converter) {
		fTabsToSpacesConverter= converter;
	}

}
